From 20e03094895ff4175b319cbc97f26711b9a4f939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Thu, 5 Oct 2023 14:43:25 +0200 Subject: [PATCH 001/115] Process Bundle Ui v2 initial commit --- README.md | 49 +--- composer.json | 71 +---- config/routes.yaml | 4 - config/services.yaml | 10 +- public/logo.jpg | Bin 0 -> 14990 bytes src/Admin/Field/EnumField.php | 21 ++ src/Admin/Field/LogLevelField.php | 21 ++ src/CleverAgeProcessUiBundle.php | 14 +- src/Command/PurgeProcessExecution.php | 88 ------ src/Command/UserCreateCommand.php | 58 ++-- .../Admin/LogRecordCrudController.php | 73 +++++ .../Admin/Process/ExecuteAction.php | 33 +++ src/Controller/Admin/Process/ListAction.php | 26 ++ .../Admin/Process/UploadAndExecuteAction.php | 75 ++++++ .../Admin/ProcessDashboardController.php | 57 ++++ .../Admin/ProcessExecutionCrudController.php | 131 +++++++++ .../Admin/Security/LoginController.php | 24 ++ .../Admin/Security/LogoutController.php | 21 ++ src/Controller/Admin/UserCrudController.php | 91 +++++++ src/Controller/Crud/ProcessCrudController.php | 141 ---------- .../Crud/ProcessExecutionCrudController.php | 146 ---------- src/Controller/Crud/UserCrudController.php | 128 --------- src/Controller/DashboardController.php | 44 --- src/Controller/SecurityController.php | 46 ---- .../CleverAgeProcessUiExtension.php | 60 ++++- ...ompilerPass.php => RegisterLogHandler.php} | 11 +- src/DependencyInjection/Configuration.php | 34 ++- src/Entity/.gitignore | 0 src/Entity/Enum/ProcessExecutionStatus.php | 12 + src/Entity/LogRecord.php | 59 ++++ src/Entity/Process.php | 113 -------- src/Entity/ProcessExecution.php | 253 +++--------------- src/Entity/ProcessExecutionLogRecord.php | 88 ------ src/Entity/User.php | 44 +-- src/Event/IncrementReportInfoEvent.php | 28 -- src/Event/SetReportInfoEvent.php | 35 --- .../Crud/ProcessCrudListener.php | 38 --- .../ProcessEventSubscriber.php | 171 +++--------- src/Form/Type/ProcessUploadFileType.php | 22 ++ .../ProcessConfigurationValueResolver.php | 24 ++ src/Manager/ProcessExecutionManager.php | 62 +++++ src/Manager/ProcessUiConfigurationManager.php | 97 ------- src/Message/LogIndexerHandler.php | 62 ----- src/Message/LogIndexerMessage.php | 46 ---- src/Message/ProcessExecuteHandler.php | 21 ++ src/Message/ProcessExecuteMessage.php | 12 + src/Message/ProcessRunHandler.php | 36 --- src/Message/ProcessRunMessage.php | 35 --- src/Migrations/Version20210903142035.php | 107 -------- src/Migrations/Version20211028081845.php | 36 --- src/Migrations/Version20231006111525.php | 87 ++++++ .../Handler/DoctrineProcessHandler.php | 77 ++++++ src/Monolog/Handler/ProcessHandler.php | 54 ++++ src/Monolog/Handler/ProcessLogHandler.php | 66 ----- src/Repository/.gitignore | 0 src/Repository/ProcessExecutionRepository.php | 70 ++--- src/Repository/ProcessRepository.php | 66 ----- src/Repository/UserRepository.php | 37 --- src/Security/LoginFormAuthAuthenticator.php | 62 ----- src/Twig/Extension/LogLevelExtension.php | 20 ++ src/Twig/Extension/MD5Extension.php | 19 ++ .../Extension/ProcessExecutionExtension.php | 30 +++ src/Twig/Runtime/LogLevelExtensionRuntime.php | 33 +++ src/Twig/Runtime/MD5ExtensionRuntime.php | 15 ++ .../ProcessExecutionExtensionRuntime.php | 37 +++ templates/admin/field/array.html.twig | 16 ++ templates/admin/field/enum.html.twig | 2 + templates/admin/field/log_level.html.twig | 1 + .../admin/field/process_source.html.twig | 1 + .../admin/field/process_target.html.twig | 1 + templates/admin/field/report.html.twig | 8 + templates/admin/login.html.twig | 1 + templates/admin/process/list.html.twig | 104 +++++++ .../process/upload_and_execute.html.twig | 23 ++ 74 files changed, 1561 insertions(+), 2147 deletions(-) delete mode 100755 config/routes.yaml create mode 100644 public/logo.jpg create mode 100644 src/Admin/Field/EnumField.php create mode 100644 src/Admin/Field/LogLevelField.php delete mode 100644 src/Command/PurgeProcessExecution.php create mode 100644 src/Controller/Admin/LogRecordCrudController.php create mode 100644 src/Controller/Admin/Process/ExecuteAction.php create mode 100644 src/Controller/Admin/Process/ListAction.php create mode 100644 src/Controller/Admin/Process/UploadAndExecuteAction.php create mode 100644 src/Controller/Admin/ProcessDashboardController.php create mode 100644 src/Controller/Admin/ProcessExecutionCrudController.php create mode 100644 src/Controller/Admin/Security/LoginController.php create mode 100644 src/Controller/Admin/Security/LogoutController.php create mode 100644 src/Controller/Admin/UserCrudController.php delete mode 100644 src/Controller/Crud/ProcessCrudController.php delete mode 100644 src/Controller/Crud/ProcessExecutionCrudController.php delete mode 100644 src/Controller/Crud/UserCrudController.php delete mode 100644 src/Controller/DashboardController.php delete mode 100644 src/Controller/SecurityController.php rename src/DependencyInjection/Compiler/{RegisterLogHandlerCompilerPass.php => RegisterLogHandler.php} (66%) delete mode 100644 src/Entity/.gitignore create mode 100644 src/Entity/Enum/ProcessExecutionStatus.php create mode 100644 src/Entity/LogRecord.php delete mode 100644 src/Entity/Process.php delete mode 100644 src/Entity/ProcessExecutionLogRecord.php delete mode 100644 src/Event/IncrementReportInfoEvent.php delete mode 100644 src/Event/SetReportInfoEvent.php delete mode 100644 src/EventSubscriber/Crud/ProcessCrudListener.php create mode 100644 src/Form/Type/ProcessUploadFileType.php create mode 100644 src/Http/ValueResolver/ProcessConfigurationValueResolver.php create mode 100644 src/Manager/ProcessExecutionManager.php delete mode 100644 src/Manager/ProcessUiConfigurationManager.php delete mode 100644 src/Message/LogIndexerHandler.php delete mode 100644 src/Message/LogIndexerMessage.php create mode 100644 src/Message/ProcessExecuteHandler.php create mode 100644 src/Message/ProcessExecuteMessage.php delete mode 100644 src/Message/ProcessRunHandler.php delete mode 100644 src/Message/ProcessRunMessage.php delete mode 100644 src/Migrations/Version20210903142035.php delete mode 100644 src/Migrations/Version20211028081845.php create mode 100644 src/Migrations/Version20231006111525.php create mode 100644 src/Monolog/Handler/DoctrineProcessHandler.php create mode 100644 src/Monolog/Handler/ProcessHandler.php delete mode 100644 src/Monolog/Handler/ProcessLogHandler.php delete mode 100644 src/Repository/.gitignore delete mode 100644 src/Repository/ProcessRepository.php delete mode 100644 src/Repository/UserRepository.php delete mode 100644 src/Security/LoginFormAuthAuthenticator.php create mode 100644 src/Twig/Extension/LogLevelExtension.php create mode 100644 src/Twig/Extension/MD5Extension.php create mode 100644 src/Twig/Extension/ProcessExecutionExtension.php create mode 100644 src/Twig/Runtime/LogLevelExtensionRuntime.php create mode 100644 src/Twig/Runtime/MD5ExtensionRuntime.php create mode 100644 src/Twig/Runtime/ProcessExecutionExtensionRuntime.php create mode 100644 templates/admin/field/array.html.twig create mode 100644 templates/admin/field/enum.html.twig create mode 100644 templates/admin/field/log_level.html.twig create mode 100644 templates/admin/field/process_source.html.twig create mode 100644 templates/admin/field/process_target.html.twig create mode 100644 templates/admin/field/report.html.twig create mode 100644 templates/admin/login.html.twig create mode 100644 templates/admin/process/list.html.twig create mode 100644 templates/admin/process/upload_and_execute.html.twig diff --git a/README.md b/README.md index 475ceab..7b2ff6a 100644 --- a/README.md +++ b/README.md @@ -7,54 +7,11 @@ A simple UX for cleverage/processbundle using EasyAdmin * Import routes ```yaml #config/routes.yaml -process-ui: - resource: '@CleverAgeProcessUiBundle/Resources/config/routes.yaml' +processui: + resource: '@CleverAgeProcessUiBundle/src/Controller' + type: attribute ``` * Run doctrine migration * Create an user using cleverage:process-ui:user-create console. Now you can access Process UI via http://your-domain.com/process - -**Indexing logs** - -You can index logs line into database to perform search on ****Process > History**** page. -See configuration section. - -When indexation is enabled you can perform it async. - -```yaml -#config/messenger.yaml -framework: - messenger: - transports: - log_index: 'doctrine://default' - - routing: - CleverAge\ProcessUiBundle\Message\LogIndexerMessage: log_index -``` - -Then you have to consume messages by running (use a supervisor to keep consumer alive) -``` -bin/console messenger:consume log_index --memory-limit=64M -``` - -See official symfony/messenger component documentations for more informations https://symfony.com/doc/current/messenger.html - -**Integrate CrudController** - -Of course you can integrate ProcessUI CRUD into your own easy admin Dashboard -```php - public function configureMenuItems(): iterable - { - /* ... your configuration */ - yield MenuItem::linkToCrud('History', null, ProcessExecution::class); - } -``` - -**Configuration** -```yaml -clever_age_process_ui: - index_logs: - enabled: false - level: ERROR #Minimum log level to index. Allowed values are DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY -``` diff --git a/composer.json b/composer.json index 152db2c..157e049 100644 --- a/composer.json +++ b/composer.json @@ -1,16 +1,9 @@ { - "name": "cleverage/process-ui-bundle", + "name": "cleverage/process-bundle-ui", "type": "symfony-bundle", "license": "MIT", "description": "UI for cleverage/process-bundle", - "minimum-stability": "dev", - "prefer-stable": true, "authors": [ - { - "name": "Baudouin Douliery", - "email": "bdouliery@clever-age.com", - "role": "Developer" - }, { "name": "Grégory Tonon", "email": "gtonon@clever-age.com", @@ -23,50 +16,19 @@ } ], "require": { - "php": ">=8.0", + "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", - "cleverage/process-bundle": "^3.2", - "easycorp/easyadmin-bundle": "^4.0", - "ddtraceweb/monolog-parser": "^1.3", - "league/flysystem": "^2.2", - "composer/package-versions-deprecated": "^1.11", - "doctrine/doctrine-bundle": "^2.4", - "doctrine/doctrine-migrations-bundle": "^3.1", - "doctrine/orm": "^2.9", - "sensio/framework-extra-bundle": "^6.1", - "symfony/console": "^5.4", - "symfony/messenger": "^5.4", - "symfony/doctrine-messenger": "^5.4", - "symfony/filesystem": "^5.4", - "symfony/flex": "^1.3.1", - "symfony/form": "^5.4", - "symfony/framework-bundle": "^5.4", - "symfony/mime": "^5.4", - "symfony/proxy-manager-bridge": "^5.4", - "symfony/runtime": "^5.4", - "symfony/security-bundle": "^5.4", - "symfony/stopwatch": "^5.4", - "symfony/twig-bundle": "^5.4", - "symfony/validator": "^5.4", - "symfony/webpack-encore-bundle": "^1.11", - "symfony/yaml": "^5.4", - "twig/extra-bundle": "^2.12|^3.0", - "twig/intl-extra": "^3.3" - }, - "require-dev": { - "doctrine/doctrine-fixtures-bundle": "^3.4", - "friendsofphp/php-cs-fixer": "^3.6", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1", - "phpstan/phpstan-doctrine": "^1.2", - "phpstan/phpstan-symfony": "^1.1", - "rector/rector": "^0.12.13", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6", - "symfony/dotenv": "^5.4", - "symfony/maker-bundle": "^1.31", - "symfony/web-profiler-bundle": "^5.4" + "ext-pcntl": "*", + "cleverage/process-bundle": "dev-v4-dev", + "symfony/flex": "^2", + "symfony/orm-pack": "^v2.4", + "symfony/dotenv": "^6.3", + "symfony/uid": "^6.3", + "symfony/string": "^6.3", + "symfony/messenger": "^6.3", + "symfony/doctrine-messenger": "^6.3", + "easycorp/easyadmin-bundle": "^4.7" }, "config": { "optimize-autoloader": true, @@ -102,14 +64,5 @@ "post-update-cmd": [ "@auto-scripts" ] - }, - "conflict": { - "symfony/symfony": "*" - }, - "extra": { - "symfony": { - "allow-contrib": false, - "require": "5.4.*" - } } } diff --git a/config/routes.yaml b/config/routes.yaml deleted file mode 100755 index 8cfca5b..0000000 --- a/config/routes.yaml +++ /dev/null @@ -1,4 +0,0 @@ -_process-ui: - prefix: '/process' - resource: ../src/Controller/ - type: annotation \ No newline at end of file diff --git a/config/services.yaml b/config/services.yaml index 3b371fb..039380d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -1,15 +1,9 @@ parameters: - uploads_directory: '%kernel.project_dir%/public/uploads' - cleverage_processes: '%kernel.project_dir%/config/packages' - process_logs_dir: '%kernel.logs_dir%/process' - + upload_directory: '%kernel.project_dir%/var/storage/uploads' services: _defaults: autowire: true autoconfigure: true - bind: - $processLogDir: '%process_logs_dir%' - $indexLogs: '%clever_age_process_ui.index_logs.enabled%' CleverAge\ProcessUiBundle\: resource: '../src' @@ -17,4 +11,4 @@ services: - '../src/DependencyInjection/' - '../src/Entity/' - '../src/Tests/' - - '../src/Migrations' \ No newline at end of file + - '../src/Migrations' diff --git a/public/logo.jpg b/public/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d110ec94b9010885e8969a2f187e8ee2f572e06a GIT binary patch literal 14990 zcmdsdcUV(N7k3obE-um(1YA&16j%&B6nCXq2#6sdT?x{Qw9o>$Yk`0v%OcW*C}@B{ zU@?RMp{xi*x*>#;5D;Q$G4#;O7q{=b?)yI9f8X;>9=N|dbMKkooH=*OIkVlr{T}e; z71PV6fE_ykfE|J#V0&~&|K*DpU9MfXG`(zY@@v6cUzlI;&MyG~KmU-R>t^4cxM631 zV$Uc*2p|U72M`9x+=2z)0Ygl!0fH2KD=Zim66E^{|CyG0KS>7wXeyq!{N1vX0R|WD z{$y|=%=)w0`S?~(mS54s93igbxB9rZr0dg9{A;xpc=F+i>^!Kl~N z7OZ6rca(IK@qHL-6N8FB_oLR+qWnj%m~|Pgl)l>^!sb@Dx3`&qi-3K*_w3!Xd*9x@ zd-w0(cR*P3u<)Tn!pFtLMI_~A6%@XbJ#pfcvZl%@rSqpxoKQ7VJFl&)udjbnBEPmbrnx2>i%D+?VkZ6dv`E|CWUs$19pn+5E9w3-3T}? zP~y&=LcdtaZ+h6V=ZoDtckLAtl!Ct$n5WRrox6AM*}Zf3zFk6sZrmxf>kEc&^2iG$B~m77r$@lmN=yaaSIN~oim2Q@?O0e6^N4( z7`)JqPgeg&`bFGsLD^}MPeguAztIttiR@B8^3@mLh~AR7I{&ShLg2-12H>Eec&CVv z2*3zXav@ar=Raiq{{waaL|bE>FJ&-Eo(tJ1q)c%%&`43<_m&%Lm{91BtGhO1KVl(I zUJ5a|y7|$Y9gC2?mi;yRR{nP@xdlj+sG8Rt_VC)FCZo-ivm5GbIoG`HXZw}k$DGDy zkDIhEL29b|!X4s$w*jITdt5J{L{vqZ;uWUBJ8MN(jnqGQ{AuR;rg&jdfNql2 zSgnTYqwp|rg3sGBo9K!40nu8cktF9$X6n-@ouxveJ6(cD8!!=Tgvh?V9u#}ENz5XR zYANDwqUp9Ny&E}A4#vAwXS3Od2o@7z=EN@0_0|>~2oC{QuJH3m2^DBNkuUR~ma-2y z2<3H(H!urd*jHJH4dIHi))nC^z{*UE><3$g-zB2A0jb`ZhS#QlMzx0SjgQwWd!M|o zTkFzJEv@@^lZw?>BPEivL>KWu;ib*GADc80BgwnG3OpA58mh9rPchFSTxkAOAJ05EAxNbu_9!zT1b>;Qb$|7W{;hEqBu`lJXC$uIpqQaB0~AZ@i5`kQo6K^Pz&Yph z=5S|PiC~O#yX2?%;(K)0y_;-zQhx^k}B_+aBVHLX=R1m03Vd7 z4V9bEGpn{uY%J7F_x?s*y>6~Er+-#|-G=dO-(P$9Kkyy~4``v1f#hZ4RxiGP%juu; zWJC{fQ=M1LzkO1Hm567`eb_l$@E>pem)nROLoB5MaSS(S(ErpYChmxm_k4+Ik6GF% z#yZMf1o)!SuY_h2+9zgZOn2<0iX0z9NE|*8Vp}-nbajmwd!ace2JJTkm30YY*8kWs zqPmy5;@=KMdvtSnL_2K-?z+)o!qC8I`a?+UWO)8k!|d__&kZ9VKO^D9FeRQ-5!bP( zvv8vd=y1{lNF3FONBy|-!tZp2ZVKJpAu64HV`l6JslFq#7RW{e?^l7Yz19nlvOo~$ zt-7h&GUY_%nr3gvrIMv{7SA7;oAY@P{sh`drjECXzR(`b5;eEk**V z6DgWlZO|QluQY~k^lexAFpZG}wOoJ<811|M^zs|2(nD@dPuJzH7cy8=y3Ep6L^RmP z^GUGX!=uK*sP5`#zjOP?)hqy`*j7B+QFq{7sd+G$HM}`RLf_ZKKT#8V-ytJ+lU6~8 zHDyjMHPhw_Ti&*?y(zp3<>?CBZ`fmc{XhRh+`nXep+SdQfz^S)R(XYp=%32Y1Lt|J zt_&Q1ooJ$AWgGxJ+jTcmzv-PHv$IG3QTFwS#wDu98p5M*dM=Ye-G_I#?-L4fa#|r4 z1b!iI6~MEKtD{@;yErqm4*e@jfyEHlrfL=YTrF&ZynH5%ei+;GP!y<=t6}WB^TUo6;Ssq#MbX(g(%R$3t!>V@+5WO%gM70&8v0S%RLh=_`3` z*}5qvv#s6(zhtW)ORY03)z*}e%~a>h5uFN91+_-0kZBBph~IjdU9`MkKl*&&jH^o( zI@z6Ui*Khni8s^C>->)0{g(lCPoHoj$Nfe#RtXR1XqXOF4Fm_Oo^+cX3ysf@E^cp9 z->6}8_S3#oS2~NF(+vP;Pt&KE1oo@p^n}7GdU<0rZ8m)Pt28?wIoi8XNC<{;m+60z zQ0Uqz@jNBb)-Nm7YC1dHqs)%w>L@Ce4LJ2rm3%G-Wbd4vR^;K(@VX4Tkw_?qScW}n zUpB*2EMB+t5d3c48o*7POywq=$*+s8izyg#e(>Hjll{IF&D4!!_BMWl=a`yyZ;2pVu!|1n z@V=SI3Rfi}F0gO6>ztujD4bAWhg_6g`j`_;bXH%R8INQ-zr1Q2tv>MG|DyFpWx{R_~A3OcAcDAU6r@&{&}MGK#qT?6;q=>HwL(>y}4DY zJAG^AqUC1Rn|`=5ssw8Jq69RGtJ=`Lcz!j<*|Oz{yKM9RmFr(whoB$m)O-V7$)9p# zCMFwJa*Q6Y+rOet0xh3rOAOuCm~mE#YTpK&a?EGbq12A)JFiwp(X`GF5XuQ5{N2xR z`bQSWn-x|<^=66N22~|^Vbh1aGqS795KBS)%Gj8$ne`8qkqYmJzwsXaa!O(w5bYR% z^el$82|7g=YXKu>*X))ln&5DoEq;3e!rZCw&(moH9mrp7bUC7x6z(V8W&!C>G zMr5!1i9FkJ;!~7xs((nCn z+=CR-UdEU%i+esvA}o|NN%&DbqJvrHW{4Ji9yXaKoA$zys$kVZ24{cEvH~OHhl*(R z{qy6%`k>^c>GnC7BkqA(Mb7@_9U7*K14L22A9X~w&T)Jj@bFlz>n&9N%>&PVYt3IT zyCDxlh8fjETIZUV)>u)=8_AuqmcHs&mGV^7-i-|RltB2U?GD8H02`&J>mDD*IGjf} z#_Zoy#=`?dq=RO!DAadeUyUPtx#9tH=xC@<3|k4q(@mW5BPL@o$2V=Ys7NicdsS`$ zzp?b??QZ9^#po-&&;2p14-}hvXy6*9)fq!^pDXW<8FXxqfzCfn7h*;H{8xgX$3naZ z$SBbHPDKOJpv|e#gfsEuz>}!_JZG_Oz>Dgx7jN^UK}TH4L*kv=0Gs%Qao`l%;a#~E zSffd-(L`fDKFR8!*?!NX8=&Xx$zFJ70cyHWWQmI*8Vv_)iV$*WRem>mPm2_J100bLvGU`C)j)&ps`86*cknl4`ar8@I&-ri4x~HSvV5y z7mF8_`Lwv$h)hO(8eV)a#T+in96 z8R7Eh_!za_$w`JiSrxTrFPu+zagC>-Fsf0QY&?lnVMuB!y**{ON&u#1rz8WJlO=SQ zPA99_qqae4-xs1UWJ}ofcQl2*iYu8~afp_*?jVS;OxAJ@m=y-vFSbsF7RUQvA>{zQ9 z@|&TT7_o9<_oS_3wR56tX#P07W8#yk%(K|Agj{&~e9nw30lj9gre;440a1d!A1O)U z*D87uvjnTQ8>k90$PsG*U0NTFP7HgfLopk@8n}2asl=2?M+c|AUEvu90uPQ64m9OD z>`m|p|9IsW?XM1zO%kCjvXh2Gt|AVHgD1Fx+}-3+^0Ln<|VWpEaB7mW?j?y zBRR;x<)NXGBC%=1sUXnQtuNV{*_d0(fmb}*l)(%>DfyusWsY_)fKrbqLs#xL-%ost~7k$_< z>dBa)Nlli9b6HU0lM*xggo&a^Z}ic0UW6ub*6g^)EOCWk;G3;gxVEGiLqS=uSax;6 zZSn`z91J8yt8Z*d+rH@yS&!(KEUa}MccYv^TT?>Fi=DGAxNn*Z(|19E;(j94DU(-| z>b;$+@+Q-?Uz2S5rfK@6?a}>n`Gl^)){r6!#Mt>=2$|ZOo*7hXWsp27sbo2-mu zqcmO`RoJ|WSYC=tyZQOP-H|fFlAk8v?3;4kGqt&nC59aJ;nk=cj5C>BY^JL>&Rt%x zUd5bx{kr;~XQnT>AB}Zp6cJVs0;)Qzi1as?F%=sKNYqwFO_W4g8Lz+0*vgxwZX!mx zt$ti!0wS+mbgM7{&hnbicAW%V%q#Zl4RzAmlHuiMJ)SR`rLzp1lrYFJ%l7)jWMhHW zo$T}4=9#zo+}V#_*c~su!q+|Kg z*ZLxPrpSgB9Vmp@PwK1P3=PI9wGsNejQwO)qbxYJuxmevU;0$XUY1%Cn0sT%-?`RF zu#?C7l;Ftn3Qybb_r|p;Pp;9c@M4 zuyCTc(iAhl!AN(84+m{THKkSN+hk7SaCgqNH)~dL+UB}SVno^~(YJ_aO9t$j3Xgq- zz^DJ(J_WbC{o%kwV7RSSVlRoD804zfpTThqr#!G4T+~V|8sXZ97H=HrVU>lwic(Z+ zfK@x+*amP2vvQJdcPd`i@Jl9_u?7a|<3@DL1;i4w@7PfNom#(=p(Jh)=T-HjQBs~M z!6p?uh!jli>#dWR_YlDZwj3Um7LXLaE^11}L$NNTS z8C`yhh3%wU^zL%oqX&85^6Oj-L)f^de}PL)ZCb>_?$2XAjE!RRAvKquySyWeH3e!8ltvJO z6jB4%-mu=!Zv#%ofGkNFEw42(%4Iv4{RT=W{%Ff*L4TxCH`{iU2a>9e>@BRC^f%s; ziXm0I%NyV$ycZ?&1Ck4;LLp0MuuY=l2HthnMP5CMWxPAI)+6y(vnziQDTIQk>*s}n zY1(2P8jv@YX}WzP!Kz-fJS=j>d|kq(zHoqA{;1Y;gOW!fY4YkBITK5rR9-~fwT}8i z50{SC($bjC;Gn9xjE(wJlTPc`=ebJ@GdV#*@C$#ZyklzPXW?LV!8i&3#p?fF`sq%{ zsG$a!Tr$k<>m@ue-kP6g)!`7(*Pf>4$y(7636A~OtIIx-l~2{Lf5hfL@oTE|ch zq%_Q~?l2kkXP|oi=gsstP3*-S4t|#{GCB9)wGK&(QHqpGbMq=Uw znEQ*0@45RDECW?4$lQ64m??Jg0q-Ghypq zHMArH;j1+Up`p$Pk8IX@)45Pat$)@NE~*GyFrj-TG!4MYO#-97alhFH*V zP)e#}aq{q$k1gdTX|J{tUmvq>X4^Zv8r=2@nS6I{z^=@aB33jS*#mwmJg^w(Up-MJ9Tg9G1!@W5$@9SvL zAeB@~uXQpqZNx04DP+6QWC*hXdXisERy#H^%Qw}O<_58PWgHodR$IA#v0!sO=n5Yl z*x2R%dOqiJEMMt1;WLsuYXRIP*eRfZ36k~yG!J-%2Xae^C)q!(lFSGXtC8o=$ zp%{%{nMJUC);3*h99=q*4&|4XMjq2~0>JbG2Sw&*XY)Rx+TL%;~#5otIN(Hx` zMd1XUsnjt*85@=?To(4N@g5$GOcmPM-lroZs_avX9em`F(nY0r4ioC6B#QF9rA%7# zw56&QVxSZ~<@uat;=Qy)jmR_%LYp!e86q^?)}wdq-(2>)N2n@w^)m0FUCSY?qHRE* zbxgoTGxyd#&+FHH0=5D2hxh61; z9%V=Mm41kYd0TNsO|C@kOto73yV2QFz#xOHGQ2wYY`Vmgu>{_j$uPZvG@ICmsPed9*WGaD3v@#h90fV z&`pb$P&Hukx1>WlToh?9Lt+a#P;qx#(^E3!=<22Uq%QByGS^OnN|GyG0#CWE0TFAA z!dURgHOF;hEPDBuXt_`ID65*Aa`!b*z#>Q3raa#uO^s(wc?>t}_{r=<#Bz&o3i)bD zIUWWDK>YwG{!|j&J{A#!z_wD zav`7GPYYGu*Lx=n$4YM_$wfBK7>)2&@jbrWrp`8W&w8A}N)PGEZca7N7Aon9OPJ(n z(51~I8Y`ntA;!E`B6>p4&-o7LH&n~R=VyH~Hg@EFFsH+4u6-M+GqRJzV~gq=FIBdz z@>MF~NvYRZ1U;QjQkSGwQ~zw0Idk*Y!kGku2t)+i(ZnHG@xXtv?Y20{$^kY9~G12JndWn+9Di zvHIJ9cly)8zn!l?h96TKB-My&N6Eo(1TbvFcO&QmQNsban9dE z=yKJv7da?ni6)mz=Q)I6*|n#W8mn(y_?&|YSf_#SWpRByDOXH_%(v z>=P@vSaPW8928h%E*Q8S2MOFB63Vh4@K0L=d>L{|X6B(kT=feKI3wA=slF+w0INio zUg|0=oXY;{X8+J5Y02|N8_?)0hWeZeeaRN1=3`71FX;^bXyyjy+|y#j6}&!>JB_XCAt|t?rscIZTRL$uDg|WL&7&DIa*edH?6M>a#_u!X7ooHV=*tc1%dXm4b|LLu z_raQGUAGhHdX{gVcJA$&L=(Le0?bl1O(3&KaFp@lLeBc#$(#R4;Gg$g1=wNa8U&O$r1hz_y|g4mp&w_Z>C+9YqOd1@lqeU#lM*D6KR zx)R#G*4RerC89y}~IY<5X3GbU_b$i%b4G>}QytcFnCbC2MR`|OS6DbB>iT=yiyeOt`d!&& zXcuAg^&IzY3)!T|8s2Bk+rJHn*V*E9)@I9Q`={Y_a7ihY|LN4!vSv%aclW z5R2&KVcG2$x)5}R1YGh=3WahkeapeH7w3v-P^sGm&7^@zABIo*s#z1(r9MoNXIsiD z;V}f?OXq^2zswA54~0#cj&AE}X|1hqT54&1+e+4c72sF}kMhRh$8OE-iFTFO6!sci z0%Qwx?Daa3-sbb{tH6ODv$p|C#pn7YRUl5lT20eAwNnPVKd&ZZ8uTno z*W1}vCJ;7MosM~Q^&IMSC!pooCyBx(FB47SyG>8Etfldw{-tM-=nh6;PLKjACFtBB zC>`~wYk}?@lUNie zjEM38*}q*JAYm(qr>JtSnA0H!gthf=K6Vp}y-N+<{Xjqc7ZvT4#C)5H?$)uNmVpXJ zTVzu4GQ`@LQWrVIImUX`IAM8xP5X%3O{h)J*uYTwTuD;kZ06&dNP7Y=;#(^jNCIUzuJSJh}Vo z-Ct`R3F1gh;K->Eu$bur5M*qY>8j{)&Ahq7vC0IeToqK1n*fW%6+JdSE33wq&V1bW zAfFCB8rWLRe$3his9|F7BUaiHxb&i;!}|;KcV~=S2QAjstJxMsOvm?Zsrfu;nA-}A zs7bO+o5LxTo#4A3zxii#|B22YH!7s(antP|fV!wN5GN~{#hFfnvYMzH3+wZS@q9IV zyOP9;!YUIhCvjt_xS3nya#eW=l3z)$ydsENBkS)OeqTA9L+upIv8@(I) ze5^D7p3fHkZ7COWJhvmbUd`Gvtm;{{JoA?Nvt4%uBL7GVu`}zu3pty4PYL#B2fP{0 zX&Hq#*=yzqC(;l+D`i-0ew^gHRfBOpG~!!#riU%n0}YTG)=%7Y8XXLewO%%xSaeRs zj(UYl-1&)TQXHkh_rw|k1wUo`HG3knwQNRW<}yppBsk2T>bn^e`hg9R^J%VzQJM|v zl#!klRP|?H{2nX&gVZm;nC}rirZwK;HESehQRMwK(BF(!kUvESZg`?Q4V4K50&$U2 zA11{o_xfb2I^+<=A+4^rI$GGx-tC%APXd{X^`?jK^VcJ%vn3V1@)ZaDBGLOcoUeBp z`u7l3*dAq9P1tt;xfcYLna=)@y;`KIH=5B^<(%~(7@?=k;DvM!J%N#1mDWGrj=V5x z*OZG_5+3X0a$;~E*|Z@M@^nj79|IXSU={devPB>tBq6ec)5 zv6<4?GwM|8i&#kn)_c4dp0eyT8gdZ~-d0XFTr5W%tVvb3hRT$;2gkjvRB+CZuMCz3 zg)h#@Ch?6Pa`f|unLOB!2E3Q2e%gyvozG+{Js2#e#Xv3^#JQUW-6TGBK*YT=i*$c3`a@vb&bgt_XDR+QTFjVu@TY>bOjlmg;+U6F?>ZBh{%DMy0>d@U>`%{?0 z&QH$}nsEx_vK)({3g$5s;N0Cm+wdpSI4>oPk2UGRkKGu8XBXvFS0jw-#cB7_JV3&o z76w+(qVgHb<e)fPl`4cs zvyGd@q~XQakv9d7>EWE=tOHH`<1*N*DU^MRhnw0&g3{vjSJ2$-otU z#Dd0I`(a2vj^AN3WD*Hy+iA)5PJtwq+kOysCr~+>0yZ zWd!b_HhO)Sj{37X|AG`AH?C;MBn{48N9mnP~H*e+DBrj`<=Yj5InXY3;e^QZe{J0aW!|DMj-v2>be_KO`SeyQwm zHdkxLp@hyjQ^E?Q<1+KYaY_}6;!0ABw${*K?YKhD67EgLHekh)W4OhsL*8$k6qSxR zznN9pS7KN1PY(0zq*EQiK+9LKFkuQ-C++@X%t?~iINJ=1E{hqaS6PzkTf?BoFH$Ya z@&#V8fbA0Nvl7=IsxO1|~mzY)NG}~$yRm3*H zWcf(JC#E~vbDU^nfVPPmAl@f6mcACst=I<4DC$+PI|~^G%wlKRiSOg5Sbf0;N(eSP z2<;cVYDTmx|JIeDOukA35`7DrXmkD_hA?E~08)v^D}_FgN~iEdk=)_Jv{I-kbOObe zMQ#elFWPbqS-)2}^~L0xg$8VLmb+_WfnNW_!mOK}I_6S?t%*iNQb ze0)4ASN`~@mU)nvz?-$B*;O&jT1IIxTH;rWPZEr(R&pK!i+@uGV{-0P(#}v6z6|sSxHIKX%R$??Ea&gU|8nSZloL^b`yU(vqu!YzHoT4l2spZ|+ zz$wl0#wmDJk6A7sQfE?M7ztWqk=G--ay~Miy?1h1vLX5>riKQ-a#yh(G4C2E z8ZgqVl|g5X-Q3VM2vxI1r*&e=@3KSoq;=Q=1l9f+uT$LnDmgQBe|jcXxRa zV5y(>3w*#kHtoegsrPiFZIu6%Hb<6~8$DFZ4Tp!GV^$}Hek9Wjf8;=nXfo7~sJwn| zT^8zlb=X|^>Z=ImP2qYUqkx1q``vZCP}wtJoOH`ObN64t?pWjLWPTU$N~B{BQ^;g+t7w6i9zB4UlE)PX%VN0cA?{x<9HIfm*Pzg#P4 zDu?YY_i=zNlq$)lZ^@yoDI;@9GpcQ=4FyOf5;Y2|Rriw@EOAii7Y8C$N)%i3E()Sa z$juLe@Jm${Fs&bf-D^N8hKb5KR;)hMn893q^>O_T!*G&JwGL^PH0fogk^MBERDh_349Q-$-#oS$H{nIh<%U&|MCg>3l9;Y}`qV6@jc}GWEoC!&y>b@> z)L^IacgcU;9e2my#TBAYS#_i3z@^~lUfO54JdN9KRz|Sqc#ND}P~@da>31DGIpbQ< zAj6j%IHix_O+Yqx8GdGKc!v1WyR%oYULHvQL*QS*+UN&cWQvdcAkPUmTDgGyuqwhx zv<*~0gX|;n@1>Z!%RI_*c|$g~wS3$>LxxNYgC-q~79;byqkR*r%f<`nP6JelqEdZ; zcAH23!^=esN`P`BaazA8)?=2pf@F-DO?!>AnX|(~1=6I;t3zp!=GVxziqqUaSy9_n z<0yt@;^4}LvkqxlO*PtR#VAB_O6FZdrnOsT2?I>KDIx4j5P_C54+CZA@M z=8@*h@s4ibla>}WEM}i*oAmw^S}XSO-tzGG^1KpO_xg{G3(nO}l7EpDj0+ z&Zt_RAh;*3=7d__H$$w&%e0Zah$hfJsD>372o-Eujg7-vvnEAfWD;DbQ=hXk)hjXs zZbRyp6=ta;avj4gwvM45dt*qkq}V~kMm0lpLuQLO>=c{dMZ^Zr366<=I+#$V|Az3B z&&z*PjdYsnv7E#kZyPf!^5r|{xS1ZYk6Sx=9Flj+2%_})+-^)%j8$Z&M{5aW!BMK& ze8kHx1GEj;-vKpV8&z5eclj!DYa)F;($PWSMFp)vYRod$FFJL$4CBFJxCD>pbdKEK zhZ;Ot)>-zAxNNV%k2~D{jmm%K3n@JJ$xOPJeJm0VhWkfPg{=_<@%ACIj`j0s3-#Cc? zyKY`ZK}a4xha2^+Ud-~)mkVw~OoFAU-WYsPy)tYZ^li>)X9^MQQHsuQoLqslMy3Y9 zKSWL?z2%$L+2GxwS;ps_&rgb)k4#jd&>CY?B5hPFTRO?8%V5X}XXe~TR6Wu06mKS9 zl-j&`MIlv--H<-*x}m=;IFitN1`F{^mJUj4{C?tZwElXtiwXn>LV=%->W&z+IiLu+ zCBitqex9ldAAw6RnzvpUQ0YU?kIn4z)LI+%3D|tx9^1-P@H)*R!aqUG!Fgy17XDWM(mXNake-a6E_qL`SP2wUb1%YDM& z)a({sj0)d)?`G+DOuujmIxrtGCmj*>IMWy}ksjI2n)0WLQ>~$3s~WJt$E@2}Lwvzy zRG?fOEPBqXvq?oJ!E}sXl+xf(NKCq>xhEE7wnt7io>wy1fgA6tz}yEu4L;B`YU@eW z=uEBjIWK=+)$Nw;uq3{nQkTuN!IXH}=L~<-6L?-R3eUn8qIHHt-A{R@yO|xuM23BP zU0x~VuAsH@9vO8%pPH|YWMwLH7!xF8INiy?Sd#@oS9*XGa>wwlyujsiF-u{yLpfHw zbj{O)T7J~t9FApiNSpVW%#iH!-WYPQVnMv%@F1{jh^kqlJu2g^oTp?}Ws*tuv)g0= zWkpH4OYNn<97L=Moz{LAB1=3L(aWv3Tt6UJQyRN3{^QceVjc8LlvB5hJ@iB1Of1s|{pJu>z4A@NUY`M*da z!_^nQ{NY{8tw3SocOpkKEBrEHuQCJZ^yL78Zeq8sIGZP0*fa&J=4C3eD|p6ckCcLb znp<-jl@25hI_Z53@2D=sJa9nBtUGDAQ|2^$y|)3mixiG>`BH1$ml0PONtyZn2&0;n zP2e_Qb`3%USLM2gC|3`Oq}D{OB|OwUv2iD&m6?-?b%l?tAg43hhqw0FESs+`Y^W$m zB)LTLpusE33rxd>hQnt9R-IJlPR)!kUzd$&*kxc)*Bi#>mc_=5n>t)K1*gkL68sQe z@lVQC#P0>IbKE&&wwj#VF7=L^+|&-pOxhc!;jG2;J!A1G@)5v}Xa8MG!MKlfZ&qzx X^VZ~@FaIr!`rk$TKVKTVJ@9`3De)^) literal 0 HcmV?d00001 diff --git a/src/Admin/Field/EnumField.php b/src/Admin/Field/EnumField.php new file mode 100644 index 0000000..6f39f7b --- /dev/null +++ b/src/Admin/Field/EnumField.php @@ -0,0 +1,21 @@ +setProperty($propertyName) + ->setLabel($label) + ->setTemplatePath('@CleverAgeProcessUi/admin/field/enum.html.twig'); + } +} diff --git a/src/Admin/Field/LogLevelField.php b/src/Admin/Field/LogLevelField.php new file mode 100644 index 0000000..df0c2bf --- /dev/null +++ b/src/Admin/Field/LogLevelField.php @@ -0,0 +1,21 @@ +setProperty($propertyName) + ->setLabel($label) + ->setTemplatePath('@CleverAgeProcessUi/admin/field/log_level.html.twig'); + } +} diff --git a/src/CleverAgeProcessUiBundle.php b/src/CleverAgeProcessUiBundle.php index b89f243..90d6971 100644 --- a/src/CleverAgeProcessUiBundle.php +++ b/src/CleverAgeProcessUiBundle.php @@ -4,26 +4,16 @@ namespace CleverAge\ProcessUiBundle; -use CleverAge\ProcessUiBundle\DependencyInjection\Compiler\RegisterLogHandlerCompilerPass; +use CleverAge\ProcessUiBundle\DependencyInjection\Compiler\RegisterLogHandler; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class CleverAgeProcessUiBundle extends Bundle { - public const ICON_NEW = 'fa fa-plus'; - public const ICON_EDIT = 'far fa-edit'; - public const ICON_DELETE = 'fa fa-trash-o'; - public const LABEL_NEW = false; - public const LABEL_EDIT = false; - public const LABEL_DELETE = false; - public const CLASS_NEW = ''; - public const CLASS_EDIT = 'text-warning'; - public const CLASS_DELETE = ''; - public function build(ContainerBuilder $container): void { parent::build($container); - $container->addCompilerPass(new RegisterLogHandlerCompilerPass()); + $container->addCompilerPass(new RegisterLogHandler()); } public function getPath(): string diff --git a/src/Command/PurgeProcessExecution.php b/src/Command/PurgeProcessExecution.php deleted file mode 100644 index ba4e480..0000000 --- a/src/Command/PurgeProcessExecution.php +++ /dev/null @@ -1,88 +0,0 @@ -managerRegistry = $managerRegistry; - } - - /** - * @required - */ - public function setProcessLogDir(string $processLogDir): void - { - $this->processLogDir = $processLogDir; - } - - protected function configure(): void - { - $this->setName('cleverage:process-ui:purge'); - $this->setDescription('Purge process_execution table.'); - $this->setDefinition( - new InputDefinition([ - new InputOption( - 'days', - 'd', - InputOption::VALUE_OPTIONAL, - 'Days to keep. Default 180', - 180 - ), - new InputOption( - 'remove-files', - 'rf', - InputOption::VALUE_NEGATABLE, - 'Remove log files ? (default false)', - false - ), - ]) - ); - } - - public function execute(InputInterface $input, OutputInterface $output): int - { - $days = $input->getOption('days'); - $removeFiles = $input->getOption('remove-files'); - $date = new \DateTime(); - $date->modify("-$days day"); - if ($removeFiles) { - $finder = new Finder(); - $fs = new Filesystem(); - $finder->in($this->processLogDir)->date('before '.$date->format(DateTimeInterface::ATOM)); - $count = $finder->count(); - $fs->remove($finder); - $output->writeln("$count log files are deleted on filesystem."); - } - /** @var ProcessExecutionRepository $repository */ - $repository = $this->managerRegistry->getRepository(ProcessExecution::class); - $repository->deleteBefore($date); - - $output->writeln(<<Process Execution before {$date->format(DateTimeInterface::ATOM)} are deleted into database. - EOT); - - return Command::SUCCESS; - } -} diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index adeb90f..9cd756b 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -6,47 +6,44 @@ use CleverAge\ProcessUiBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; +use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Validator\ValidatorInterface; -/** - * Class UserCreateCommand. - */ -final class UserCreateCommand extends Command +#[AsCommand( + name: 'cleverage:process-ui:user-create', + description: 'Command to create a new admin into database for process ui.' +)] +class UserCreateCommand extends Command { - private ValidatorInterface $validator; - private UserPasswordHasherInterface $passwordEncoder; - private EntityManagerInterface $em; - public function __construct( - ValidatorInterface $validator, - UserPasswordHasherInterface $passwordEncoder, - EntityManagerInterface $em + private readonly ValidatorInterface $validator, + private readonly UserPasswordHasherInterface $passwordEncoder, + private readonly EntityManagerInterface $em ) { - $this->validator = $validator; - $this->passwordEncoder = $passwordEncoder; - $this->em = $em; parent::__construct(); } - protected function configure(): void - { - $this->setName('cleverage:process-ui:user-create'); - $this->setDescription('Command to create a new admin into database for process ui.'); - } - protected function execute(InputInterface $input, OutputInterface $output): int { $style = new SymfonyStyle($input, $output); $username = $this->ask('Please enter the email.', $style, [new Email()]); - $password = $this->ask('Please enter the user password.', $style, [new NotBlank(), new Length(min: 8)]); + + $password = $this->askPassword( + (new Question('Please enter the user password.'))->setHidden(true)->setHiddenFallback(false), + $input, + $output + ); $user = new User(); $user->setEmail($username); @@ -62,7 +59,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } /** - * @param array $constraints + * @param Constraint[] $constraints */ private function ask(string $question, SymfonyStyle $style, array $constraints = []): mixed { @@ -77,4 +74,21 @@ private function ask(string $question, SymfonyStyle $style, array $constraints = return $value; } + + private function askPassword(Question $question, InputInterface $input, OutputInterface $output): mixed + { + $constraints = [new NotBlank(), new Length(min: 8)]; + /** @var QuestionHelper $helper */ + $helper = $this->getHelper('question'); + $password = $helper->ask($input, $output, $question); + $violations = $this->validator->validate($password, $constraints); + while ($violations->count() > 0) { + $violationsMessage = $violations->get(0)->getMessage(); + $output->writeln("$violationsMessage"); + $password = $helper->ask($input, $output, $question); + $violations = $this->validator->validate($password, $constraints); + } + + return $password; + } } diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php new file mode 100644 index 0000000..5cc7f1a --- /dev/null +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -0,0 +1,73 @@ +setFormat('Y/M/dd H:mm:ss'), + ArrayField::new('context') + ->setTemplatePath('@CleverAgeProcessUi/admin/field/array.html.twig') + ->onlyOnDetail(), + BooleanField::new('contextIsEmpty', 'Has context info ?') + ->onlyOnIndex() + ->renderAsSwitch(false), + ]; + } + + public function configureCrud(Crud $crud): Crud + { + return $crud->showEntityActionsInlined()->setPaginatorPageSize(250); + } + + public function configureActions(Actions $actions): Actions + { + return Actions::new() + ->add(Crud::PAGE_INDEX, Action::new('detail', false, 'fas fa-eye') + ->setHtmlAttributes( + [ + 'data-bs-toggle' => 'tooltip', + 'data-bs-placement' => 'top', + 'title' => 'Show details', + ] + ) + ->linkToCrudAction('detail')) + ->add(Crud::PAGE_DETAIL, 'index'); + } + + public function configureFilters(Filters $filters): Filters + { + return $filters->add('processExecution') + ->add( + ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) + ) + ->add('createdAt'); + } +} diff --git a/src/Controller/Admin/Process/ExecuteAction.php b/src/Controller/Admin/Process/ExecuteAction.php new file mode 100644 index 0000000..8da0685 --- /dev/null +++ b/src/Controller/Admin/Process/ExecuteAction.php @@ -0,0 +1,33 @@ +get('process'); + if (null === $process) { + $this->createNotFoundException('Process is missing'); + } + $bus->dispatch(new ProcessExecuteMessage($process, null)); + $this->addFlash( + 'success', + 'Process has been added to queue. It will start as soon as possible' + ); + + return $this->redirectToRoute('process', ['routeName' => 'process_list']); + } +} diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php new file mode 100644 index 0000000..3c1cf4c --- /dev/null +++ b/src/Controller/Admin/Process/ListAction.php @@ -0,0 +1,26 @@ +render( + '@CleverAgeProcessUi/admin/process/list.html.twig', + [ + 'processes' => $registry->getProcessConfigurations(), + ] + ); + } +} diff --git a/src/Controller/Admin/Process/UploadAndExecuteAction.php b/src/Controller/Admin/Process/UploadAndExecuteAction.php new file mode 100644 index 0000000..ea540eb --- /dev/null +++ b/src/Controller/Admin/Process/UploadAndExecuteAction.php @@ -0,0 +1,75 @@ + '\w+'], + methods: ['POST', 'GET'] +)] +#[IsGranted('ROLE_USER')] +class UploadAndExecuteAction extends AbstractController +{ + public function __invoke( + RequestStack $requestStack, + MessageBusInterface $messageBus, + #[Autowire(param: 'upload_directory')] string $uploadDirectory, + #[ValueResolver('process')] ProcessConfiguration $processConfiguration + ): Response { + if (null === $processConfiguration->getEntryPoint()) { + throw new \RuntimeException('You must set an entry_point.'); + } + if (false === ($processConfiguration->getOptions()['ui']['upload_and_run'] ?? false)) { + throw new \RuntimeException('ui.upload_and_run options not set to true in process options.'); + } + $form = $this->createForm( + ProcessUploadFileType::class, + null, + ['process_code' => $requestStack->getMainRequest()?->get('process')] + ); + $form->handleRequest($requestStack->getMainRequest()); + if ($form->isSubmitted() && $form->isValid()) { + /** @var UploadedFile $file */ + $file = $form->getData(); + $savedFilepath = sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $file->getClientOriginalExtension()); + (new Filesystem())->dumpFile($savedFilepath, $file->getContent()); + $messageBus->dispatch( + new ProcessExecuteMessage( + $form->getConfig()->getOption('process_code'), + $savedFilepath + ) + ); + $this->addFlash( + 'success', + 'Process has been added to queue. It will start as soon as possible' + ); + + return $this->redirectToRoute('process', ['routeName' => 'process_list']); + } + + return $this->render( + '@CleverAgeProcessUi/admin/process/upload_and_execute.html.twig', + [ + 'form' => $form->createView(), + ] + ); + } +} diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php new file mode 100644 index 0000000..a0a323c --- /dev/null +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -0,0 +1,57 @@ +container->get(AdminUrlGenerator::class); + + return $this->redirect($adminUrlGenerator->setController(ProcessExecutionCrudController::class)->generateUrl()); + } + + public function configureDashboard(): Dashboard + { + return Dashboard::new() + ->setTitle(''); + } + + public function configureMenuItems(): iterable + { + yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home'); + yield MenuItem::subMenu('Process', 'fas fa-gear')->setSubItems( + [ + MenuItem::linkToRoute('Process list', 'fas fa-list', 'process_list'), + MenuItem::linkToCrud('Executions', 'fas fa-rocket', ProcessExecution::class), + MenuItem::linkToCrud('Logs', 'fas fa-pen', LogRecord::class), + ] + ); + if ($this->isGranted('ROLE_ADMIN')) { + yield MenuItem::subMenu('Users', 'fas fa-user')->setSubItems( + [ + MenuItem::linkToCrud('User List', 'fas fa-user', User::class), + ] + ); + } + } +} diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php new file mode 100644 index 0000000..246cf0d --- /dev/null +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -0,0 +1,131 @@ +setFormat('Y/M/dd H:mm:ss'), + DateTimeField::new('endDate')->setFormat('Y/M/dd H:mm:ss'), + TextField::new('source')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_source.html.twig'), + TextField::new('target')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_target.html.twig'), + TextField::new('duration')->formatValue(function($value, ProcessExecution $entity) { + return $entity->duration(); // returned format can be changed here + }), + ArrayField::new('report')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), + ]; + } + + public function configureCrud(Crud $crud): Crud + { + $crud->showEntityActionsInlined(); + $crud->setDefaultSort(['startDate' => 'DESC']); + + return $crud; + } + + public function configureActions(Actions $actions): Actions + { + return Actions::new() + ->add( + Crud::PAGE_INDEX, + Action::new('showLogs', false, 'fas fa-eye') + ->setHtmlAttributes( + [ + 'data-bs-toggle' => 'tooltip', + 'data-bs-placement' => 'top', + 'title' => 'Show logs stored in database', + ] + ) + ->linkToCrudAction('showLogs') + )->add( + Crud::PAGE_INDEX, + Action::new('downloadLogfile', false, 'fas fa-download') + ->setHtmlAttributes( + [ + 'data-bs-toggle' => 'tooltip', + 'data-bs-placement' => 'top', + 'title' => 'Download log file', + ] + ) + ->linkToCrudAction('downloadLogFile') + ); + } + + public function showLogs(AdminContext $adminContext): RedirectResponse + { + /** @var AdminUrlGenerator $adminUrlGenerator */ + $adminUrlGenerator = $this->container->get(AdminUrlGenerator::class); + $url = $adminUrlGenerator + ->setController(LogRecordCrudController::class) + ->setAction('index') + ->setEntityId(null) + ->set( + 'filters', + [ + 'processExecution' => [ + 'comparison' => '=', + 'value' => $this->getContext()->getEntity()->getInstance()->getId(), + ], + ] + ) + ->generateUrl(); + + return $this->redirect($url); + } + + public function downloadLogFile( + AdminContext $context, + #[Autowire(param: 'kernel.logs_dir')] string $directory, + ): Response { + /** @var ProcessExecution $processExecution */ + $processExecution = $context->getEntity()->getInstance(); + $filepath = $directory.DIRECTORY_SEPARATOR.$processExecution->code.DIRECTORY_SEPARATOR + .$processExecution->logFilename; + $basename = basename($filepath); + $content = file_get_contents($filepath); + if (false === $content) { + throw new NotFoundHttpException('Log file not found.'); + } + $response = new Response($content); + $response->headers->set('Content-Type', 'text/plain; charset=utf-8'); + $response->headers->set('Content-Disposition', "attachment; filename=\"$basename\""); + + return $response; + } + + public function configureFilters(Filters $filters): Filters + { + return $filters->add('code')->add('startDate'); + } +} diff --git a/src/Controller/Admin/Security/LoginController.php b/src/Controller/Admin/Security/LoginController.php new file mode 100644 index 0000000..f39026c --- /dev/null +++ b/src/Controller/Admin/Security/LoginController.php @@ -0,0 +1,24 @@ +render( + '@CleverAgeProcessUi/admin/login.html.twig', + [ + 'page_title' => 'Login', + 'target_path' => '/process', + ] + ); + } +} diff --git a/src/Controller/Admin/Security/LogoutController.php b/src/Controller/Admin/Security/LogoutController.php new file mode 100644 index 0000000..e272d38 --- /dev/null +++ b/src/Controller/Admin/Security/LogoutController.php @@ -0,0 +1,21 @@ +logout(); + + return $this->redirectToRoute('process_login'); + } +} diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php new file mode 100644 index 0000000..8cc3cd4 --- /dev/null +++ b/src/Controller/Admin/UserCrudController.php @@ -0,0 +1,91 @@ + $roles */ + public function __construct(private array $roles) + { + } + + public function configureCrud(Crud $crud): Crud + { + $crud->showEntityActionsInlined(); + $crud->setEntityPermission('ROLE_ADMIN'); + + return $crud; + } + + public static function getEntityFqcn(): string + { + return User::class; + } + + public function configureFields(string $pageName): iterable + { + yield FormField::addTab('Credentials')->setIcon('fa fa-key'); + yield EmailField::new('email'); + yield TextField::new('password', 'New password') + ->onlyOnForms() + ->setFormType(RepeatedType::class) + ->setFormTypeOptions( + [ + 'type' => PasswordType::class, + 'first_options' => [ + 'label' => 'New password', + 'hash_property_path' => 'password', + 'always_empty' => false, + ], + 'second_options' => ['label' => 'Repeat password'], + 'mapped' => false, + ] + ); + + yield FormField::addTab('Informations')->setIcon('fa fa-user'); + yield TextField::new('firstname'); + yield TextField::new('lastname'); + + yield FormField::addTab('Roles')->setIcon('fa fa-theater-masks'); + yield ChoiceField::new('roles', false) + ->setChoices($this->roles) + ->setFormTypeOptions(['multiple' => true, 'expanded' => true]); + } + + public function configureActions(Actions $actions): Actions + { + return $actions + ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { + return $action->setIcon('fa fa-plus') + ->setLabel(false) + ->addCssClass(''); + })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { + return $action->setIcon('fa fa-edit') + ->setLabel(false) + ->addCssClass('text-warning'); + })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { + return $action->setIcon('fa fa-trash-o') + ->setLabel(false) + ->addCssClass(''); + })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { + return $action->setLabel('Delete') + ->addCssClass(''); + }); + } +} diff --git a/src/Controller/Crud/ProcessCrudController.php b/src/Controller/Crud/ProcessCrudController.php deleted file mode 100644 index ee17c4b..0000000 --- a/src/Controller/Crud/ProcessCrudController.php +++ /dev/null @@ -1,141 +0,0 @@ -processUiConfigurationManager = $processUiConfigurationManager; - } - - public static function getEntityFqcn(): string - { - return Process::class; - } - - public function configureCrud(Crud $crud): Crud - { - $crud->showEntityActionsInlined(); - $crud->setDefaultSort(['lastExecutionDate' => SortOrder::DESC]); - $crud->setEntityPermission('ROLE_ADMIN'); - $crud->setSearchFields(['processCode', 'source', 'target']); - - return $crud; - } - - /** - * @return array - */ - public function configureFields(string $pageName): array - { - return [ - Field::new('processCode', 'Process'), - 'source', - 'target', - 'lastExecutionDate', - IntegerField::new('lastExecutionStatus')->formatValue(static function (?int $value) { - return match ($value) { - ProcessExecution::STATUS_FAIL => '', - ProcessExecution::STATUS_START => '', - ProcessExecution::STATUS_SUCCESS => '', - default => '', - }; - }), - ]; - } - - public function configureActions(Actions $actions): Actions - { - $actions->remove(Crud::PAGE_INDEX, Action::EDIT); - $actions->remove(Crud::PAGE_INDEX, Action::DELETE); - $actions->remove(Crud::PAGE_INDEX, Action::NEW); - $runProcess = Action::new('run', '', 'fa fa-rocket') - ->linkToCrudAction('runProcessAction'); - $runProcess->setHtmlAttributes(['data-toggle' => 'tooltip', 'title' => 'Run process in background']); - $runProcess->displayIf(fn (Process $process) => $this->processUiConfigurationManager->canRun($process)); - $viewHistoryAction = Action::new('viewHistory', '', 'fa fa-history') - ->linkToCrudAction('viewHistoryAction'); - $viewHistoryAction->setHtmlAttributes(['data-toggle' => 'tooltip', 'title' => 'View executions history']); - $actions->add(Crud::PAGE_INDEX, $viewHistoryAction); - $actions->add(Crud::PAGE_INDEX, $runProcess); - - return $actions; - } - - public function runProcessAction(AdminContext $context): Response - { - try { - /** @var Process $process */ - $process = $context->getEntity()->getInstance(); - if (false === $this->processUiConfigurationManager->canRun($process)) { - $this->addFlash( - 'warning', - 'Process is not run-able via Ui.' - ); - } else { - $message = new ProcessRunMessage($process->getProcessCode()); - $this->dispatchMessage($message); - $this->addFlash( - 'success', - 'Process has been added to queue. It will start as soon as possible' - ); - } - } catch (Exception $e) { - $this->addFlash('warning', 'Cannot run process.'); - } - - /** @var AdminUrlGenerator $routeBuilder */ - $routeBuilder = $this->get(AdminUrlGenerator::class); - - return $this->redirect( - $routeBuilder->setController(__CLASS__)->setAction(Action::INDEX)->generateUrl() - ); - } - - public function viewHistoryAction(AdminContext $adminContext): RedirectResponse - { - /** @var AdminUrlGenerator $routeBuilder */ - $routeBuilder = $this->get(AdminUrlGenerator::class); - /** @var Process $process */ - $process = $adminContext->getEntity()->getInstance(); - - return $this->redirect( - $routeBuilder - ->setController(ProcessExecutionCrudController::class) - ->setEntityId(null) - ->setAction(Action::INDEX) - ->setAll([ - 'filters' => [ - 'processCode' => ['comparison' => ComparisonType::EQ, 'value' => $process->getProcessCode()], - ], - ]) - ->generateUrl() - ); - } -} diff --git a/src/Controller/Crud/ProcessExecutionCrudController.php b/src/Controller/Crud/ProcessExecutionCrudController.php deleted file mode 100644 index c5e8a4c..0000000 --- a/src/Controller/Crud/ProcessExecutionCrudController.php +++ /dev/null @@ -1,146 +0,0 @@ -indexLogs = $indexLogs; - } - - /** - * @required - */ - public function setProcessLogDir(string $processLogDir): void - { - $this->processLogDir = $processLogDir; - } - - /** - * @required true - */ - public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void - { - $this->processUiConfigurationManager = $processUiConfigurationManager; - } - - public static function getEntityFqcn(): string - { - return ProcessExecution::class; - } - - public function configureCrud(Crud $crud): Crud - { - $crud->showEntityActionsInlined(); - $crud->setDefaultSort(['startDate' => SortOrder::DESC]); - $crud->setEntityPermission('ROLE_ADMIN'); - $crud->setSearchFields(true === $this->indexLogs ? ['processCode', 'source', 'target', 'logRecords.message'] : ['processCode', 'source', 'target']); - - return $crud; - } - - /** - * @return array - */ - public function configureFields(string $pageName): array - { - return [ - Field::new('processCode', 'Process'), - 'source', - 'target', - 'startDate', - 'endDate', - IntegerField::new('status')->formatValue(static function (?int $value) { - return match ($value) { - ProcessExecution::STATUS_FAIL => '', - ProcessExecution::STATUS_START => '', - ProcessExecution::STATUS_SUCCESS => '', - default => '', - }; - }), - ]; - } - - public function configureFilters(Filters $filters): Filters - { - $processCodeChoices = $this->processUiConfigurationManager->getProcessChoices(); - if (\count($processCodeChoices) > 0) { - $filters->add(ChoiceFilter::new('processCode', 'Process')->setChoices($processCodeChoices)); - } - - $sourceChoices = $this->processUiConfigurationManager->getSourceChoices(); - if (\count($sourceChoices) > 0) { - $filters->add(ChoiceFilter::new('source')->setChoices($sourceChoices)); - } - - $targetChoices = $this->processUiConfigurationManager->getTargetChoices(); - if (\count($targetChoices) > 0) { - $filters->add(ChoiceFilter::new('target')->setChoices($targetChoices)); - } - $filters->add(ChoiceFilter::new('status')->setChoices([ - 'failed' => ProcessExecution::STATUS_FAIL, - 'success' => ProcessExecution::STATUS_SUCCESS, - 'started' => ProcessExecution::STATUS_START, - ])); - $filters->add('startDate'); - $filters->add('endDate'); - - return $filters; - } - - public function configureActions(Actions $actions): Actions - { - $actions->remove(Crud::PAGE_INDEX, Action::EDIT); - $actions->remove(Crud::PAGE_INDEX, Action::DELETE); - $actions->remove(Crud::PAGE_INDEX, Action::NEW); - - $downloadLogAction = Action::new('downloadLog', '', 'fa fa-file-download') - ->linkToCrudAction('downloadLog'); - $downloadLogAction->setHtmlAttributes(['data-toggle' => 'tooltip', 'title' => 'Download log file']); - $actions->add(Crud::PAGE_INDEX, $downloadLogAction); - - return $actions; - } - - public function downloadLog(AdminContext $context): Response - { - /** @var ProcessExecution $processExecution */ - $processExecution = $context->getEntity()->getInstance(); - $filepath = $this->processLogDir.\DIRECTORY_SEPARATOR.$processExecution->getLog(); - $basename = basename($filepath); - $content = file_get_contents($filepath); - if (false === $content) { - throw new NotFoundHttpException('Log file not found.'); - } - $response = new Response($content); - $response->headers->set('Content-Type', 'text/plain; charset=utf-8'); - $response->headers->set('Content-Disposition', "attachment; filename=\"$basename\""); - - return $response; - } -} diff --git a/src/Controller/Crud/UserCrudController.php b/src/Controller/Crud/UserCrudController.php deleted file mode 100644 index d432029..0000000 --- a/src/Controller/Crud/UserCrudController.php +++ /dev/null @@ -1,128 +0,0 @@ -passwordHasher = $passwordHasher; - } - - public function configureCrud(Crud $crud): Crud - { - $crud->showEntityActionsInlined(); - $crud->setEntityPermission('ROLE_ADMIN'); - - return $crud; - } - - public static function getEntityFqcn(): string - { - return User::class; - } - - public function configureFields(string $pageName): iterable - { - yield FormField::addPanel('Credentials')->setIcon('fa fa-key'); - yield EmailField::new('email'); - yield TextField::new('password', 'New password') - ->onlyOnForms() - ->setFormType(RepeatedType::class) - ->setFormTypeOptions([ - 'type' => PasswordType::class, - 'first_options' => ['label' => 'New password'], - 'second_options' => ['label' => 'Repeat password'], - ]); - - yield FormField::addPanel('Informations')->setIcon('fa fa-user'); - yield TextField::new('firstname'); - yield TextField::new('lastname'); - - yield FormField::addPanel('Roles')->setIcon('fa fa-theater-masks'); - yield ChoiceField::new('roles', false) - ->setChoices(['ROLE_ADMIN' => 'ROLE_ADMIN', 'ROLE_USER' => 'ROLE_USER']) - ->setFormTypeOptions(['multiple' => true, 'expanded' => true]); - } - - public function configureActions(Actions $actions): Actions - { - return $actions - ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_NEW) - ->setLabel(CleverAgeProcessUiBundle::LABEL_NEW) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_NEW); - })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_EDIT) - ->setLabel(CleverAgeProcessUiBundle::LABEL_EDIT) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_EDIT); - })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_DELETE) - ->setLabel(CleverAgeProcessUiBundle::LABEL_DELETE) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE); - })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { - return $action->setLabel('Delete') - ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE); - }); - } - - public function createEditFormBuilder( - EntityDto $entityDto, - KeyValueStore $formOptions, - AdminContext $context - ): FormBuilderInterface { - $formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context); - - $this->addEncodePasswordEventListener($formBuilder); - - return $formBuilder; - } - - public function createNewFormBuilder( - EntityDto $entityDto, - KeyValueStore $formOptions, - AdminContext $context - ): FormBuilderInterface { - $formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context); - - $this->addEncodePasswordEventListener($formBuilder); - - return $formBuilder; - } - - protected function addEncodePasswordEventListener(FormBuilderInterface $formBuilder): void - { - $formBuilder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event): void { - /** @var User $user */ - $user = $event->getData(); - $password = $user->getPassword(); - if ($password) { - $user->setPassword($this->passwordHasher->hashPassword($user, $password)); - } - }); - } -} diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php deleted file mode 100644 index dc90303..0000000 --- a/src/Controller/DashboardController.php +++ /dev/null @@ -1,44 +0,0 @@ -container->get(AdminUrlGenerator::class); - - return $this->redirect($routeBuilder->setController(ProcessCrudController::class)->generateUrl()); - } - - public function configureDashboard(): Dashboard - { - return Dashboard::new()->setTitle('CleverAge Process UI'); - } - - public function configureMenuItems(): iterable - { - yield MenuItem::section('Process', 'fas fa-tasks')->setPermission('ROLE_ADMIN'); - yield MenuItem::linkToCrud('List', 'fa fa-list', Process::class)->setPermission('ROLE_ADMIN'); - yield MenuItem::linkToCrud('History', 'fa fa-history', ProcessExecution::class)->setPermission('ROLE_ADMIN'); - - yield MenuItem::section(); - yield MenuItem::section('Settings', 'fas fa-tools')->setPermission('ROLE_ADMIN'); - yield MenuItem::linkToCrud('Users', 'fa fa-users', User::class)->setPermission('ROLE_ADMIN'); - } -} diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php deleted file mode 100644 index 2c7c54f..0000000 --- a/src/Controller/SecurityController.php +++ /dev/null @@ -1,46 +0,0 @@ -getUser()) { - return $this->redirectToRoute('/'); - } - - // get the login error if there is one - $error = $authenticationUtils->getLastAuthenticationError(); - // last username entered by the user - $lastUsername = $authenticationUtils->getLastUsername(); - - return $this->render('@EasyAdmin/page/login.html.twig', [ - 'last_username' => $lastUsername, - 'error' => $error, - 'page_title' => 'Login', - 'username_parameter' => 'email', - 'username_label' => 'Email', - 'password_parameter' => 'password', - 'csrf_token_intention' => 'authenticate', - ]); - } - - /** - * @Route("/logout", name="app_logout") - */ - public function logout(): void - { - throw new \LogicException( - 'This method can be blank - it will be intercepted by the logout key on your firewall.' - ); - } -} diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index 504ae37..addd734 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -4,15 +4,19 @@ namespace CleverAge\ProcessUiBundle\DependencyInjection; -use CleverAge\ProcessUiBundle\Message\LogIndexerMessage; -use CleverAge\ProcessUiBundle\Message\ProcessRunMessage; +use CleverAge\ProcessUiBundle\Controller\Admin\ProcessDashboardController; +use CleverAge\ProcessUiBundle\Controller\Admin\UserCrudController; +use CleverAge\ProcessUiBundle\Entity\User; +use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; +use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; +use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -class CleverAgeProcessUiExtension extends Extension implements PrependExtensionInterface +final class CleverAgeProcessUiExtension extends Extension implements PrependExtensionInterface { public function load(array $configs, ContainerBuilder $container): void { @@ -21,7 +25,15 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $container->setParameter('clever_age_process_ui.index_logs.enabled', $config['index_logs']['enabled']); + $container->getDefinition(UserCrudController::class) + ->setArgument('$roles', array_combine($config['security']['roles'], $config['security']['roles'])); + $container->getDefinition(DoctrineProcessHandler::class) + ->addMethodCall('setEnabled', [$config['logs']['store_in_database']]) + ->addMethodCall('setLevel', [$config['logs']['database_level']]); + $container->getDefinition(ProcessHandler::class) + ->addMethodCall('setReportIncrementLevel', [$config['logs']['report_increment_level']]); + $container->getDefinition(ProcessDashboardController::class) + ->setArgument('$logoPath', $config['design']['logo_path']); } /** @@ -32,29 +44,49 @@ public function prepend(ContainerBuilder $container): void $container->loadFromExtension( 'doctrine_migrations', [ - 'migrations_paths' => ['CleverAgeProcessUi' => \dirname(__DIR__).'/Migrations'], + 'migrations_paths' => ['CleverAge\ProcessUiBundle\Migrations' => \dirname(__DIR__).'/Migrations'], ] ); $container->loadFromExtension( 'framework', [ - 'assets' => ['json_manifest_path' => null], 'messenger' => [ 'transport' => [ [ - 'name' => 'run_process', - 'dsn' => 'doctrine://default', - 'retry_strategy' => ['max_retries' => 0], - ], - [ - 'name' => 'index_logs', + 'name' => 'execute_process', 'dsn' => 'doctrine://default', 'retry_strategy' => ['max_retries' => 0], ], ], 'routing' => [ - ProcessRunMessage::class => 'run_process', - LogIndexerMessage::class => 'index_logs', + ProcessExecuteMessage::class => 'execute_process', + ], + ], + ] + ); + $container->loadFromExtension( + 'security', + [ + 'providers' => [ + 'process_user_provider' => [ + 'entity' => [ + 'class' => User::class, + 'property' => 'email', + ], + ], + ], + 'firewalls' => [ + 'main' => [ + 'provider' => 'process_user_provider', + 'form_login' => [ + 'login_path' => 'process_login', + 'check_path' => 'process_login', + ], + 'logout' => [ + 'path' => 'process_logout', + 'target' => 'process_login', + 'clear_site_data' => '*', + ], ], ], ] diff --git a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php b/src/DependencyInjection/Compiler/RegisterLogHandler.php similarity index 66% rename from src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php rename to src/DependencyInjection/Compiler/RegisterLogHandler.php index 3b28378..a4c258d 100644 --- a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php +++ b/src/DependencyInjection/Compiler/RegisterLogHandler.php @@ -4,15 +4,19 @@ namespace CleverAge\ProcessUiBundle\DependencyInjection\Compiler; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler; +use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; +use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -class RegisterLogHandlerCompilerPass implements CompilerPassInterface +class RegisterLogHandler implements CompilerPassInterface { public function process(ContainerBuilder $container): void { + if (!$container->hasDefinition('monolog.logger')) { + return; + } $loggers = [ 'monolog.logger.cleverage_process', 'monolog.logger.cleverage_process_task', @@ -22,7 +26,8 @@ public function process(ContainerBuilder $container): void if ($container->has($logger)) { $container ->getDefinition($logger) - ->addMethodCall('pushHandler', [new Reference(ProcessLogHandler::class)]); + ->addMethodCall('pushHandler', [new Reference(ProcessHandler::class)]) + ->addMethodCall('pushHandler', [new Reference(DoctrineProcessHandler::class)]); } } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 0e5c270..57473bb 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -4,6 +4,8 @@ namespace CleverAge\ProcessUiBundle\DependencyInjection; +use Monolog\Level; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -11,16 +13,32 @@ class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { - $treeBuilder = new TreeBuilder('clever_age_process_ui'); - $treeBuilder->getRootNode() + $tb = new TreeBuilder('clever_age_process_ui'); + /** @var ArrayNodeDefinition $rootNode */ + $rootNode = $tb->getRootNode(); + $rootNode ->children() - ->arrayNode('index_logs') - ->ignoreExtraKeys() - ->addDefaultsIfNotSet() + ->arrayNode('security') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('roles')->defaultValue(['ROLE_ADMIN'])->end(); // Roles displayed inside user edit form + $rootNode + ->children() + ->arrayNode('logs') + ->addDefaultsIfNotSet() ->children() - ->booleanNode('enabled')->defaultFalse()->end() - ?->end(); + ->booleanNode('store_in_database')->defaultValue(true)->end() // enable/disable store log in database (log_record table) + ->scalarNode('database_level')->defaultValue(Level::Debug->name)->end() // min log level to store log record in database + ->scalarNode('report_increment_level')->defaultValue(Level::Warning->name)->end() // min log level to increment process execution report + ->end(); + $rootNode + ->children() + ->arrayNode('design') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('logo_path')->defaultValue('bundles/cleverageprocessui/logo.jpg')->end() + ->end(); - return $treeBuilder; + return $tb; } } diff --git a/src/Entity/.gitignore b/src/Entity/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/Entity/Enum/ProcessExecutionStatus.php b/src/Entity/Enum/ProcessExecutionStatus.php new file mode 100644 index 0000000..1950783 --- /dev/null +++ b/src/Entity/Enum/ProcessExecutionStatus.php @@ -0,0 +1,12 @@ + */ + public readonly array $context; + + #[ORM\Column(type: 'datetime_immutable')] + public readonly \DateTimeImmutable $createdAt; + + public function getId(): ?int + { + return $this->id; + } + + public function __construct(\Monolog\LogRecord $record, ProcessExecution $processExecution) + { + $this->channel = (string) (new UnicodeString($record->channel))->truncate(64); + $this->level = $record->level->value; + $this->message = (string) (new UnicodeString($record->message))->truncate(512); + $this->context = $record->context; + $this->processExecution = $processExecution; + $this->createdAt = \DateTimeImmutable::createFromMutable(new \DateTime()); + } + + public function contextIsEmpty(): bool + { + return !empty($this->context); + } +} diff --git a/src/Entity/Process.php b/src/Entity/Process.php deleted file mode 100644 index 7d0ca7b..0000000 --- a/src/Entity/Process.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @ORM\OneToMany(targetEntity="CleverAge\ProcessUiBundle\Entity\ProcessExecution", mappedBy="process") - */ - private $executions; - - /** - * @ORM\Column(name="last_execution_status", type="integer", nullable=true) - */ - private ?int $lastExecutionStatus; - - public function __construct( - string $processCode, - ?string $source = null, - ?string $target = null, - ?DateTime $lastExecutionDate = null, - ?int $lastExecutionStatus = null - ) { - $this->processCode = $processCode; - $this->source = $source; - $this->target = $target; - $this->lastExecutionDate = $lastExecutionDate; - $this->lastExecutionStatus = $lastExecutionStatus; - } - - public function getId(): ?int - { - return $this->id; - } - - public function getProcessCode(): string - { - return $this->processCode; - } - - public function getSource(): ?string - { - return $this->source; - } - - public function getTarget(): ?string - { - return $this->target; - } - - public function getLastExecutionDate(): ?DateTimeInterface - { - return $this->lastExecutionDate; - } - - public function getLastExecutionStatus(): ?int - { - return $this->lastExecutionStatus; - } - - public function setLastExecutionDate(DateTimeInterface $lastExecutionDate): self - { - $this->lastExecutionDate = $lastExecutionDate; - - return $this; - } - - public function setLastExecutionStatus(int $lastExecutionStatus): self - { - $this->lastExecutionStatus = $lastExecutionStatus; - - return $this; - } -} diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 47ff1ac..b701f34 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -4,253 +4,86 @@ namespace CleverAge\ProcessUiBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; -use DateTime; -use DateTimeInterface; -use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Collection; +use CleverAge\ProcessUiBundle\Entity\Enum\ProcessExecutionStatus; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\String\UnicodeString; -/** - * @ORM\Entity(repositoryClass=ProcessExecutionRepository::class) - */ +#[ORM\Entity] +#[ORM\Index(columns: ['code'], name: 'idx_process_execution_code')] +#[ORM\Index(columns: ['start_date'], name: 'idx_process_execution_start_date')] class ProcessExecution { - public const STATUS_START = 0; - public const STATUS_SUCCESS = 1; - public const STATUS_FAIL = -1; + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column] + private ?int $id = null; - /** - * @ORM\Id - * @ORM\Column(type="integer") - * @ORM\GeneratedValue() - */ - private ?int $id; + #[ORM\Column(type: 'string', length: 255)] + public readonly string $code; - /** - * @ORM\Column(name="process_code", type="string", length=255, nullable=true) - */ - private ?string $processCode; + #[ORM\Column(type: 'string', length: 255)] + public readonly string $logFilename; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ - private ?string $source; + #[ORM\Column(type: 'datetime_immutable')] + public readonly \DateTimeImmutable $startDate; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ - private ?string $target; + #[ORM\Column(type: 'datetime_immutable', nullable: true)] + public ?\DateTimeImmutable $endDate = null; - /** - * @ORM\Column(type="datetime") - */ - private DateTimeInterface $startDate; + #[ORM\Column(type: 'string', enumType: ProcessExecutionStatus::class)] + public ProcessExecutionStatus $status; - /** - * @ORM\Column(type="datetime", nullable=true) - */ - private ?DateTimeInterface $endDate; - - /** - * @ORM\Column(type="integer") - */ - private int $status; - - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ - private ?string $response; - - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ - private ?string $data; - - /** - * @ORM\Column(type="json", nullable=true) - */ - private ?array $report; - - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ - private ?string $log; - - /** - * @ORM\ManyToOne(targetEntity="CleverAge\ProcessUiBundle\Entity\Process", inversedBy="executions") - * @ORM\JoinColumn(name="process_id", referencedColumnName="id", onDelete="SET NULL") - */ - private Process $process; - - /** - * @ORM\OneToMany(targetEntity="ProcessExecutionLogRecord", mappedBy="processExecution", cascade={"persist"}) - * - * @var Collection - */ - private Collection $logRecords; - - public function __construct(Process $process) - { - $this->process = $process; - $this->status = self::STATUS_START; - $this->startDate = new DateTime(); - $this->logRecords = new ArrayCollection(); - } + #[ORM\Column(type: 'json')] + private array $report = []; public function getId(): ?int { return $this->id; } - public function getProcessCode(): ?string - { - return $this->processCode; - } - - public function setProcessCode(?string $processCode): self - { - $this->processCode = $processCode; - - return $this; - } - - public function getSource(): ?string - { - return $this->source; - } - - public function setSource(?string $source): self - { - $this->source = $source; - - return $this; - } - - public function getTarget(): ?string - { - return $this->target; - } - - public function setTarget(?string $target): self - { - $this->target = $target; - - return $this; - } - - public function getStartDate(): DateTimeInterface - { - return $this->startDate; - } - - public function setStartDate(DateTimeInterface $startDate): self - { - $this->startDate = $startDate; - - return $this; - } - - public function getEndDate(): ?DateTimeInterface - { - return $this->endDate; - } - - public function setEndDate(DateTimeInterface $endDate): self - { - $this->endDate = $endDate; - - return $this; - } - - public function getStatus(): ?int + public function __construct(string $code, string $logFilename) { - return $this->status; + $this->code = (string) (new UnicodeString($code))->truncate(255); + $this->logFilename = $logFilename; + $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); + $this->status = ProcessExecutionStatus::Started; } - public function setStatus(int $status): self + public function setStatus(ProcessExecutionStatus $status): void { $this->status = $status; - - return $this; - } - - public function getResponse(): ?string - { - return $this->response; - } - - public function setResponse(?string $response): self - { - $this->response = $response; - - return $this; - } - - public function getData(): ?string - { - return $this->data; - } - - public function setData(?string $data): self - { - $this->data = $data; - - return $this; - } - - public function getLog(): ?string - { - return $this->log; } - public function setLog(string $log): self + public function end(): void { - $this->log = $log; - - return $this; + $this->endDate = \DateTimeImmutable::createFromMutable(new \DateTime()); } - public function addLogRecord(ProcessExecutionLogRecord $processExecutionLogRecord): void + public function __toString(): string { - $processExecutionLogRecord->setProcessExecution($this); - $this->logRecords->add($processExecutionLogRecord); + return sprintf('%s (%s)', $this->id, $this->code); } - /** - * @return Collection - */ - public function getLogRecords(): Collection + public function addReport(string $key, mixed $value): void { - return $this->logRecords; + $this->report[$key] = $value; } - /** - * @param Collection $logRecords - */ - public function setLogRecords(Collection $logRecords): self + public function getReport(string $key = null, mixed $default = null): mixed { - foreach ($logRecords as $logRecord) { - $this->addLogRecord($logRecord); + if (null === $key) { + return $this->report; } - return $this; + return $this->report[$key] ?? $default; } - public function getProcess(): Process + public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string { - return $this->process; - } - - public function getReport(): array - { - return $this->report ?? []; - } - - public function setReport(?array $report): self - { - $this->report = $report; - - return $this; + if (null === $this->endDate) { + return null; + } + $diff = $this->endDate->diff($this->startDate); + return $diff->format($format); } } diff --git a/src/Entity/ProcessExecutionLogRecord.php b/src/Entity/ProcessExecutionLogRecord.php deleted file mode 100644 index c70807b..0000000 --- a/src/Entity/ProcessExecutionLogRecord.php +++ /dev/null @@ -1,88 +0,0 @@ -logLevel = $logLevel; - $this->message = $message; - } - - public function getId(): ?int - { - return $this->id; - } - - public function getLogLevel(): int - { - return $this->logLevel; - } - - public function setLogLevel(int $logLevel): self - { - $this->logLevel = $logLevel; - - return $this; - } - - public function getMessage(): string - { - return $this->message; - } - - public function setMessage(string $message): self - { - $this->message = $message; - - return $this; - } - - public function setProcessExecution(ProcessExecution $processExecution): self - { - $this->processExecution = $processExecution; - - return $this; - } - - public function getProcessExecution(): ?ProcessExecution - { - return $this->processExecution; - } -} diff --git a/src/Entity/User.php b/src/Entity/User.php index 20dbed5..f89463e 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -4,49 +4,33 @@ namespace CleverAge\ProcessUiBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\UserRepository; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; -/** - * @ORM\Entity(repositoryClass=UserRepository::class) - * @ORM\Table(name="user") - */ +#[ORM\Entity] +#[ORM\Table(name: 'process_user')] +#[ORM\Index(columns: ['email'], name: 'idx_process_user_email')] class User implements UserInterface, PasswordAuthenticatedUserInterface { - /** - * @ORM\Id - * @ORM\GeneratedValue - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column] private ?int $id; - /** - * @ORM\Column(type="string", length=255, unique=true) - */ + #[ORM\Column(type: 'string', length: 255, unique: true)] private ?string $email; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $firstname; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $lastname; - /** - * @ORM\Column(type="json") - * - * @var array - */ + #[ORM\Column(type: 'json')] private array $roles = []; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $password; public function getId(): ?int @@ -110,11 +94,7 @@ public function getUsername(): string */ public function getRoles(): array { - $roles = $this->roles; - // guarantee every user at least has ROLE_USER - $roles[] = 'ROLE_USER'; - - return array_unique($roles); + return array_unique(['ROLE_USER'] + $this->roles); } /** diff --git a/src/Event/IncrementReportInfoEvent.php b/src/Event/IncrementReportInfoEvent.php deleted file mode 100644 index 4d10e7e..0000000 --- a/src/Event/IncrementReportInfoEvent.php +++ /dev/null @@ -1,28 +0,0 @@ -key = $key; - $this->processCode = $processCode; - } - - public function getKey(): string - { - return $this->key; - } - - public function getProcessCode(): string - { - return $this->processCode; - } -} diff --git a/src/Event/SetReportInfoEvent.php b/src/Event/SetReportInfoEvent.php deleted file mode 100644 index 20d14af..0000000 --- a/src/Event/SetReportInfoEvent.php +++ /dev/null @@ -1,35 +0,0 @@ -key = $key; - $this->value = $value; - $this->processCode = $processCode; - } - - public function getKey(): string - { - return $this->key; - } - - public function getValue(): mixed - { - return $this->value; - } - - public function getProcessCode(): string - { - return $this->processCode; - } -} diff --git a/src/EventSubscriber/Crud/ProcessCrudListener.php b/src/EventSubscriber/Crud/ProcessCrudListener.php deleted file mode 100644 index f8a7543..0000000 --- a/src/EventSubscriber/Crud/ProcessCrudListener.php +++ /dev/null @@ -1,38 +0,0 @@ -entityManager = $entityManager; - } - - /** - * @return array - */ - public static function getSubscribedEvents(): array - { - return [BeforeCrudActionEvent::class => 'syncProcessIntoDatabase']; - } - - public function syncProcessIntoDatabase(BeforeCrudActionEvent $event): void - { - if (Process::class === $event->getAdminContext()?->getEntity()->getFqcn()) { - /** @var ProcessRepository $repository */ - $repository = $this->entityManager->getRepository(Process::class); - $repository->sync(); - } - } -} diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index e9ed92f..9ededc7 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -5,161 +5,68 @@ namespace CleverAge\ProcessUiBundle\EventSubscriber; use CleverAge\ProcessBundle\Event\ProcessEvent; -use CleverAge\ProcessUiBundle\Entity\Process; +use CleverAge\ProcessUiBundle\Entity\Enum\ProcessExecutionStatus; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Event\IncrementReportInfoEvent; -use CleverAge\ProcessUiBundle\Event\SetReportInfoEvent; -use CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager; -use CleverAge\ProcessUiBundle\Message\LogIndexerMessage; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler; -use CleverAge\ProcessUiBundle\Repository\ProcessRepository; -use DateTime; -use Doctrine\ORM\EntityManagerInterface; -use RuntimeException; -use SplFileObject; +use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; +use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; +use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Uid\Uuid; -class ProcessEventSubscriber implements EventSubscriberInterface +final readonly class ProcessEventSubscriber implements EventSubscriberInterface { - private array $processExecution = []; - private EntityManagerInterface $entityManager; - private ProcessLogHandler $processLogHandler; - private MessageBusInterface $messageBus; - private ProcessUiConfigurationManager $processUiConfigurationManager; - private string $processLogDir; - private bool $indexLogs; - public function __construct( - EntityManagerInterface $entityManager, - ProcessLogHandler $processLogHandler, - MessageBusInterface $messageBus, - ProcessUiConfigurationManager $processUiConfigurationManager, - string $processLogDir, - bool $indexLogs + private ProcessHandler $processHandler, + private DoctrineProcessHandler $doctrineProcessHandler, + private ProcessExecutionManager $processExecutionManager ) { - $this->entityManager = $entityManager; - $this->processLogHandler = $processLogHandler; - $this->messageBus = $messageBus; - $this->processUiConfigurationManager = $processUiConfigurationManager; - $this->processLogDir = $processLogDir; - $this->indexLogs = $indexLogs; - } - - public static function getSubscribedEvents(): array - { - return [ - ProcessEvent::EVENT_PROCESS_STARTED => [ - ['syncProcessIntoDatabase', 1000], - ['onProcessStarted', 0], - ], - ProcessEvent::EVENT_PROCESS_ENDED => [ - ['onProcessEnded'], - ], - ProcessEvent::EVENT_PROCESS_FAILED => [ - ['onProcessFailed'], - ], - IncrementReportInfoEvent::NAME => [ - ['updateProcessExecutionReport'], - ], - SetReportInfoEvent::NAME => [ - ['updateProcessExecutionReport'], - ], - ]; } - public function onProcessStarted(ProcessEvent $event): void + public function onProcessStart(ProcessEvent $event): void { - $process = $this->entityManager->getRepository(Process::class) - ->findOneBy(['processCode' => $event->getProcessCode()]); - if (null === $process) { - throw new RuntimeException('Unable to found process into database.'); + if (false === $this->processHandler->hasFilename()) { + $this->processHandler->setFilename(sprintf('%s/%s.log', $event->getProcessCode(), Uuid::v4())); } - $processExecution = new ProcessExecution($process); - $processExecution->setProcessCode($event->getProcessCode()); - $processExecution->setSource($this->processUiConfigurationManager->getSource($event->getProcessCode())); - $processExecution->setTarget($this->processUiConfigurationManager->getTarget($event->getProcessCode())); - $logFilename = sprintf( - 'process_%s_%s.log', - $event->getProcessCode(), - sha1(uniqid((string) mt_rand(), true)) - ); - $this->processLogHandler->setLogFilename($logFilename, $event->getProcessCode()); - $this->processLogHandler->setCurrentProcessCode($event->getProcessCode()); - $processExecution->setLog($logFilename); - $this->entityManager->persist($processExecution); - $this->entityManager->flush(); - $this->processExecution[$event->getProcessCode()] = $processExecution; - } - - public function onProcessEnded(ProcessEvent $processEvent): void - { - if ($processExecution = ($this->processExecution[$processEvent->getProcessCode()] ?? null)) { - $this->processExecution = array_filter($this->processExecution); - array_pop($this->processExecution); - $this->processLogHandler->setCurrentProcessCode((string) array_key_last($this->processExecution)); - $processExecution->setEndDate(new DateTime()); - $processExecution->setStatus(ProcessExecution::STATUS_SUCCESS); - $processExecution->getProcess()->setLastExecutionDate($processExecution->getStartDate()); - $processExecution->getProcess()->setLastExecutionStatus( - ProcessExecution::STATUS_SUCCESS + if (null === $this->processExecutionManager->getCurrentProcessExecution()) { + $processExecution = new ProcessExecution( + $event->getProcessCode(), + basename($this->processHandler->getFilename()) ); - $this->entityManager->persist($processExecution); - $this->entityManager->flush(); - $this->dispatchLogIndexerMessage($processExecution); - $this->processExecution[$processEvent->getProcessCode()] = null; + $this->processExecutionManager->setCurrentProcessExecution($processExecution)->save(); } } - public function onProcessFailed(ProcessEvent $processEvent): void + public function success(ProcessEvent $event): void { - if ($processExecution = ($this->processExecution[$processEvent->getProcessCode()] ?? null)) { - $processExecution->setEndDate(new DateTime()); - $processExecution->setStatus(ProcessExecution::STATUS_FAIL); - $processExecution->getProcess()->setLastExecutionDate($processExecution->getStartDate()); - $processExecution->getProcess()->setLastExecutionStatus(ProcessExecution::STATUS_FAIL); - $this->entityManager->persist($processExecution); - $this->entityManager->flush(); - $this->dispatchLogIndexerMessage($processExecution); - $this->processExecution[$processEvent->getProcessCode()] = null; - } + $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Finish); + $this->processExecutionManager->getCurrentProcessExecution()?->end(); + $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); } - public function syncProcessIntoDatabase(): void + public function fail(ProcessEvent $event): void { - /** @var ProcessRepository $repository */ - $repository = $this->entityManager->getRepository(Process::class); - $repository->sync(); + $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Failed); + $this->processExecutionManager->getCurrentProcessExecution()?->end(); + $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); } - protected function dispatchLogIndexerMessage(ProcessExecution $processExecution): void + public function flushDoctrineLogs(ProcessEvent $event): void { - if ($this->indexLogs && null !== $processExecutionId = $processExecution->getId()) { - $filePath = $this->processLogDir.\DIRECTORY_SEPARATOR.$processExecution->getLog(); - $file = new SplFileObject($filePath); - $file->seek(\PHP_INT_MAX); - $chunkSize = LogIndexerMessage::DEFAULT_OFFSET; - $chunk = (int) ($file->key() / $chunkSize) + 1; - for ($i = 0; $i < $chunk; ++$i) { - $this->messageBus->dispatch( - new LogIndexerMessage( - $processExecutionId, - $this->processLogDir.\DIRECTORY_SEPARATOR.$processExecution->getLog(), - $i * $chunkSize - ) - ); - } - } + $this->doctrineProcessHandler->flush(); } - public function updateProcessExecutionReport(IncrementReportInfoEvent|SetReportInfoEvent $event): void + public static function getSubscribedEvents(): array { - if ($processExecution = ($this->processExecution[$event->getProcessCode()] ?? false)) { - $report = $processExecution->getReport(); - $event instanceof IncrementReportInfoEvent - ? $report[$event->getKey()] = ($report[$event->getKey()] ?? 0) + 1 - : $report[$event->getKey()] = $event->getValue(); - $processExecution->setReport($report); - } + return [ + ProcessEvent::EVENT_PROCESS_STARTED => 'onProcessStart', + ProcessEvent::EVENT_PROCESS_ENDED => [ + ['flushDoctrineLogs', 100], + ['success', 100], + ], + ProcessEvent::EVENT_PROCESS_FAILED => [ + ['flushDoctrineLogs', 100], + ['fail', 100], + ], + ]; } } diff --git a/src/Form/Type/ProcessUploadFileType.php b/src/Form/Type/ProcessUploadFileType.php new file mode 100644 index 0000000..cf476c7 --- /dev/null +++ b/src/Form/Type/ProcessUploadFileType.php @@ -0,0 +1,22 @@ +setRequired('process_code'); + } + + public function getParent(): string + { + return FileType::class; + } +} diff --git a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php new file mode 100644 index 0000000..a8c2a89 --- /dev/null +++ b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php @@ -0,0 +1,24 @@ +registry->getProcessConfiguration($request->get('process'))]; + } +} diff --git a/src/Manager/ProcessExecutionManager.php b/src/Manager/ProcessExecutionManager.php new file mode 100644 index 0000000..cc4ab7c --- /dev/null +++ b/src/Manager/ProcessExecutionManager.php @@ -0,0 +1,62 @@ +currentProcessExecution) { + $this->currentProcessExecution = $processExecution; + } + + return $this; + } + + public function getCurrentProcessExecution(): ?ProcessExecution + { + return $this->currentProcessExecution; + } + + public function unsetProcessExecution(string $processCode): self + { + if ($this->currentProcessExecution?->code === $processCode) { + $this->currentProcessExecution = null; + } + + return $this; + } + + public function save(): self + { + if (null !== $this->currentProcessExecution) { + $this->processExecutionRepository->save($this->currentProcessExecution); + } + + return $this; + } + + public function increment(string $incrementKey, int $step = 1): void + { + $this->currentProcessExecution?->addReport( + $incrementKey, + $this->currentProcessExecution->getReport($incrementKey, 0) + $step + ); + } + + public function setReport(string $incrementKey, string $value): void + { + $this->currentProcessExecution?->addReport($incrementKey, $value); + } +} diff --git a/src/Manager/ProcessUiConfigurationManager.php b/src/Manager/ProcessUiConfigurationManager.php deleted file mode 100644 index d852b1e..0000000 --- a/src/Manager/ProcessUiConfigurationManager.php +++ /dev/null @@ -1,97 +0,0 @@ -processConfigurationRegistry = $processConfigurationRegistry; - } - - /** - * @return array - */ - public function getProcessChoices(): array - { - return array_map(static fn (ProcessConfiguration $configuration) => $configuration->getCode(), $this->processConfigurationRegistry->getProcessConfigurations()); - } - - /** - * @return array - */ - public function getSourceChoices(): array - { - $sources = []; - foreach ($this->processConfigurationRegistry->getProcessConfigurations() as $configuration) { - $source = $this->getSource($configuration->getCode()); - $sources[(string) $source] = (string) $source; - } - - return $sources; - } - - /** - * @return array - */ - public function getTargetChoices(): array - { - $targets = []; - foreach ($this->processConfigurationRegistry->getProcessConfigurations() as $configuration) { - $target = $this->getTarget($configuration->getCode()); - $targets[(string) $target] = (string) $target; - } - - return $targets; - } - - public function getSource(Process|string $process): ?string - { - return $this->resolveUiOptions($process)[self::UI_OPTION_SOURCE]; - } - - public function getTarget(Process|string $process): ?string - { - return $this->resolveUiOptions($process)[self::UI_OPTION_TARGET]; - } - - public function canRun(Process|string $process): bool - { - return (bool) $this->resolveUiOptions($process)[self::UI_OPTION_RUN]; - } - - /** - * @return array - */ - private function resolveUiOptions(Process|string $process): array - { - $code = $process instanceof Process ? $process->getProcessCode() : $process; - $resolver = new OptionsResolver(); - - $resolver->setDefaults([ - self::UI_OPTION_SOURCE => null, - self::UI_OPTION_TARGET => null, - self::UI_OPTION_RUN => true, - ]); - $resolver->setAllowedTypes(self::UI_OPTION_RUN, 'bool'); - $resolver->setAllowedTypes(self::UI_OPTION_SOURCE, ['string', 'null']); - $resolver->setAllowedTypes(self::UI_OPTION_TARGET, ['string', 'null']); - - return $resolver->resolve( - $this->processConfigurationRegistry->getProcessConfiguration($code)->getOptions()['ui_options'] ?? [] - ); - } -} diff --git a/src/Message/LogIndexerHandler.php b/src/Message/LogIndexerHandler.php deleted file mode 100644 index deced04..0000000 --- a/src/Message/LogIndexerHandler.php +++ /dev/null @@ -1,62 +0,0 @@ -managerRegistry = $managerRegistry; - } - - public function __invoke(LogIndexerMessage $logIndexerMessage): void - { - /** @var EntityManagerInterface $manager */ - $manager = $this->managerRegistry->getManagerForClass(ProcessExecutionLogRecord::class); - $table = $manager->getClassMetadata(ProcessExecutionLogRecord::class)->getTableName(); - $file = new \SplFileObject($logIndexerMessage->getLogPath()); - $file->seek($logIndexerMessage->getStart()); - $offset = $logIndexerMessage->getOffset(); - $parser = new LineLogParser(); - $parameters = []; - while ($offset > 0 && !$file->eof()) { - /** @var string $currentLine */ - $currentLine = $file->current(); - $parsedLine = $parser->parse($currentLine); - if (!empty($parsedLine) && true === ($parsedLine['context'][self::INDEX_LOG_RECORD] ?? false)) { - $parameters[] = $logIndexerMessage->getProcessExecutionId(); - $parameters[] = Logger::toMonologLevel($parsedLine['level']); - $parameters[] = substr($parsedLine['message'], 0, 255); - } - $file->next(); - --$offset; - } - if (\count($parameters) > 0) { - $statement = $this->getStatement($table, (int) (\count($parameters) / 3)); - $manager->getConnection()->executeStatement($statement, $parameters); - } - } - - private function getStatement(string $table, int $size): string - { - $sql = 'INSERT INTO '.$table.' (process_execution_id, log_level, message) VALUES '; - while ($size > 0) { - $sql .= $size > 1 ? '(?, ?, ?),' : '(?, ?, ?)'; - --$size; - } - - return $sql; - } -} diff --git a/src/Message/LogIndexerMessage.php b/src/Message/LogIndexerMessage.php deleted file mode 100644 index 760b63d..0000000 --- a/src/Message/LogIndexerMessage.php +++ /dev/null @@ -1,46 +0,0 @@ -processExecutionId = $processExecutionId; - $this->logPath = $logPath; - $this->start = $start; - $this->offset = $offset; - } - - public function getProcessExecutionId(): int - { - return $this->processExecutionId; - } - - public function getLogPath(): string - { - return $this->logPath; - } - - public function getStart(): int - { - return $this->start; - } - - public function getOffset(): int - { - return $this->offset; - } -} diff --git a/src/Message/ProcessExecuteHandler.php b/src/Message/ProcessExecuteHandler.php new file mode 100644 index 0000000..fcff027 --- /dev/null +++ b/src/Message/ProcessExecuteHandler.php @@ -0,0 +1,21 @@ +manager->execute($message->code, $message->input); + } +} diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php new file mode 100644 index 0000000..e17b9d6 --- /dev/null +++ b/src/Message/ProcessExecuteMessage.php @@ -0,0 +1,12 @@ +command = $command; - } - - /** - * @throws Exception - */ - public function __invoke(ProcessRunMessage $processRunMessage): void - { - $this->command->run( - new ArrayInput( - [ - 'processCodes' => [$processRunMessage->getProcessCode()], - ] - ), - new NullOutput() - ); - } -} diff --git a/src/Message/ProcessRunMessage.php b/src/Message/ProcessRunMessage.php deleted file mode 100644 index 5b9682a..0000000 --- a/src/Message/ProcessRunMessage.php +++ /dev/null @@ -1,35 +0,0 @@ - */ - private array $processInput; - - /** - * @param array $processInput - */ - public function __construct(string $processCode, array $processInput = []) - { - $this->processCode = $processCode; - $this->processInput = $processInput; - } - - public function getProcessCode(): string - { - return $this->processCode; - } - - /** - * @return array - */ - public function getProcessInput(): array - { - return $this->processInput; - } -} diff --git a/src/Migrations/Version20210903142035.php b/src/Migrations/Version20210903142035.php deleted file mode 100644 index 88e869c..0000000 --- a/src/Migrations/Version20210903142035.php +++ /dev/null @@ -1,107 +0,0 @@ -addSql(<<addSql(<<addSql(<<addSql(<<addSql(<<addSql('ALTER TABLE process_execution ADD process_id INT DEFAULT NULL'); - $this->addSql(<<addSql('CREATE INDEX IDX_98E995D27EC2F574 ON process_execution (process_id)'); - } - - public function down(Schema $schema): void - { - // this down() migration is auto-generated, please modify it to your needs - $this->addSql('DROP TABLE process'); - $this->addSql('DROP TABLE process_execution'); - $this->addSql('DROP TABLE process_execution_log_record'); - $this->addSql('DROP TABLE user'); - } - - public function isTransactional(): bool - { - return false; - } -} diff --git a/src/Migrations/Version20211028081845.php b/src/Migrations/Version20211028081845.php deleted file mode 100644 index 0b2ff9e..0000000 --- a/src/Migrations/Version20211028081845.php +++ /dev/null @@ -1,36 +0,0 @@ -addSql('ALTER TABLE process_execution ADD report JSON DEFAULT NULL'); - } - - public function down(Schema $schema): void - { - // this down() migration is auto-generated, please modify it to your needs - $this->addSql('ALTER TABLE process_execution DROP report'); - } - - public function isTransactional(): bool - { - return false; - } -} diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php new file mode 100644 index 0000000..7a45b2a --- /dev/null +++ b/src/Migrations/Version20231006111525.php @@ -0,0 +1,87 @@ +hasTable('log_record')) { + $this->addSql( + <<addSql('CREATE INDEX IDX_8ECECC333DAC0075 ON log_record (process_execution_id)'); + $this->addSql('CREATE INDEX idx_log_record_level ON log_record (level)'); + $this->addSql('CREATE INDEX idx_log_record_created_at ON log_record (created_at)'); + } + + if (!$schema->hasTable('process_execution')) { + $this->addSql(<<addSql( + <<addSql('CREATE INDEX idx_process_execution_code ON process_execution (code)'); + $this->addSql('CREATE INDEX idx_process_execution_start_date ON process_execution (start_date)'); + } + + if (!$schema->hasTable('process_user')) { + $this->addSql(<<addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); + $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); + } + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE log_record DROP CONSTRAINT FK_8ECECC333DAC0075'); + $this->addSql('DROP TABLE log_record'); + $this->addSql('DROP TABLE process_execution'); + $this->addSql('DROP TABLE process_user'); + } +} diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php new file mode 100644 index 0000000..fee6318 --- /dev/null +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -0,0 +1,77 @@ + */ + private ArrayCollection $records; + private ?ProcessExecutionManager $processExecutionManager; + private ?EntityManagerInterface $em = null; + private bool $enabled = false; + + public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) + { + parent::__construct($level, $bubble); + $this->records = new ArrayCollection(); + } + + #[Required] + public function setEntityManager(EntityManagerInterface $em): void + { + $this->em = $em; + } + + #[Required] + public function setProcessExecutionManager(ProcessExecutionManager $processExecutionManager): void + { + $this->processExecutionManager = $processExecutionManager; + } + + public function setEnabled(bool $flag): void + { + $this->enabled = $flag; + } + + public function __destruct() + { + $this->flush(); + parent::__destruct(); + } + + public function flush(): void + { + foreach ($this->records as $record) { + if ($currentProcessExecution = $this->processExecutionManager->getCurrentProcessExecution()) { + $entity = new \CleverAge\ProcessUiBundle\Entity\LogRecord($record, $currentProcessExecution); + $this->em?->persist($entity); + } + } + $this->em?->flush(); + foreach ($this->records as $record) { + $this->em?->detach($record); + } + $this->records = new ArrayCollection(); + } + + protected function write(LogRecord $record): void + { + if (false === $this->enabled) { + return; + } + $this->records->add($record); + if (500 === $this->records->count()) { + $this->flush(); + } + } +} diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php new file mode 100644 index 0000000..4484148 --- /dev/null +++ b/src/Monolog/Handler/ProcessHandler.php @@ -0,0 +1,54 @@ +directory = $directory; + $this->reportIncrementLevel = Level::Error; + parent::__construct($directory); + } + + public function hasFilename(): bool + { + return $this->directory !== $this->url; + } + + public function setFilename(string $filename): void + { + $this->url = sprintf('%s/%s', $this->directory, $filename); + } + + public function getFilename(): ?string + { + return $this->url; + } + + public function write(LogRecord $record): void + { + parent::write($record); + if ($record->level->value >= $this->reportIncrementLevel->value) { + $this->processExecutionManager->increment($record->level->name); + } + } + + public function setReportIncrementLevel(string $level): void + { + $this->reportIncrementLevel = Level::fromName($level); + } +} diff --git a/src/Monolog/Handler/ProcessLogHandler.php b/src/Monolog/Handler/ProcessLogHandler.php deleted file mode 100644 index 1278e5f..0000000 --- a/src/Monolog/Handler/ProcessLogHandler.php +++ /dev/null @@ -1,66 +0,0 @@ -logDir = $processLogDir; - } - - /** - * @param array $record - * - * @throws FilesystemException - */ - protected function write(array $record): void - { - if (null === $logFilename = ($this->logFilenames[$this->currentProcessCode] ?? null)) { - return; - } - - if ($record['level'] < Logger::INFO) { - return; - } - - if (null === $this->filesystem) { - $this->filesystem = new Filesystem( - new LocalFilesystemAdapter($this->logDir, null, \FILE_APPEND) - ); - } - $this->filesystem->write($logFilename, $record['formatted']); - } - - public function setLogFilename(string $logFilename, string $processCode): void - { - $this->logFilenames[$processCode] = $logFilename; - } - - public function setCurrentProcessCode(?string $code): void - { - $this->currentProcessCode = $code; - } - - public function getLogFilename(): ?string - { - return $this->logFilenames[$this->currentProcessCode] ?? null; - } -} diff --git a/src/Repository/.gitignore b/src/Repository/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index 9294fa7..b761ff7 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -10,6 +10,11 @@ /** * @extends ServiceEntityRepository + * + * @method ProcessExecution|null find($id, $lockMode = null, $lockVersion = null) + * @method ProcessExecution|null findOneBy(array $criteria, array $orderBy = null) + * @method ProcessExecution[] findAll() + * @method ProcessExecution[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class ProcessExecutionRepository extends ServiceEntityRepository { @@ -18,61 +23,22 @@ public function __construct(ManagerRegistry $registry) parent::__construct($registry, ProcessExecution::class); } - /** - * @return array - */ - public function getProcessCodeChoices(): array + public function save(ProcessExecution $processExecution): void { - $choices = []; - $qb = $this->createQueryBuilder('pe'); - $qb->distinct(true); - $qb->select('pe.processCode'); - foreach ($qb->getQuery()->getArrayResult() as $result) { - $choices[(string) $result['processCode']] = (string) $result['processCode']; - } - - return $choices; - } - - /** - * @return array - */ - public function getSourceChoices(): array - { - $choices = []; - $qb = $this->createQueryBuilder('pe'); - $qb->distinct(true); - $qb->select('pe.source'); - foreach ($qb->getQuery()->getArrayResult() as $result) { - $choices[(string) $result['source']] = (string) $result['source']; - } - - return $choices; + $this->_em->persist($processExecution); + $this->_em->flush(); } - /** - * @return array - */ - public function getTargetChoices(): array + public function getLastProcessExecution(string $code): ?ProcessExecution { - $choices = []; - $qb = $this->createQueryBuilder('pe'); - $qb->distinct(true); - $qb->select('pe.target'); - foreach ($qb->getQuery()->getArrayResult() as $result) { - $choices[(string) $result['target']] = (string) $result['target']; - } - - return $choices; - } - - public function deleteBefore(\DateTime $dateTime): void - { - $qb = $this->createQueryBuilder('pe'); - $qb->delete(); - $qb->where('pe.startDate < :date'); - $qb->setParameter('date', $dateTime); - - $qb->getQuery()->execute(); + $qb = $this->_em->createQueryBuilder(); + + return $qb->select('pe') + ->from(ProcessExecution::class, 'pe') + ->where($qb->expr()->eq('pe.code', $qb->expr()->literal($code))) + ->orderBy('pe.startDate', 'DESC') + ->setMaxResults(1) + ->getQuery() + ->getOneOrNullResult(); } } diff --git a/src/Repository/ProcessRepository.php b/src/Repository/ProcessRepository.php deleted file mode 100644 index 71140df..0000000 --- a/src/Repository/ProcessRepository.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -class ProcessRepository extends ServiceEntityRepository -{ - private ProcessUiConfigurationManager $processUiConfigurationManager; - private ProcessConfigurationRegistry $processConfigurationRegistry; - - /** - * @required - */ - public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void - { - $this->processUiConfigurationManager = $processUiConfigurationManager; - } - - /** - * @required - */ - public function setProcessConfigurationRegistry(ProcessConfigurationRegistry $processConfigurationRegistry): void - { - $this->processConfigurationRegistry = $processConfigurationRegistry; - } - - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, Process::class); - } - - public function sync(): void - { - // Create missing process into database - $codes = []; - foreach ($this->processConfigurationRegistry->getProcessConfigurations() as $configuration) { - $process = $this->findOneBy(['processCode' => $configuration->getCode()]); - $codes[] = $configuration->getCode(); - if (null === $process) { - $process = new Process( - $configuration->getCode(), - $this->processUiConfigurationManager->getSource($configuration->getCode()), - $this->processUiConfigurationManager->getTarget($configuration->getCode()), - ); - $this->getEntityManager()->persist($process); - } - } - $this->getEntityManager()->flush(); - - // Delete process in database if not into configuration registry - $qb = $this->createQueryBuilder('p'); - $qb->delete(); - $qb->where($qb->expr()->notIn('p.processCode', $codes)); - $qb->getQuery()->execute(); - } -} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php deleted file mode 100644 index e03ffa9..0000000 --- a/src/Repository/UserRepository.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, User::class); - } - - /** - * Used to upgrade (rehash) the user's password automatically over time. - */ - public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newEncodedPassword): void - { - if (!$user instanceof User) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); - } - - $user->setPassword($newEncodedPassword); - $this->_em->persist($user); - $this->_em->flush(); - } -} diff --git a/src/Security/LoginFormAuthAuthenticator.php b/src/Security/LoginFormAuthAuthenticator.php deleted file mode 100644 index fc08421..0000000 --- a/src/Security/LoginFormAuthAuthenticator.php +++ /dev/null @@ -1,62 +0,0 @@ -urlGenerator = $urlGenerator; - } - - public function authenticate(Request $request): PassportInterface - { - $username = (string) $request->request->get('email', ''); - - $request->getSession()->set(Security::LAST_USERNAME, $username); - - return new Passport( - new UserBadge($username), - new PasswordCredentials((string) $request->request->get('password', '')), - [ - new CsrfTokenBadge('authenticate', $request->get('_csrf_token')), - ] - ); - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response - { - if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) { - return new RedirectResponse($targetPath); - } - - return new RedirectResponse($this->urlGenerator->generate('process_admin')); - } - - protected function getLoginUrl(Request $request): string - { - return $this->urlGenerator->generate(self::LOGIN_ROUTE); - } -} diff --git a/src/Twig/Extension/LogLevelExtension.php b/src/Twig/Extension/LogLevelExtension.php new file mode 100644 index 0000000..2c93258 --- /dev/null +++ b/src/Twig/Extension/LogLevelExtension.php @@ -0,0 +1,20 @@ +getName(); + } + + public function getCssClass(string|int $value): string + { + return is_int($value) ? + match ($value) { + Level::Warning->value => 'warning', + Level::Error->value, Level::Emergency->value, Level::Critical->value, Level::Alert->value => 'danger', + Level::Debug->value, Level::Info->value => 'success', + default => '' + } + : match ($value) { + Level::Warning->name => 'warning', + Level::Error->name, Level::Emergency->name, Level::Critical->name, Level::Alert->name => 'danger', + Level::Debug->name, Level::Info->name => 'success', + default => '' + }; + } +} diff --git a/src/Twig/Runtime/MD5ExtensionRuntime.php b/src/Twig/Runtime/MD5ExtensionRuntime.php new file mode 100644 index 0000000..40bd3f1 --- /dev/null +++ b/src/Twig/Runtime/MD5ExtensionRuntime.php @@ -0,0 +1,15 @@ +processExecutionRepository->getLastProcessExecution($code); + } + + public function getProcessSource(string $code): ?string + { + return $this->processConfigurationRegistry + ->getProcessConfiguration($code)?->getOptions()['ui']['source'] ?? null; + } + + public function getProcessTarget(string $code): ?string + { + return $this->processConfigurationRegistry + ->getProcessConfiguration($code)?->getOptions()['ui']['target'] ?? null; + } +} diff --git a/templates/admin/field/array.html.twig b/templates/admin/field/array.html.twig new file mode 100644 index 0000000..8cdf10d --- /dev/null +++ b/templates/admin/field/array.html.twig @@ -0,0 +1,16 @@ +{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #} +{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #} +{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #} +
    + {{ _self.render(field.value) }} +
+ +{% macro render(value) %} + {% for key, item in value %} + {% if item is iterable %} +
  • {{ key }}
    • {{ _self.render(item) }}
    + {% else %} +
  • {{ key }} : {{ item }}
  • + {% endif %} + {% endfor %} +{% endmacro %} diff --git a/templates/admin/field/enum.html.twig b/templates/admin/field/enum.html.twig new file mode 100644 index 0000000..e615276 --- /dev/null +++ b/templates/admin/field/enum.html.twig @@ -0,0 +1,2 @@ +{% set class = field.value.value == 'failed' ? 'danger' : 'success' %} +{{ field.value.value }} diff --git a/templates/admin/field/log_level.html.twig b/templates/admin/field/log_level.html.twig new file mode 100644 index 0000000..2a666ad --- /dev/null +++ b/templates/admin/field/log_level.html.twig @@ -0,0 +1 @@ +{{ log_label(field.value) }} diff --git a/templates/admin/field/process_source.html.twig b/templates/admin/field/process_source.html.twig new file mode 100644 index 0000000..fea3203 --- /dev/null +++ b/templates/admin/field/process_source.html.twig @@ -0,0 +1 @@ +{{ get_process_source(entity.instance.code) }} diff --git a/templates/admin/field/process_target.html.twig b/templates/admin/field/process_target.html.twig new file mode 100644 index 0000000..15470e6 --- /dev/null +++ b/templates/admin/field/process_target.html.twig @@ -0,0 +1 @@ +{{ get_process_target(entity.instance.code) }} diff --git a/templates/admin/field/report.html.twig b/templates/admin/field/report.html.twig new file mode 100644 index 0000000..c24b268 --- /dev/null +++ b/templates/admin/field/report.html.twig @@ -0,0 +1,8 @@ +{# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #} +{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #} +{# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #} +
      + {% for key, item in field.value %} +
    • {{ key }} : {{ item }}
    • + {% endfor %} +
    diff --git a/templates/admin/login.html.twig b/templates/admin/login.html.twig new file mode 100644 index 0000000..1d1d077 --- /dev/null +++ b/templates/admin/login.html.twig @@ -0,0 +1 @@ +{% extends '@EasyAdmin/page/login.html.twig' %} diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig new file mode 100644 index 0000000..514cd4f --- /dev/null +++ b/templates/admin/process/list.html.twig @@ -0,0 +1,104 @@ +{# @var urlGenerator \EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator #} +{% extends ea.templatePath('layout') %} +{% trans_default_domain ea.i18n.translationDomain %} + +{% block main %} + + + {% block table_head %} + + + + + + + + + {% endblock %} + + + {% block table_body %} + {# @var process \CleverAge\ProcessBundle\Configuration\ProcessConfiguration #} + {% for process in processes %} + {% set lastExecution = get_last_execution_date(process.code) %} + {% set statusClass = '' %} + {% if lastExecution is not null %} + {% set statusClass = lastExecution.status.value == 'failed' ? 'danger' : 'success' %} + {% endif %} + + + + + + + + + {% endfor %} + {% endblock %} + +
    Process codeLast executionStatusSourceTargetActions
    {{ process.code }}{% if lastExecution is not null %}{{ lastExecution.startDate|date('Y/m/d H:i:s') }}{% endif %}{% if lastExecution is not null %}{{ lastExecution.status.value }}{% endif %}{% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %}{% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} + {% if process.options.ui.upload_and_run is defined and true == process.options.ui.upload_and_run %} + + + + {% endif %} + {% if process.options.ui.run is defined and true == process.options.ui.run %} + + + + {% endif %} + + + +
    + {% for process in processes %} + + + + {% endfor %} +{% endblock %} diff --git a/templates/admin/process/upload_and_execute.html.twig b/templates/admin/process/upload_and_execute.html.twig new file mode 100644 index 0000000..53160fc --- /dev/null +++ b/templates/admin/process/upload_and_execute.html.twig @@ -0,0 +1,23 @@ +{% extends ea.templatePath('layout') %} +{% trans_default_domain ea.i18n.translationDomain %} + +{% block main %} +
    +
    +
    + {{ 'Upload you file then click on button to run process in background' }} +
    +
    +
    +
    + {{ form_start(form) }} + {{ form_widget(form) }} +
    + +
    + {{ form_end(form) }} +
    +
    +
    + +{% endblock %} From 56b0e8d91e905ea94034be1574e2ba32da8a4047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Fri, 6 Oct 2023 15:23:43 +0200 Subject: [PATCH 002/115] Add dependency to symfony/runtime --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 157e049..fc0c2c2 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "symfony/uid": "^6.3", "symfony/string": "^6.3", "symfony/messenger": "^6.3", + "symfony/runtime": "^6.3", "symfony/doctrine-messenger": "^6.3", "easycorp/easyadmin-bundle": "^4.7" }, From d7bb55bf402b7d10c65686ffec09b1c60787f867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Fri, 6 Oct 2023 17:14:57 +0200 Subject: [PATCH 003/115] Add migration for mysql, postresql & sqlite --- src/Migrations/Version20231006111525.php | 115 ++++++++++++----------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php index 7a45b2a..3fe032f 100644 --- a/src/Migrations/Version20231006111525.php +++ b/src/Migrations/Version20231006111525.php @@ -16,64 +16,71 @@ public function getDescription(): string public function up(Schema $schema): void { - // this up() migration is auto-generated, please modify it to your needs - if (!$schema->hasTable('log_record')) { - $this->addSql( - <<addSql('CREATE INDEX IDX_8ECECC333DAC0075 ON log_record (process_execution_id)'); - $this->addSql('CREATE INDEX idx_log_record_level ON log_record (level)'); - $this->addSql('CREATE INDEX idx_log_record_created_at ON log_record (created_at)'); + $platform = $this->connection->getDatabasePlatform()->getName(); + if ("sqlite" === $platform) { + if (!$schema->hasTable('log_record')) { + $this->addSql('CREATE TABLE log_record (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, process_execution_id INTEGER DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INTEGER NOT NULL, message VARCHAR(512) NOT NULL, context CLOB NOT NULL --(DC2Type:json) + , created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , CONSTRAINT FK_8ECECC333DAC0075 FOREIGN KEY (process_execution_id) REFERENCES process_execution (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('CREATE INDEX IDX_8ECECC333DAC0075 ON log_record (process_execution_id)'); + $this->addSql('CREATE INDEX idx_log_record_level ON log_record (level)'); + $this->addSql('CREATE INDEX idx_log_record_created_at ON log_record (created_at)'); + } + if (!$schema->hasTable('process_execution')) { + $this->addSql('CREATE TABLE process_execution (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, code VARCHAR(255) NOT NULL, log_filename VARCHAR(255) NOT NULL, start_date DATETIME NOT NULL --(DC2Type:datetime_immutable) + , end_date DATETIME DEFAULT NULL --(DC2Type:datetime_immutable) + , status VARCHAR(255) NOT NULL, report CLOB NOT NULL --(DC2Type:json) + )'); + $this->addSql('CREATE INDEX idx_process_execution_code ON process_execution (code)'); + $this->addSql('CREATE INDEX idx_process_execution_start_date ON process_execution (start_date)'); + } + if (!$schema->hasTable('process_user')) { + $this->addSql('CREATE TABLE process_user (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, email VARCHAR(255) NOT NULL, firstname VARCHAR(255) DEFAULT NULL, lastname VARCHAR(255) DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:json) + , password VARCHAR(255) DEFAULT NULL)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); + $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); + } } - if (!$schema->hasTable('process_execution')) { - $this->addSql(<<addSql( - <<addSql('CREATE INDEX idx_process_execution_code ON process_execution (code)'); - $this->addSql('CREATE INDEX idx_process_execution_start_date ON process_execution (start_date)'); + if ("mysql" === $platform) { + if (!$schema->hasTable('log_record')) { + $this->addSql('CREATE TABLE log_record (id INT AUTO_INCREMENT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL COMMENT \'(DC2Type:json)\', created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_8ECECC333DAC0075 (process_execution_id), INDEX idx_log_record_level (level), INDEX idx_log_record_created_at (created_at), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + } + if (!$schema->hasTable('process_execution')) { + $this->addSql('CREATE TABLE process_execution (id INT AUTO_INCREMENT NOT NULL, code VARCHAR(255) NOT NULL, log_filename VARCHAR(255) NOT NULL, start_date DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', end_date DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', status VARCHAR(255) NOT NULL, report JSON NOT NULL COMMENT \'(DC2Type:json)\', INDEX idx_process_execution_code (code), INDEX idx_process_execution_start_date (start_date), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE log_record ADD CONSTRAINT FK_8ECECC333DAC0075 FOREIGN KEY (process_execution_id) REFERENCES process_execution (id) ON DELETE CASCADE'); + } + if (!$schema->hasTable('process_user')) { + $this->addSql('CREATE TABLE process_user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(255) NOT NULL, firstname VARCHAR(255) DEFAULT NULL, lastname VARCHAR(255) DEFAULT NULL, roles JSON NOT NULL COMMENT \'(DC2Type:json)\', password VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_627A047CE7927C74 (email), INDEX idx_process_user_email (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + } } - if (!$schema->hasTable('process_user')) { - $this->addSql(<<addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); - $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); + if ("postgresql" === $platform) { + if (!$schema->hasTable('log_record')) { + $this->addSql('CREATE SEQUENCE log_record_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE log_record (id INT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_8ECECC333DAC0075 ON log_record (process_execution_id)'); + $this->addSql('CREATE INDEX idx_log_record_level ON log_record (level)'); + $this->addSql('CREATE INDEX idx_log_record_created_at ON log_record (created_at)'); + $this->addSql('COMMENT ON COLUMN log_record.created_at IS \'(DC2Type:datetime_immutable)\''); + } + if (!$schema->hasTable('process_execution')) { + $this->addSql('CREATE SEQUENCE process_execution_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE process_execution (id INT NOT NULL, code VARCHAR(255) NOT NULL, log_filename VARCHAR(255) NOT NULL, start_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, end_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, status VARCHAR(255) NOT NULL, report JSON NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX idx_process_execution_code ON process_execution (code)'); + $this->addSql('CREATE INDEX idx_process_execution_start_date ON process_execution (start_date)'); + $this->addSql('COMMENT ON COLUMN process_execution.start_date IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN process_execution.end_date IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE log_record ADD CONSTRAINT FK_8ECECC333DAC0075 FOREIGN KEY (process_execution_id) REFERENCES process_execution (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + if (!$schema->hasTable('process_user')) { + $this->addSql('CREATE SEQUENCE process_user_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE process_user (id INT NOT NULL, email VARCHAR(255) NOT NULL, firstname VARCHAR(255) DEFAULT NULL, lastname VARCHAR(255) DEFAULT NULL, roles JSON NOT NULL, password VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); + $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); + } + + } } From 0b945b9289d02b6d0a806dcff35b69f6bc1a67dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Mon, 9 Oct 2023 09:41:48 +0200 Subject: [PATCH 004/115] Lint twig templates --- composer.json | 3 +++ templates/admin/process/list.html.twig | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index fc0c2c2..c418223 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,9 @@ "symfony/doctrine-messenger": "^6.3", "easycorp/easyadmin-bundle": "^4.7" }, + "require-dev": { + "vincentlanglet/twig-cs-fixer": "1.4.0" + }, "config": { "optimize-autoloader": true, "preferred-install": { diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 514cd4f..5682e7b 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} {% if process.options.ui.upload_and_run is defined and true == process.options.ui.upload_and_run %} - + {% endif %} From 4b22326a3216e61228813b0ce876adc70caecaac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 16:13:15 +0000 Subject: [PATCH 005/115] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/php.yml | 2 +- .github/workflows/super-linter.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index da34859..8231bcc 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -10,7 +10,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Validate composer.json and composer.lock run: composer validate --strict - name: Cache Composer packages diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 2f75c6f..c8b12a9 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -11,7 +11,7 @@ jobs: name: PHP-CS-Fixer runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # see https://github.com/OskarStark/php-cs-fixer-ga - name: PHP-CS-Fixer uses: docker://oskarstark/php-cs-fixer-ga From 9db1f591b2233fbb9dd5c2d36f529d5d08217951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Wed, 13 Dec 2023 16:20:13 +0100 Subject: [PATCH 006/115] [Update symfony & easy admin] --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index c418223..ec1fd81 100644 --- a/composer.json +++ b/composer.json @@ -23,13 +23,13 @@ "cleverage/process-bundle": "dev-v4-dev", "symfony/flex": "^2", "symfony/orm-pack": "^v2.4", - "symfony/dotenv": "^6.3", - "symfony/uid": "^6.3", - "symfony/string": "^6.3", - "symfony/messenger": "^6.3", - "symfony/runtime": "^6.3", - "symfony/doctrine-messenger": "^6.3", - "easycorp/easyadmin-bundle": "^4.7" + "symfony/dotenv": "^6.4", + "symfony/uid": "^6.4", + "symfony/string": "^6.4", + "symfony/messenger": "^6.4", + "symfony/runtime": "^6.4", + "symfony/doctrine-messenger": "^6.4", + "easycorp/easyadmin-bundle": "^4.8" }, "require-dev": { "vincentlanglet/twig-cs-fixer": "1.4.0" From 0adf9a767b314bd1c2829fa3595d4db9de9023b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Mon, 18 Mar 2024 13:25:54 +0100 Subject: [PATCH 007/115] [Fix] When multiple messages in queue log filename must be reset before new run --- src/EventSubscriber/ProcessEventSubscriber.php | 2 ++ src/Monolog/Handler/ProcessHandler.php | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index 9ededc7..783e51f 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -41,6 +41,7 @@ public function success(ProcessEvent $event): void $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Finish); $this->processExecutionManager->getCurrentProcessExecution()?->end(); $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); + $this->processHandler->close(); } public function fail(ProcessEvent $event): void @@ -48,6 +49,7 @@ public function fail(ProcessEvent $event): void $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Failed); $this->processExecutionManager->getCurrentProcessExecution()?->end(); $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); + $this->processHandler->close(); } public function flushDoctrineLogs(ProcessEvent $event): void diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php index 4484148..97115ea 100644 --- a/src/Monolog/Handler/ProcessHandler.php +++ b/src/Monolog/Handler/ProcessHandler.php @@ -34,6 +34,12 @@ public function setFilename(string $filename): void $this->url = sprintf('%s/%s', $this->directory, $filename); } + public function close(): void + { + $this->url = $this->directory; + parent::close(); + } + public function getFilename(): ?string { return $this->url; From a42bb492a6d6697110d515f984343912ebd78b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Tonon?= Date: Mon, 18 Mar 2024 13:26:25 +0100 Subject: [PATCH 008/115] Add context when run process async --- src/Message/ProcessExecuteHandler.php | 2 +- src/Message/ProcessExecuteMessage.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Message/ProcessExecuteHandler.php b/src/Message/ProcessExecuteHandler.php index fcff027..979c8f2 100644 --- a/src/Message/ProcessExecuteHandler.php +++ b/src/Message/ProcessExecuteHandler.php @@ -16,6 +16,6 @@ public function __construct(private ProcessManager $manager) public function __invoke(ProcessExecuteMessage $message): void { - $this->manager->execute($message->code, $message->input); + $this->manager->execute($message->code, $message->input, $message->context); } } diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php index e17b9d6..a64e633 100644 --- a/src/Message/ProcessExecuteMessage.php +++ b/src/Message/ProcessExecuteMessage.php @@ -6,7 +6,7 @@ readonly class ProcessExecuteMessage { - public function __construct(public string $code, public mixed $input) + public function __construct(public string $code, public mixed $input, public array $context = []) { } } From f2f771a2df0066e4e353c8ba6017abb9c142a7e1 Mon Sep 17 00:00:00 2001 From: Xavier Marchegay Date: Tue, 23 Jul 2024 13:23:27 +0200 Subject: [PATCH 009/115] Update ProcessExecutionStatus.php finish -> completed --- src/Entity/Enum/ProcessExecutionStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Enum/ProcessExecutionStatus.php b/src/Entity/Enum/ProcessExecutionStatus.php index 1950783..837a9dc 100644 --- a/src/Entity/Enum/ProcessExecutionStatus.php +++ b/src/Entity/Enum/ProcessExecutionStatus.php @@ -7,6 +7,6 @@ enum ProcessExecutionStatus: string { case Started = 'started'; - case Finish = 'finish'; + case Finish = 'completed'; case Failed = 'failed'; } From 7594fdad4e7698bbcd917c091ee7449262c1e73b Mon Sep 17 00:00:00 2001 From: Xavier Marchegay Date: Tue, 23 Jul 2024 13:26:11 +0200 Subject: [PATCH 010/115] Update ProcessExecutionStatus.php --- src/Entity/Enum/ProcessExecutionStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Enum/ProcessExecutionStatus.php b/src/Entity/Enum/ProcessExecutionStatus.php index 837a9dc..1950783 100644 --- a/src/Entity/Enum/ProcessExecutionStatus.php +++ b/src/Entity/Enum/ProcessExecutionStatus.php @@ -7,6 +7,6 @@ enum ProcessExecutionStatus: string { case Started = 'started'; - case Finish = 'completed'; + case Finish = 'finish'; case Failed = 'failed'; } From 6c2bf373454801032523497231d83b0258c25903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 30 Jul 2024 15:32:32 +0200 Subject: [PATCH 011/115] Only display public process (list, execution & logs) --- .../Admin/LogRecordCrudController.php | 27 ++++++++++++++++ src/Controller/Admin/Process/ListAction.php | 6 ++-- .../Admin/ProcessExecutionCrudController.php | 23 +++++++++++++ src/Manager/ProcessConfigurationsManager.php | 32 +++++++++++++++++++ 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/Manager/ProcessConfigurationsManager.php diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 5cc7f1a..0fce4b0 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -4,13 +4,20 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Admin\Field\LogLevelField; use CleverAge\ProcessUiBundle\Entity\LogRecord; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use Doctrine\ORM\QueryBuilder; +use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; +use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; +use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; +use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; @@ -22,6 +29,11 @@ #[IsGranted('ROLE_USER')] class LogRecordCrudController extends AbstractCrudController { + + public function __construct(private readonly ProcessConfigurationsManager $processConfigurationsManager) + { + } + public static function getEntityFqcn(): string { return LogRecord::class; @@ -70,4 +82,19 @@ public function configureFilters(Filters $filters): Filters ) ->add('createdAt'); } + + public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder + { + $queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); + $queryBuilder->join($queryBuilder->getRootAliases()[0].'.processExecution', 'pe'); + $codes = array_map( + fn(ProcessConfiguration $configuration) => $configuration->getCode(), + $this->processConfigurationsManager->getPublicProcesses() + ); + $queryBuilder->where($queryBuilder->expr()->in('pe.code', ':codes')); + $queryBuilder->setParameter('codes', $codes); + + return $queryBuilder; + + } } diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php index 3c1cf4c..26726b1 100644 --- a/src/Controller/Admin/Process/ListAction.php +++ b/src/Controller/Admin/Process/ListAction.php @@ -4,7 +4,7 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; -use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -14,12 +14,12 @@ #[IsGranted('ROLE_USER')] class ListAction extends AbstractController { - public function __invoke(ProcessConfigurationRegistry $registry): Response + public function __invoke(ProcessConfigurationsManager $processConfigurationsManager): Response { return $this->render( '@CleverAgeProcessUi/admin/process/list.html.twig', [ - 'processes' => $registry->getProcessConfigurations(), + 'processes' => $processConfigurationsManager->getPublicProcesses() ] ); } diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index 246cf0d..40300a3 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -4,14 +4,21 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Admin\Field\EnumField; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use Doctrine\ORM\QueryBuilder; +use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; +use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; +use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; +use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; @@ -25,6 +32,9 @@ #[IsGranted('ROLE_USER')] class ProcessExecutionCrudController extends AbstractCrudController { + public function __construct(private readonly ProcessConfigurationsManager $processConfigurationsManager) + { + } public static function getEntityFqcn(): string { return ProcessExecution::class; @@ -128,4 +138,17 @@ public function configureFilters(Filters $filters): Filters { return $filters->add('code')->add('startDate'); } + + public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder + { + $codes = array_map( + fn(ProcessConfiguration $configuration) => $configuration->getCode(), + $this->processConfigurationsManager->getPublicProcesses() + ); + $queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); + $queryBuilder->where($queryBuilder->expr()->in($queryBuilder->getRootAliases()[0] . '.code', ':codes')); + $queryBuilder->setParameter('codes', $codes); + + return $queryBuilder; + } } diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php new file mode 100644 index 0000000..eed55c0 --- /dev/null +++ b/src/Manager/ProcessConfigurationsManager.php @@ -0,0 +1,32 @@ +getConfigurations(), fn(ProcessConfiguration $cfg) => $cfg->isPublic()); + } + + /** @return ProcessConfiguration[] */ + public function getPrivateProcesses(): array + { + return array_filter($this->getConfigurations(), fn(ProcessConfiguration $cfg) => !$cfg->isPublic()); + } + + /** @return ProcessConfiguration[] */ + private function getConfigurations(): array + { + return $this->registry->getProcessConfigurations(); + } +} From c3ba778edb931eff840df34d707fbf94cc58371a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 31 Jul 2024 16:53:45 +0200 Subject: [PATCH 012/115] Add scheduler configuration from UI --- README.md | 79 ++++++++++- .../Admin/ProcessDashboardController.php | 2 + .../Admin/ProcessScheduleCrudController.php | 124 ++++++++++++++++++ src/Entity/ProcessSchedule.php | 116 ++++++++++++++++ src/Form/Type/ProcessContextType.php | 39 ++++++ src/Message/CronProcessMessage.php | 14 ++ src/Message/CronProcessMessageHandler.php | 24 ++++ src/Migrations/Version20240729151928.php | 43 ++++++ src/Repository/ProcessScheduleRepository.php | 25 ++++ src/Scheduler/CronScheduler.php | 61 +++++++++ src/Validator/CronExpression.php | 13 ++ src/Validator/CronExpressionValidator.php | 23 ++++ src/Validator/EveryExpression.php | 13 ++ src/Validator/EveryExpressionValidator.php | 24 ++++ src/Validator/IsValidProcessCode.php | 14 ++ src/Validator/IsValidProcessCodeValidator.php | 36 +++++ 16 files changed, 644 insertions(+), 6 deletions(-) create mode 100644 src/Controller/Admin/ProcessScheduleCrudController.php create mode 100644 src/Entity/ProcessSchedule.php create mode 100644 src/Form/Type/ProcessContextType.php create mode 100644 src/Message/CronProcessMessage.php create mode 100644 src/Message/CronProcessMessageHandler.php create mode 100644 src/Migrations/Version20240729151928.php create mode 100644 src/Repository/ProcessScheduleRepository.php create mode 100644 src/Scheduler/CronScheduler.php create mode 100644 src/Validator/CronExpression.php create mode 100644 src/Validator/CronExpressionValidator.php create mode 100644 src/Validator/EveryExpression.php create mode 100644 src/Validator/EveryExpressionValidator.php create mode 100644 src/Validator/IsValidProcessCode.php create mode 100644 src/Validator/IsValidProcessCodeValidator.php diff --git a/README.md b/README.md index 7b2ff6a..b8ef7cb 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,84 @@ ![Code Style](https://github.com/cleverage/processuibundle/actions/workflows/super-linter.yml/badge.svg) ![Composer](https://github.com/cleverage/processuibundle/actions/workflows/php.yml/badge.svg) + ## CleverAge/ProcessUIBundle A simple UX for cleverage/processbundle using EasyAdmin **Installation** * Import routes -```yaml -#config/routes.yaml -processui: - resource: '@CleverAgeProcessUiBundle/src/Controller' - type: attribute -``` +```yaml +#config/routes.yaml +processui: + resource: '@CleverAgeProcessUiBundle/src/Controller' type: attribute +``` * Run doctrine migration * Create an user using cleverage:process-ui:user-create console. Now you can access Process UI via http://your-domain.com/process + +# Features +### Scheduler +You can schedule process execution via UI using cron expression (*/5 * * * *) or periodical triggers (5 seconds) +For more details about cron expression and peridical triggers visit https://symfony.com/doc/6.4/scheduler.html#cron-expression-triggers and https://symfony.com/doc/6.4/scheduler.html#periodical-triggers + +In order to make sheduler process working be sure the following command is running +``` +bin/console messenger:consume scheduler_cron +``` +See more details about ***messenger:consume*** command in consume message section + +# Consume Messages +Symfony messenger is used in order to run process via UI or schedule process + +*To consume process launched via UI make sure the following command is running* +``` +bin/console messenger:consume execute_process +``` + +*To consume scheduled process make sure the following command is running* +``` +bin/console messenger:consume scheduler_cron +``` +You can pass some options to messenger:consume command +``` +Options: + -l, --limit=LIMIT Limit the number of received messages + -f, --failure-limit=FAILURE-LIMIT The number of failed messages the worker can consume + -m, --memory-limit=MEMORY-LIMIT The memory limit the worker can consume + -t, --time-limit=TIME-LIMIT The time limit in seconds the worker can handle new messages + --sleep=SLEEP Seconds to sleep before asking for new messages after no messages were found [default: 1] + -b, --bus=BUS Name of the bus to which received messages should be dispatched (if not passed, bus is determined automatically) + --queues=QUEUES Limit receivers to only consume from the specified queues (multiple values allowed) + --no-reset Do not reset container services after each message +``` + +It's recommended to use supervisor app or equivalent to keep command alive + +***Sample supervisor configuration*** +``` +[program:scheduler] +command=php /var/www/html/bin/console messenger:consume scheduler_cron +autostart=false +autorestart=true +startretries=1 +startsecs=1 +redirect_stderr=true +stderr_logfile=/var/log/supervisor.scheduler-err.log +stdout_logfile=/var/log/supervisor.scheduler-out.log +user=www-data +killasgroup=true +stopasgroup=true + +[program:process] +command=php /var/www/html/bin/console messenger:consume execute_process +autostart=false +autorestart=true +startretries=1 +startsecs=1 +redirect_stderr=true +stderr_logfile=/var/log/supervisor.process-err.log +stdout_logfile=/var/log/supervisor.process-out.log +user=www-data +killasgroup=true +stopasgroup=true +``` \ No newline at end of file diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index a0a323c..bd6edd8 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -6,6 +6,7 @@ use CleverAge\ProcessUiBundle\Entity\LogRecord; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; +use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; use CleverAge\ProcessUiBundle\Entity\User; use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard; use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem; @@ -44,6 +45,7 @@ public function configureMenuItems(): iterable MenuItem::linkToRoute('Process list', 'fas fa-list', 'process_list'), MenuItem::linkToCrud('Executions', 'fas fa-rocket', ProcessExecution::class), MenuItem::linkToCrud('Logs', 'fas fa-pen', LogRecord::class), + MenuItem::linkToCrud('Scheduler', 'fas fa-solid fa-clock', ProcessSchedule::class), ] ); if ($this->isGranted('ROLE_ADMIN')) { diff --git a/src/Controller/Admin/ProcessScheduleCrudController.php b/src/Controller/Admin/ProcessScheduleCrudController.php new file mode 100644 index 0000000..7193165 --- /dev/null +++ b/src/Controller/Admin/ProcessScheduleCrudController.php @@ -0,0 +1,124 @@ +setPageTitle('index', 'Scheduler') + ->showEntityActionsInlined(); + } + + public function configureActions(Actions $actions): Actions + { + return $actions + ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { + return $action->setIcon('fa fa-plus') + ->setLabel(false) + ->addCssClass(''); + })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { + return $action->setIcon('fa fa-edit') + ->setLabel(false) + ->addCssClass('text-warning'); + })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { + return $action->setIcon('fa fa-trash-o') + ->setLabel(false) + ->addCssClass(''); + })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { + return $action->setLabel('Delete') + ->addCssClass(''); + }); + } + + public static function getEntityFqcn(): string + { + return ProcessSchedule::class; + } + + public function configureFields(string $pageName): iterable + { + + $choices = array_map(function(ProcessConfiguration $configuration) { + return [$configuration->getCode()]; + }, $this->processConfigurationsManager->getPublicProcesses()); + return [ + FormField::addTab('General'), + TextField::new('process') + ->setFormType(ChoiceType::class) + ->setFormTypeOption('choices', array_combine(array_keys($choices), array_keys($choices))), + EnumField::new('type') + ->setFormType(EnumType::class) + ->setFormTypeOption('class', ProcessScheduleType::class), + TextField::new('expression'), + DateTimeField::new('nextExecution') + ->setFormTypeOption('mapped', false) + ->setVirtual(true) + ->hideOnForm() + ->hideOnDetail() + ->formatValue(function ($value, ProcessSchedule $entity) { + return ProcessScheduleType::CRON === $entity->getType() + ? CronExpressionTrigger::fromSpec($entity->getExpression())->getNextRunDate(new \DateTimeImmutable())->format('c') + : null; + }), + FormField::addTab('Input'), + TextField::new('input'), + FormField::addTab('Context'), + ArrayField::new('context') + ->setFormTypeOption('entry_type', ProcessContextType::class) + ->hideOnIndex() + ->setFormTypeOption('entry_options.label', 'Context (key/value)') + ->setFormTypeOption('label', '') + ->setFormTypeOption('required', false) + ]; + } + + public function index(AdminContext $context): KeyValueStore|RedirectResponse|Response + { + if (false === $this->schedulerIsRunning()) { + $this->addFlash('warning', 'To run scheduler, ensure "bin/console messenger:consume scheduler_cron" console is alive. See https://symfony.com/doc/current/messenger.html#supervisor-configuration.'); + } + + return parent::index($context); + } + + private function schedulerIsRunning(): bool + { + + $process = Process::fromShellCommandline('ps -faux'); + $process->run(); + $out = $process->getOutput(); + + return str_contains($out, 'scheduler_cron'); + } +} diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php new file mode 100644 index 0000000..8a26e88 --- /dev/null +++ b/src/Entity/ProcessSchedule.php @@ -0,0 +1,116 @@ +id; + } + + public function getProcess(): ?string + { + return $this->process; + } + + public function setProcess(string $process): static + { + $this->process = $process; + + return $this; + } + + public function getContext(): array + { + return is_array($this->context) ? $this->context : json_decode($this->context); + } + + public function setContext(array $context): void + { + $this->context = $context; + } + + public function getNextExecution(): null + { + return null; + } + + public function getType(): ProcessScheduleType + { + return $this->type; + } + + public function setType(ProcessScheduleType $type): self + { + $this->type = $type; + + return $this; + } + + public function getExpression(): ?string + { + return $this->expression; + } + + public function setExpression(?string $expression): self + { + $this->expression = $expression; + + return $this; + } + + public function getInput(): ?string + { + return $this->input; + } + + public function setInput(?string $input): self + { + $this->input = $input; + + return $this; + } +} diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php new file mode 100644 index 0000000..204aeb8 --- /dev/null +++ b/src/Form/Type/ProcessContextType.php @@ -0,0 +1,39 @@ +add( + 'key', + null, + [ + 'label' => 'Context Key', + 'attr' => ['placeholder' => 'key'], + 'constraints' => [new NotBlank()] + ] + )->add( + 'value', + null, + [ + 'label' => 'Context Value', + 'attr' => ['placeholder' => 'value'], + 'constraints' => [new NotBlank()] + ] + ); + } + + + public function configureOptions(OptionsResolver $resolver): void + { + } +} diff --git a/src/Message/CronProcessMessage.php b/src/Message/CronProcessMessage.php new file mode 100644 index 0000000..6d8bc86 --- /dev/null +++ b/src/Message/CronProcessMessage.php @@ -0,0 +1,14 @@ +processSchedule; + $this->bus->dispatch( + new ProcessExecuteMessage($schedule->getProcess(), $schedule->getInput(), $message->processSchedule->getContext()) + ); + } +} diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php new file mode 100644 index 0000000..454a14f --- /dev/null +++ b/src/Migrations/Version20240729151928.php @@ -0,0 +1,43 @@ +connection->getDatabasePlatform(); + if ($platform instanceof PostgreSQLPlatform) { + $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL, PRIMARY KEY(id))'); + } + if ($platform instanceof SqlitePlatform) { + $this->addSql('CREATE TABLE process_schedule (id INTEGER AUTO_INCREMENT PRIMARY KEY AUTOINCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context CLOB NOT NULL --(DC2Type:json))'); + } + + if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { + $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL COMMENT \'(DC2Type:json)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;'); + } + } + + public function down(Schema $schema): void + { + $this->addSql('DROP TABLE process_schedule'); + } +} diff --git a/src/Repository/ProcessScheduleRepository.php b/src/Repository/ProcessScheduleRepository.php new file mode 100644 index 0000000..b7b3452 --- /dev/null +++ b/src/Repository/ProcessScheduleRepository.php @@ -0,0 +1,25 @@ + + * + * @method ProcessSchedule|null find($id, $lockMode = null, $lockVersion = null) + * @method ProcessSchedule|null findOneBy(array $criteria, array $orderBy = null) + * @method ProcessSchedule[] findAll() + * @method ProcessSchedule[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class ProcessScheduleRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ProcessSchedule::class); + } +} diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php new file mode 100644 index 0000000..e5de3b2 --- /dev/null +++ b/src/Scheduler/CronScheduler.php @@ -0,0 +1,61 @@ +repository->findAll() as $processSchedule) { + $violations = $this->validator->validate($processSchedule); + if (0 !== $violations->count()) { + foreach ($violations as $violation) { + $this->logger->info( + 'Scheduler configuration is not valid.', + ['reason' => $violation->getMessage()] + ); + } + continue; + } + if (ProcessScheduleType::CRON === $processSchedule->getType()) { + $schedule->add( + RecurringMessage::cron( + $processSchedule->getExpression(), + new CronProcessMessage($processSchedule) + ) + ); + } elseif (ProcessScheduleType::EVERY === $processSchedule->getType()) { + $schedule->add( + RecurringMessage::every( + $processSchedule->getExpression(), + new CronProcessMessage($processSchedule) + ) + ); + } + } + + return $schedule; + } +} diff --git a/src/Validator/CronExpression.php b/src/Validator/CronExpression.php new file mode 100644 index 0000000..9d1a363 --- /dev/null +++ b/src/Validator/CronExpression.php @@ -0,0 +1,13 @@ +context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $value) + ->addViolation(); + } + } +} diff --git a/src/Validator/EveryExpression.php b/src/Validator/EveryExpression.php new file mode 100644 index 0000000..2288311 --- /dev/null +++ b/src/Validator/EveryExpression.php @@ -0,0 +1,13 @@ +context->buildViolation($constraint->message) + ->setParameter('{{ value }}', $value) + ->addViolation(); + } +} diff --git a/src/Validator/IsValidProcessCode.php b/src/Validator/IsValidProcessCode.php new file mode 100644 index 0000000..b957e86 --- /dev/null +++ b/src/Validator/IsValidProcessCode.php @@ -0,0 +1,14 @@ +registry->hasProcessConfiguration($value)) { + $this->context->buildViolation($constraint->messageNotExists) + ->setParameter('{{ value }}', $value) + ->addViolation(); + + return; + } + + if (!$this->registry->getProcessConfiguration($value)->isPublic()) { + $this->context->buildViolation($constraint->messageIsNotPublic) + ->setParameter('{{ value }}', $value) + ->addViolation(); + } + } +} From 3a768a827941f32f3e629361a8b237ce0ba06ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 1 Aug 2024 09:36:10 +0200 Subject: [PATCH 013/115] [Feature] Http post request process launcher --- README.md | 22 ++++++- src/Controller/Admin/UserCrudController.php | 29 ++++++++- src/Controller/ProcessExecuteController.php | 44 +++++++++++++ src/Entity/User.php | 16 +++++ src/Http/Model/HttpProcessExecution.php | 20 ++++++ .../HttpProcessExecuteValueResolver.php | 34 +++++++++++ src/Migrations/Version20240730090403.php | 33 ++++++++++ .../HttpProcessExecutionAuthenticator.php | 61 +++++++++++++++++++ 8 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 src/Controller/ProcessExecuteController.php create mode 100644 src/Http/Model/HttpProcessExecution.php create mode 100644 src/Http/ValueResolver/HttpProcessExecuteValueResolver.php create mode 100644 src/Migrations/Version20240730090403.php create mode 100644 src/Security/HttpProcessExecutionAuthenticator.php diff --git a/README.md b/README.md index b8ef7cb..e694372 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -![Code Style](https://github.com/cleverage/processuibundle/actions/workflows/super-linter.yml/badge.svg) ![Composer](https://github.com/cleverage/processuibundle/actions/workflows/php.yml/badge.svg) - ## CleverAge/ProcessUIBundle A simple UX for cleverage/processbundle using EasyAdmin @@ -17,6 +15,26 @@ processui: Now you can access Process UI via http://your-domain.com/process # Features +### Launch process via http request +You can launch a process via http post request +First you need to generate a token via UI User edit form. The ProcessUi generate for you a auth token (keep it in secured area, it will display once). + +It' all, now you can launch a process via http post request + +***Curl sample*** +``` +curl --location 'https://localhost:8080/http/process/execute?code=demo.die' \ +--header 'Authorization: Bearer 3da8409b5f5b640fb0c43d68e8ac8d23' \ +--form 'input=@"/file.csv"' \ +--form 'context[context_1]="FOO"' \ +--form 'context[context_2]="BAR"' +``` +* Query string code parameter must be a valid process code +* Header Autorization: Bearer is the previously generated token +* input could be string or file representation +* context you can pass multiple context values + + ### Scheduler You can schedule process execution via UI using cron expression (*/5 * * * *) or periodical triggers (5 seconds) For more details about cron expression and peridical triggers visit https://symfony.com/doc/6.4/scheduler.html#cron-expression-triggers and https://symfony.com/doc/6.4/scheduler.html#periodical-triggers diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 8cc3cd4..fd964e3 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -8,13 +8,17 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; +use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher; use Symfony\Component\Security\Http\Attribute\IsGranted; #[IsGranted('ROLE_USER')] @@ -57,7 +61,6 @@ public function configureFields(string $pageName): iterable 'mapped' => false, ] ); - yield FormField::addTab('Informations')->setIcon('fa fa-user'); yield TextField::new('firstname'); yield TextField::new('lastname'); @@ -86,6 +89,28 @@ public function configureActions(Actions $actions): Actions })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { return $action->setLabel('Delete') ->addCssClass(''); - }); + })->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')); + } + + + public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adminUrlGenerator): Response + { + /** @var User $user */ + $user = $adminContext->getEntity()->getInstance(); + $token = md5(uniqid(date('YmdHis'))); + $user->setToken((new Pbkdf2PasswordHasher())->hash($token)); + $this->persistEntity( + $this->container->get('doctrine')->getManagerForClass($adminContext->getEntity()->getFqcn()), + $user + ); + $this->addFlash('success', 'New token generated ' . $token . ' (keep it in secured area. This token will never be displayed anymore)'); + + return $this->redirect( + $adminUrlGenerator + ->setController(UserCrudController::class) + ->setAction(Action::EDIT) + ->setEntityId($user->getId()) + ->generateUrl() + ); } } diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php new file mode 100644 index 0000000..dd745cd --- /dev/null +++ b/src/Controller/ProcessExecuteController.php @@ -0,0 +1,44 @@ +validate($httpProcessExecution); + if ($violations->count() > 0) { + $violationsMessages = []; + foreach ($violations as $violation) { + $violationsMessages[] = $violation->getMessage(); + } + throw new UnprocessableEntityHttpException(implode('. ', $violationsMessages)); + } + $bus->dispatch( + new ProcessExecuteMessage( + $httpProcessExecution->code, + $httpProcessExecution->input, + $httpProcessExecution->context + ) + ); + + return new JsonResponse('Process has been added to queue. It will start as soon as possible.'); + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index f89463e..02832af 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -33,6 +33,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $password; + #[ORM\Column(type: 'string', length: 255, nullable: true)] + private ?string $token; + public function getId(): ?int { return $this->id; @@ -122,6 +125,19 @@ public function setPassword(string $password): self return $this; } + public function getToken(): ?string + { + return $this->token; + } + + public function setToken(?string $token): self + { + $this->token = $token; + + return $this; + } + + /** * Returning a salt is only needed, if you are not using a modern * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml. diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php new file mode 100644 index 0000000..7e770dc --- /dev/null +++ b/src/Http/Model/HttpProcessExecution.php @@ -0,0 +1,20 @@ +get('input', $request->files->get('input')); + if ($input instanceof UploadedFile) { + $uploadFileName = $this->storageDir . DIRECTORY_SEPARATOR . date('YmdHis') . '_' . uniqid() . '_' . $input->getClientOriginalName(); + (new Filesystem())->dumpFile($uploadFileName, $input->getContent()); + $input = $uploadFileName; + + } + + return [new HttpProcessExecution($request->get('code'), $input, $request->get('context', []))]; + } +} \ No newline at end of file diff --git a/src/Migrations/Version20240730090403.php b/src/Migrations/Version20240730090403.php new file mode 100644 index 0000000..205f650 --- /dev/null +++ b/src/Migrations/Version20240730090403.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE process_user ADD token VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE process_user DROP token'); + } +} diff --git a/src/Security/HttpProcessExecutionAuthenticator.php b/src/Security/HttpProcessExecutionAuthenticator.php new file mode 100644 index 0000000..ccac246 --- /dev/null +++ b/src/Security/HttpProcessExecutionAuthenticator.php @@ -0,0 +1,61 @@ +get('_route') && $request->isMethod(Request::METHOD_POST); + } + + public function authenticate(Request $request): Passport + { + if (false === $request->headers->has('Authorization')) { + throw new AuthenticationException('Missing auth token.'); + } + $token = $request->headers->get('Authorization'); + $token = str_replace('Bearer ', '', null === $token ? [''] : $token); + $user = $this->entityManager->getRepository(User::class)->findOneBy( + ['token' => (new Pbkdf2PasswordHasher())->hash($token)] + ); + if (null === $user) { + throw new AuthenticationException('Invalid token.'); + } + + return new SelfValidatingPassport(new UserBadge($user->getEmail())); + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response + { + return null; + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response + { + $data = [ + 'message' => $exception->getMessage() + ]; + + return new JsonResponse($data, Response::HTTP_UNAUTHORIZED); + } +} From 458e6d9c713ddcc71d2eb7752fd08ffa0e69cfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 1 Aug 2024 11:00:04 +0200 Subject: [PATCH 014/115] Launch process form to set input && context --- .../Admin/Process/ExecuteAction.php | 33 -------- src/Controller/Admin/Process/LaunchAction.php | 78 +++++++++++++++++++ src/Form/Type/LaunchType.php | 55 +++++++++++++ ...and_execute.html.twig => launch.html.twig} | 9 +-- templates/admin/process/list.html.twig | 45 +---------- 5 files changed, 138 insertions(+), 82 deletions(-) delete mode 100644 src/Controller/Admin/Process/ExecuteAction.php create mode 100644 src/Controller/Admin/Process/LaunchAction.php create mode 100644 src/Form/Type/LaunchType.php rename templates/admin/process/{upload_and_execute.html.twig => launch.html.twig} (68%) diff --git a/src/Controller/Admin/Process/ExecuteAction.php b/src/Controller/Admin/Process/ExecuteAction.php deleted file mode 100644 index 8da0685..0000000 --- a/src/Controller/Admin/Process/ExecuteAction.php +++ /dev/null @@ -1,33 +0,0 @@ -get('process'); - if (null === $process) { - $this->createNotFoundException('Process is missing'); - } - $bus->dispatch(new ProcessExecuteMessage($process, null)); - $this->addFlash( - 'success', - 'Process has been added to queue. It will start as soon as possible' - ); - - return $this->redirectToRoute('process', ['routeName' => 'process_list']); - } -} diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php new file mode 100644 index 0000000..17acc17 --- /dev/null +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -0,0 +1,78 @@ + '\w+'], + methods: ['POST', 'GET'] +)] +#[IsGranted('ROLE_USER')] +class LaunchAction extends AbstractController +{ + public function __invoke( + RequestStack $requestStack, + MessageBusInterface $messageBus, + #[Autowire(param: 'upload_directory')] string $uploadDirectory, + #[ValueResolver('process')] ProcessConfiguration $processConfiguration, + AdminContext $context + ): Response { + $form = $this->createForm( + LaunchType::class, + null, + ['process_code' => $requestStack->getMainRequest()?->get('process')] + ); + $form->handleRequest($requestStack->getMainRequest()); + if ($form->isSubmitted() && $form->isValid()) { + /** @var mixed|UploadedFile $file */ + $input = $form->get('input')->getData(); + if ($input instanceof UploadedFile) { + $filename = sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $input->getClientOriginalExtension()); + (new Filesystem())->dumpFile($filename, $input->getContent()); + $input = $filename; + } + $context = $form->get('context')->getData(); + $message = new ProcessExecuteMessage( + $form->getConfig()->getOption('process_code'), + $input, + $context + ); + $messageBus->dispatch($message); + $this->addFlash( + 'success', + 'Process has been added to queue. It will start as soon as possible' + ); + + return $this->redirectToRoute('process', ['routeName' => 'process_list']); + } + $context->getAssets()->addJsAsset(Asset::fromEasyAdminAssetPackage('field-collection.js')->getAsDto()); + return $this->render( + '@CleverAgeProcessUi/admin/process/launch.html.twig', + [ + 'form' => $form->createView(), + ] + ); + } +} diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php new file mode 100644 index 0000000..3cd7445 --- /dev/null +++ b/src/Form/Type/LaunchType.php @@ -0,0 +1,55 @@ +registry->getProcessConfiguration($code); + $builder->add( + 'input', + "file" === ($configuration->getOptions()['ui']['entrypoint_type'] ?? null) ? FileType::class : TextType::class, + [ + 'required' => !(null === $configuration->getEntryPoint()) + ] + ); + $builder->add( + 'context', + CollectionType::class, + [ + 'entry_type' => ProcessContextType::class, + 'allow_add' => true, + 'allow_delete' => true, + 'required' => false, + ] + ); + + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setRequired('process_code'); + } + + public function getParent(): string + { + return FormType::class; + } +} diff --git a/templates/admin/process/upload_and_execute.html.twig b/templates/admin/process/launch.html.twig similarity index 68% rename from templates/admin/process/upload_and_execute.html.twig rename to templates/admin/process/launch.html.twig index 53160fc..88d0f7b 100644 --- a/templates/admin/process/upload_and_execute.html.twig +++ b/templates/admin/process/launch.html.twig @@ -2,22 +2,17 @@ {% trans_default_domain ea.i18n.translationDomain %} {% block main %} + {% form_theme form '@EasyAdmin/crud/form_theme.html.twig' %}
    -
    -
    - {{ 'Upload you file then click on button to run process in background' }} -
    -
    {{ form_start(form) }} {{ form_widget(form) }}
    - +
    {{ form_end(form) }}
    - {% endblock %} diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 5682e7b..899a671 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -32,25 +32,9 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if process.options.ui.upload_and_run is defined and true == process.options.ui.upload_and_run %} - - - - {% endif %} - {% if process.options.ui.run is defined and true == process.options.ui.run %} - - - - {% endif %} + + + - {% for process in processes %} - - - - {% endfor %} {% endblock %} From 0c6fb77a95b60c60d2bc2f2ad9f214d298a5766c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 1 Aug 2024 11:00:24 +0200 Subject: [PATCH 015/115] Fix error on Logs filter --- src/Controller/Admin/LogRecordCrudController.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 0fce4b0..458d533 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -86,15 +86,14 @@ public function configureFilters(Filters $filters): Filters public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder { $queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); - $queryBuilder->join($queryBuilder->getRootAliases()[0].'.processExecution', 'pe'); - $codes = array_map( - fn(ProcessConfiguration $configuration) => $configuration->getCode(), - $this->processConfigurationsManager->getPublicProcesses() - ); - $queryBuilder->where($queryBuilder->expr()->in('pe.code', ':codes')); - $queryBuilder->setParameter('codes', $codes); + if (false === isset($searchDto->getAppliedFilters()['processExecution'])) { + $publicProcesses = $this->processConfigurationsManager->getPublicProcesses(); + $queryBuilder->join($queryBuilder->getRootAliases()[0] . '.processExecution', 'pe'); + $codes = array_map(fn(ProcessConfiguration $configuration) => $configuration->getCode(), $publicProcesses); + $queryBuilder->where($queryBuilder->expr()->in('pe.code', ':codes')); + $queryBuilder->setParameter('codes', $codes); + } return $queryBuilder; - } } From 07d2f261d029bc862f3b70a016d0d9273649c84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 1 Aug 2024 15:38:30 +0200 Subject: [PATCH 016/115] Add custom filter for log crud on process code or id --- src/Admin/Filter/LogProcessCodeFilter.php | 60 +++++++++++++++++++ .../Admin/LogRecordCrudController.php | 34 ++++------- src/Entity/ProcessExecution.php | 5 ++ 3 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 src/Admin/Filter/LogProcessCodeFilter.php diff --git a/src/Admin/Filter/LogProcessCodeFilter.php b/src/Admin/Filter/LogProcessCodeFilter.php new file mode 100644 index 0000000..6d738ff --- /dev/null +++ b/src/Admin/Filter/LogProcessCodeFilter.php @@ -0,0 +1,60 @@ +setFilterFqcn(__CLASS__) + ->setProperty('processExecution') + ->setLabel($label) + ->setFormType(ChoiceType::class); + } + + public function addChoices(ProcessConfigurationsManager $manager): self + { + $choices = $manager->getPublicProcesses(); + $choices = array_map(fn(ProcessConfiguration $cfg) => $cfg->getCode(), $choices); + $this->setFormTypeOption('choices', $choices); + + return $this; + } + + public function setCurrentProcessExecutionId(?int $currentProcessExecutionId): self + { + $this->currentProcessExecutionId = $currentProcessExecutionId; + if (0 !== $this->currentProcessExecutionId) { + $this->setFormTypeOption('disabled', true); + } + return $this; + } + + public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, ?FieldDto $fieldDto, EntityDto $entityDto): void + { + $queryBuilder->join('entity.processExecution', 'pe'); + if (null !== $this->currentProcessExecutionId) { + $queryBuilder->andWhere($queryBuilder->expr()->eq('pe.id', ':id')); + $queryBuilder->setParameter('id', $this->currentProcessExecutionId); + return; + } + $queryBuilder->where('pe.code IN (:codes)'); + $queryBuilder->setParameter('codes', $filterDataDto->getValue()); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 458d533..d88d9bf 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -4,33 +4,32 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; -use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Admin\Field\LogLevelField; +use CleverAge\ProcessUiBundle\Admin\Filter\LogProcessCodeFilter; use CleverAge\ProcessUiBundle\Entity\LogRecord; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; -use Doctrine\ORM\QueryBuilder; -use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; -use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; -use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; -use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Filter\ChoiceFilter; use Monolog\Level; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Http\Attribute\IsGranted; #[IsGranted('ROLE_USER')] class LogRecordCrudController extends AbstractCrudController { - public function __construct(private readonly ProcessConfigurationsManager $processConfigurationsManager) + public function __construct( + private readonly ProcessConfigurationsManager $processConfigurationsManager, + private readonly RequestStack $request + ) { } @@ -76,24 +75,15 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { - return $filters->add('processExecution') + $id = $this->request->getMainRequest()->query->all('filters')['processExecution']['value'] ?? null; + return $filters->add( + LogProcessCodeFilter::new('process') + ->addChoices($this->processConfigurationsManager) + ->setCurrentProcessExecutionId((int) $id) + ) ->add( ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) ) ->add('createdAt'); } - - public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder - { - $queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); - if (false === isset($searchDto->getAppliedFilters()['processExecution'])) { - $publicProcesses = $this->processConfigurationsManager->getPublicProcesses(); - $queryBuilder->join($queryBuilder->getRootAliases()[0] . '.processExecution', 'pe'); - $codes = array_map(fn(ProcessConfiguration $configuration) => $configuration->getCode(), $publicProcesses); - $queryBuilder->where($queryBuilder->expr()->in('pe.code', ':codes')); - $queryBuilder->setParameter('codes', $codes); - } - - return $queryBuilder; - } } diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index b701f34..82e5e05 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -86,4 +86,9 @@ public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string $diff = $this->endDate->diff($this->startDate); return $diff->format($format); } + + public function getCode(): string + { + return $this->code; + } } From cf86b78e7053e739be6cebd201eaad525ec62717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 26 Aug 2024 09:47:22 +0200 Subject: [PATCH 017/115] [Fix] Migration for sqlite platform --- src/Migrations/Version20240729151928.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php index 454a14f..b3c9adf 100644 --- a/src/Migrations/Version20240729151928.php +++ b/src/Migrations/Version20240729151928.php @@ -28,7 +28,8 @@ public function up(Schema $schema): void $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL, PRIMARY KEY(id))'); } if ($platform instanceof SqlitePlatform) { - $this->addSql('CREATE TABLE process_schedule (id INTEGER AUTO_INCREMENT PRIMARY KEY AUTOINCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context CLOB NOT NULL --(DC2Type:json))'); + $this->addSql('CREATE TABLE process_schedule (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input CLOB DEFAULT NULL, context CLOB NOT NULL --(DC2Type:json) +);'); } if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { @@ -41,3 +42,4 @@ public function down(Schema $schema): void $this->addSql('DROP TABLE process_schedule'); } } + From 100813734d4c985a5d9f824a2512761b500a9621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 28 Aug 2024 14:16:27 +0200 Subject: [PATCH 018/115] [Fix] Context from form --- src/Controller/Admin/Process/LaunchAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 17acc17..93f0acd 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -53,7 +53,7 @@ public function __invoke( (new Filesystem())->dumpFile($filename, $input->getContent()); $input = $filename; } - $context = $form->get('context')->getData(); + $context = array_column($form->get('context')->getData(), 'value', 'key'); $message = new ProcessExecuteMessage( $form->getConfig()->getOption('process_code'), $input, From 992aa1db6a42cdab5a2d0b6883bdf8c85ab0bb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 29 Aug 2024 15:13:41 +0200 Subject: [PATCH 019/115] [Feature] Add default values && constraints over the execute page --- src/Controller/Admin/Process/LaunchAction.php | 26 +++++++--- .../Admin/Process/UploadAndExecuteAction.php | 3 -- src/Form/Type/LaunchType.php | 20 ++++++-- src/Manager/ProcessConfigurationsManager.php | 49 +++++++++++++++++++ .../ProcessExecutionExtensionRuntime.php | 10 ++-- 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 93f0acd..665bb58 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -6,14 +6,14 @@ use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Form\Type\LaunchType; -use CleverAge\ProcessUiBundle\Form\Type\ProcessUploadFileType; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; use EasyCorp\Bundle\EasyAdminBundle\Config\Asset; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; -use EasyCorp\Bundle\EasyAdminBundle\Dto\AssetDto; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; @@ -37,13 +37,27 @@ public function __invoke( MessageBusInterface $messageBus, #[Autowire(param: 'upload_directory')] string $uploadDirectory, #[ValueResolver('process')] ProcessConfiguration $processConfiguration, - AdminContext $context + ProcessConfigurationsManager $configurationsManager, + AdminContext $context, ): Response { + $uiOptions = $configurationsManager->getUiOptions($requestStack->getMainRequest()->get('process')); $form = $this->createForm( LaunchType::class, null, - ['process_code' => $requestStack->getMainRequest()?->get('process')] + [ + 'constraints' => $uiOptions['constraints'], + 'process_code' => $requestStack->getMainRequest()?->get('process'), + ] ); + if (false === $form->isSubmitted()) { + $default = $uiOptions['default']; + if (false === $form->get('input')->getConfig()->getType()->getInnerType() instanceof TextType + && isset($default['input']) + ) { + unset($default['input']); + } + $form->setData($default); + } $form->handleRequest($requestStack->getMainRequest()); if ($form->isSubmitted() && $form->isValid()) { /** @var mixed|UploadedFile $file */ @@ -53,11 +67,11 @@ public function __invoke( (new Filesystem())->dumpFile($filename, $input->getContent()); $input = $filename; } - $context = array_column($form->get('context')->getData(), 'value', 'key'); + $message = new ProcessExecuteMessage( $form->getConfig()->getOption('process_code'), $input, - $context + $form->get('context')->getData() ); $messageBus->dispatch($message); $this->addFlash( diff --git a/src/Controller/Admin/Process/UploadAndExecuteAction.php b/src/Controller/Admin/Process/UploadAndExecuteAction.php index ea540eb..8ad3ae0 100644 --- a/src/Controller/Admin/Process/UploadAndExecuteAction.php +++ b/src/Controller/Admin/Process/UploadAndExecuteAction.php @@ -37,9 +37,6 @@ public function __invoke( if (null === $processConfiguration->getEntryPoint()) { throw new \RuntimeException('You must set an entry_point.'); } - if (false === ($processConfiguration->getOptions()['ui']['upload_and_run'] ?? false)) { - throw new \RuntimeException('ui.upload_and_run options not set to true in process options.'); - } $form = $this->createForm( ProcessUploadFileType::class, null, diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 3cd7445..0a8e9bb 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -5,7 +5,9 @@ namespace CleverAge\ProcessUiBundle\Form\Type; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\FormType; @@ -15,7 +17,10 @@ class LaunchType extends AbstractType { - public function __construct(private readonly ProcessConfigurationRegistry $registry) + public function __construct( + private readonly ProcessConfigurationRegistry $registry, + private readonly ProcessConfigurationsManager $configurationsManager, + ) { } @@ -23,11 +28,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void { $code = $options['process_code']; $configuration = $this->registry->getProcessConfiguration($code); + $uiOptions = $this->configurationsManager->getUiOptions($code); $builder->add( 'input', - "file" === ($configuration->getOptions()['ui']['entrypoint_type'] ?? null) ? FileType::class : TextType::class, + "file" === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, [ - 'required' => !(null === $configuration->getEntryPoint()) + 'required' => !(null === $configuration->getEntryPoint()), ] ); $builder->add( @@ -40,6 +46,14 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'required' => false, ] ); + $builder->get('context')->addModelTransformer(new CallbackTransformer( + function ($data) { + return null === $data ? [] : $data; + }, + function ($data) { + return array_column($data ?? [], 'value', 'key'); + }, + )); } diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index eed55c0..68c3e74 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -5,6 +5,9 @@ use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; +use CleverAge\ProcessBundle\Validator\ConstraintLoader; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolver; final readonly class ProcessConfigurationsManager { @@ -24,6 +27,52 @@ public function getPrivateProcesses(): array return array_filter($this->getConfigurations(), fn(ProcessConfiguration $cfg) => !$cfg->isPublic()); } + public function getUiOptions(string $processCode): ?array + { + if (false === $this->registry->hasProcessConfiguration($processCode)) { + return null; + } + + $configuration = $this->registry->getProcessConfiguration($processCode); + + return $this->resolveUiOptions($configuration->getOptions())['ui']; + } + + private function resolveUiOptions(array $options): array + { + $resolver = new OptionsResolver(); + $resolver->setDefault('ui', function (OptionsResolver $uiResolver): void { + $uiResolver->setDefaults( + [ + 'source' => null, + 'target' => null, + 'entrypoint_type' => 'text', + 'constraints' => [], + 'run' => null, + 'default' => function(OptionsResolver $defaultResolver) { + $defaultResolver->setDefault('input', null); + $defaultResolver->setDefault('context', function(OptionsResolver $contextResolver) { + $contextResolver->setPrototype(true); + $contextResolver->setRequired(['key', 'value']); + }); + } + ] + ); + $uiResolver->setDeprecated( + 'run', + 'cleverage/process-ui-bundle', + '2', + 'run ui option is deprecated. Use public option instead to hide a process from UI' + ); + $uiResolver->setAllowedValues('entrypoint_type', ['text', 'file']); + $uiResolver->setNormalizer('constraints', function (Options $options, array $values): array { + return (new ConstraintLoader())->buildConstraints($values); + }); + }); + + return $resolver->resolve($options); + } + /** @return ProcessConfiguration[] */ private function getConfigurations(): array { diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index eb988cb..1ad0a7b 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -4,8 +4,8 @@ namespace CleverAge\ProcessUiBundle\Twig\Runtime; -use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; +use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; use Twig\Extension\RuntimeExtensionInterface; @@ -13,7 +13,7 @@ { public function __construct( private ProcessExecutionRepository $processExecutionRepository, - private ProcessConfigurationRegistry $processConfigurationRegistry + private ProcessConfigurationsManager $processConfigurationsManager, ) { } @@ -25,13 +25,11 @@ public function getLastExecutionDate(string $code): ?ProcessExecution public function getProcessSource(string $code): ?string { - return $this->processConfigurationRegistry - ->getProcessConfiguration($code)?->getOptions()['ui']['source'] ?? null; + return $this->processConfigurationsManager->getUiOptions($code)['source']; } public function getProcessTarget(string $code): ?string { - return $this->processConfigurationRegistry - ->getProcessConfiguration($code)?->getOptions()['ui']['target'] ?? null; + return $this->processConfigurationsManager->getUiOptions($code)['target']; } } From 7dbdb51572e5d44a5ca32efbf5347143634c82cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 3 Sep 2024 10:47:27 +0200 Subject: [PATCH 020/115] [FIX] Error on _em for ProcessExecutionRepository --- src/Repository/ProcessExecutionRepository.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index b761ff7..6125786 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -25,16 +25,15 @@ public function __construct(ManagerRegistry $registry) public function save(ProcessExecution $processExecution): void { - $this->_em->persist($processExecution); - $this->_em->flush(); + $this->getEntityManager()->persist($processExecution); + $this->getEntityManager()->flush(); } public function getLastProcessExecution(string $code): ?ProcessExecution { - $qb = $this->_em->createQueryBuilder(); + $qb = $this->createQueryBuilder('pe'); return $qb->select('pe') - ->from(ProcessExecution::class, 'pe') ->where($qb->expr()->eq('pe.code', $qb->expr()->literal($code))) ->orderBy('pe.startDate', 'DESC') ->setMaxResults(1) From b4209aeef4151b5babdd98705f0c18d128833884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 6 Sep 2024 11:18:35 +0200 Subject: [PATCH 021/115] Add message to log crud filters --- src/Controller/Admin/LogRecordCrudController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index d88d9bf..f831ada 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -84,6 +84,7 @@ public function configureFilters(Filters $filters): Filters ->add( ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) ) + ->add('message') ->add('createdAt'); } } From e116c6c619e24bb2294adcb4a5f0263501568129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 12 Sep 2024 11:18:04 +0200 Subject: [PATCH 022/115] Fix log handler (log in same file for subprocess) && messenger --- .../ProcessEventSubscriber.php | 20 +++++++++++-------- src/Message/ProcessExecuteHandler.php | 4 +++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index 783e51f..99ee679 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -38,18 +38,22 @@ public function onProcessStart(ProcessEvent $event): void public function success(ProcessEvent $event): void { - $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Finish); - $this->processExecutionManager->getCurrentProcessExecution()?->end(); - $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); - $this->processHandler->close(); + if ($event->getProcessCode() === $this->processExecutionManager?->getCurrentProcessExecution()?->getCode()) { + $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Finish); + $this->processExecutionManager->getCurrentProcessExecution()?->end(); + $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); + $this->processHandler->close(); + } } public function fail(ProcessEvent $event): void { - $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Failed); - $this->processExecutionManager->getCurrentProcessExecution()?->end(); - $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); - $this->processHandler->close(); + if ($event->getProcessCode() === $this->processExecutionManager?->getCurrentProcessExecution()?->getCode()) { + $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Failed); + $this->processExecutionManager->getCurrentProcessExecution()?->end(); + $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); + $this->processHandler->close(); + } } public function flushDoctrineLogs(ProcessEvent $event): void diff --git a/src/Message/ProcessExecuteHandler.php b/src/Message/ProcessExecuteHandler.php index 979c8f2..48e1b8a 100644 --- a/src/Message/ProcessExecuteHandler.php +++ b/src/Message/ProcessExecuteHandler.php @@ -5,17 +5,19 @@ namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessBundle\Manager\ProcessManager; +use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\Messenger\Attribute\AsMessageHandler; #[AsMessageHandler] readonly class ProcessExecuteHandler { - public function __construct(private ProcessManager $manager) + public function __construct(private ProcessManager $manager, private readonly ProcessHandler $processHandler) { } public function __invoke(ProcessExecuteMessage $message): void { + $this->processHandler->close(); $this->manager->execute($message->code, $message->input, $message->context); } } From df0e1f7ff2801e965884c7fe4677332000589ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 18 Sep 2024 10:03:18 +0200 Subject: [PATCH 023/115] Remove custom index query builder --- .../Admin/ProcessExecutionCrudController.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index 40300a3..c25412b 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -138,17 +138,4 @@ public function configureFilters(Filters $filters): Filters { return $filters->add('code')->add('startDate'); } - - public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder - { - $codes = array_map( - fn(ProcessConfiguration $configuration) => $configuration->getCode(), - $this->processConfigurationsManager->getPublicProcesses() - ); - $queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); - $queryBuilder->where($queryBuilder->expr()->in($queryBuilder->getRootAliases()[0] . '.code', ':codes')); - $queryBuilder->setParameter('codes', $codes); - - return $queryBuilder; - } } From 1f37a57c91729813b450d0f8c253a41fd8ff6973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 18 Sep 2024 11:04:26 +0200 Subject: [PATCH 024/115] Fix scheduler on first migration run --- src/Scheduler/CronScheduler.php | 52 ++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index e5de3b2..b9e647d 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -12,6 +12,7 @@ use Symfony\Component\Scheduler\Schedule; use Symfony\Component\Scheduler\ScheduleProviderInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; +use Doctrine\DBAL\Driver\AbstractException; #[AsSchedule('cron')] #[WithMonologChannel('scheduler')] @@ -28,34 +29,39 @@ public function __construct( public function getSchedule(): Schedule { $schedule = new Schedule(); - foreach ($this->repository->findAll() as $processSchedule) { - $violations = $this->validator->validate($processSchedule); - if (0 !== $violations->count()) { - foreach ($violations as $violation) { - $this->logger->info( - 'Scheduler configuration is not valid.', - ['reason' => $violation->getMessage()] + try { + foreach ($this->repository->findAll() as $processSchedule) { + $violations = $this->validator->validate($processSchedule); + if (0 !== $violations->count()) { + foreach ($violations as $violation) { + $this->logger->info( + 'Scheduler configuration is not valid.', + ['reason' => $violation->getMessage()] + ); + } + continue; + } + if (ProcessScheduleType::CRON === $processSchedule->getType()) { + $schedule->add( + RecurringMessage::cron( + $processSchedule->getExpression(), + new CronProcessMessage($processSchedule) + ) + ); + } elseif (ProcessScheduleType::EVERY === $processSchedule->getType()) { + $schedule->add( + RecurringMessage::every( + $processSchedule->getExpression(), + new CronProcessMessage($processSchedule) + ) ); } - continue; - } - if (ProcessScheduleType::CRON === $processSchedule->getType()) { - $schedule->add( - RecurringMessage::cron( - $processSchedule->getExpression(), - new CronProcessMessage($processSchedule) - ) - ); - } elseif (ProcessScheduleType::EVERY === $processSchedule->getType()) { - $schedule->add( - RecurringMessage::every( - $processSchedule->getExpression(), - new CronProcessMessage($processSchedule) - ) - ); } + } catch (\Exception $e) { + $this->logger->critical($e->getMessage()); } return $schedule; } } + From 15c7b420606014809d0734249bf0b06f0df2a55c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 24 Sep 2024 16:08:23 +0200 Subject: [PATCH 025/115] Add context to filter on log crud --- src/Controller/Admin/LogRecordCrudController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index f831ada..c954bc6 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -85,6 +85,7 @@ public function configureFilters(Filters $filters): Filters ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) ) ->add('message') + ->add('context') ->add('createdAt'); } } From aca79fcc4d5d67c77bff620ce45beac6089aafbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 7 Oct 2024 16:03:45 +0200 Subject: [PATCH 026/115] Add timezone to user --- .../Admin/ProcessDashboardController.php | 8 +++++ src/Controller/Admin/UserCrudController.php | 3 ++ src/Entity/User.php | 16 +++++++++ src/Migrations/Version20241007134542.php | 33 +++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src/Migrations/Version20241007134542.php diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index bd6edd8..14befc2 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -8,6 +8,7 @@ use CleverAge\ProcessUiBundle\Entity\ProcessExecution; use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; use CleverAge\ProcessUiBundle\Entity\User; +use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard; use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; @@ -56,4 +57,11 @@ public function configureMenuItems(): iterable ); } } + + public function configureCrud(): Crud + { + /** @var User $user */ + $user = $this->getUser(); + return parent::configureCrud()->setTimezone($user?->getTimezone() ?? date_default_timezone_get()); + } } diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index fd964e3..895e6f5 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -14,6 +14,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; +use EasyCorp\Bundle\EasyAdminBundle\Field\TimezoneField; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; @@ -69,6 +70,8 @@ public function configureFields(string $pageName): iterable yield ChoiceField::new('roles', false) ->setChoices($this->roles) ->setFormTypeOptions(['multiple' => true, 'expanded' => true]); + yield FormField::addTab('Intl.')->setIcon('fa fa-flag'); + yield TimezoneField::new('timezone'); } public function configureActions(Actions $actions): Actions diff --git a/src/Entity/User.php b/src/Entity/User.php index 02832af..03e5d05 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -33,6 +33,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $password; + #[ORM\Column(type: 'string', length: 255, nullable: true)] + private ?string $timezone; + #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $token; @@ -92,6 +95,19 @@ public function getUsername(): string return $this->getUserIdentifier(); } + public function getTimezone(): ?string + { + return $this->timezone; + } + + public function setTimezone(?string $timezone): self + { + $this->timezone = $timezone; + + return $this; + } + + /** * @see UserInterface */ diff --git a/src/Migrations/Version20241007134542.php b/src/Migrations/Version20241007134542.php new file mode 100644 index 0000000..259c62f --- /dev/null +++ b/src/Migrations/Version20241007134542.php @@ -0,0 +1,33 @@ +hasTable('process_user') && !$schema->getTable('process_user')->hasColumn('timezone')) { + $this->addSql('ALTER TABLE process_user ADD timezone VARCHAR(255) DEFAULT NULL'); + } + } + + public function down(Schema $schema): void + { + if ($schema->hasTable('process_user') && $schema->getTable('process_user')->hasColumn('timezone')) { + $this->addSql('ALTER TABLE process_user DROP timezone'); + } + } +} From 252e3ff36d56fd39c54393cd9fffc0f1c5c010c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 7 Oct 2024 17:48:57 +0200 Subject: [PATCH 027/115] Add context to process execution --- src/Controller/Admin/Process/LaunchAction.php | 13 ++++++- .../Admin/ProcessExecutionCrudController.php | 1 + src/Entity/ProcessExecution.php | 29 ++++++++++++---- .../ProcessEventSubscriber.php | 3 +- src/Migrations/Version20241007152613.php | 34 +++++++++++++++++++ 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 src/Migrations/Version20241007152613.php diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 665bb58..b3e56cd 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -5,6 +5,7 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; +use CleverAge\ProcessUiBundle\Entity\User; use CleverAge\ProcessUiBundle\Form\Type\LaunchType; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; @@ -71,7 +72,10 @@ public function __invoke( $message = new ProcessExecuteMessage( $form->getConfig()->getOption('process_code'), $input, - $form->get('context')->getData() + array_merge( + ['execution_user' => $this->getUser()?->getEmail()], + $form->get('context')->getData() + ) ); $messageBus->dispatch($message); $this->addFlash( @@ -89,4 +93,11 @@ public function __invoke( ] ); } + + protected function getUser(): ?User + { + /** @var User $user */ + $user = parent::getUser(); + return $user; + } } diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index c25412b..220ea6d 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -53,6 +53,7 @@ public function configureFields(string $pageName): iterable return $entity->duration(); // returned format can be changed here }), ArrayField::new('report')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), + ArrayField::new('context')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), ]; } diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 82e5e05..b75083f 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -5,6 +5,7 @@ namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Entity\Enum\ProcessExecutionStatus; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\String\UnicodeString; @@ -18,35 +19,39 @@ class ProcessExecution #[ORM\Column] private ?int $id = null; - #[ORM\Column(type: 'string', length: 255)] + #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $code; - #[ORM\Column(type: 'string', length: 255)] + #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename; - #[ORM\Column(type: 'datetime_immutable')] + #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public readonly \DateTimeImmutable $startDate; - #[ORM\Column(type: 'datetime_immutable', nullable: true)] + #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)] public ?\DateTimeImmutable $endDate = null; - #[ORM\Column(type: 'string', enumType: ProcessExecutionStatus::class)] + #[ORM\Column(type: Types::STRING, enumType: ProcessExecutionStatus::class)] public ProcessExecutionStatus $status; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] private array $report = []; + #[ORM\Column(type: Types::JSON, nullable: true)] + private ?array $context = []; + public function getId(): ?int { return $this->id; } - public function __construct(string $code, string $logFilename) + public function __construct(string $code, string $logFilename, ?array $context = []) { $this->code = (string) (new UnicodeString($code))->truncate(255); $this->logFilename = $logFilename; $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); $this->status = ProcessExecutionStatus::Started; + $this->context = $context ?? []; } public function setStatus(ProcessExecutionStatus $status): void @@ -91,4 +96,14 @@ public function getCode(): string { return $this->code; } + + public function getContext(): array + { + return $this->context; + } + + public function setContext(array $context): void + { + $this->context = $context; + } } diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index 99ee679..3d17791 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -30,7 +30,8 @@ public function onProcessStart(ProcessEvent $event): void if (null === $this->processExecutionManager->getCurrentProcessExecution()) { $processExecution = new ProcessExecution( $event->getProcessCode(), - basename($this->processHandler->getFilename()) + basename($this->processHandler->getFilename()), + $event->getProcessContext() ); $this->processExecutionManager->setCurrentProcessExecution($processExecution)->save(); } diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php new file mode 100644 index 0000000..b6360b2 --- /dev/null +++ b/src/Migrations/Version20241007152613.php @@ -0,0 +1,34 @@ +hasTable('process_execution') && !$schema->getTable('process_execution')->hasColumn('context')) { + $this->addSql('ALTER TABLE process_execution ADD context JSON NOT NULL COMMENT \'(DC2Type:json)\''); + } + } + + public function down(Schema $schema): void + { + if ($schema->hasTable('process_execution') && $schema->getTable('process_execution')->hasColumn('context')) { + $this->addSql('ALTER TABLE process_execution DROP context'); + + } + } +} From 374e6302697af3de61fe4dfb606f0f1077a87507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 8 Oct 2024 15:50:14 +0200 Subject: [PATCH 028/115] Delete comment on last migration --- src/Migrations/Version20241007152613.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php index b6360b2..c5e1ddf 100644 --- a/src/Migrations/Version20241007152613.php +++ b/src/Migrations/Version20241007152613.php @@ -20,7 +20,7 @@ public function getDescription(): string public function up(Schema $schema): void { if ($schema->hasTable('process_execution') && !$schema->getTable('process_execution')->hasColumn('context')) { - $this->addSql('ALTER TABLE process_execution ADD context JSON NOT NULL COMMENT \'(DC2Type:json)\''); + $this->addSql('ALTER TABLE process_execution ADD context JSON NOT NULL'); } } From c3e6378f66a12f91dfa404a1410e102a7a85c6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 9 Oct 2024 10:35:59 +0200 Subject: [PATCH 029/115] Add locale managment to user --- .../Admin/ProcessDashboardController.php | 9 +++- src/Controller/Admin/UserCrudController.php | 2 + src/Entity/User.php | 15 ++++++ src/Migrations/Version20241009075733.php | 30 +++++++++++ templates/admin/process/list.html.twig | 12 ++--- translations/messages.fr.yaml | 54 +++++++++++++++++++ 6 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 src/Migrations/Version20241009075733.php create mode 100644 translations/messages.fr.yaml diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 14befc2..35d9cc6 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -16,11 +16,15 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; +use Symfony\Component\Translation\LocaleSwitcher; #[IsGranted('ROLE_USER')] class ProcessDashboardController extends AbstractDashboardController { - public function __construct(private readonly string $logoPath = '') + public function __construct( + private readonly LocaleSwitcher $localeSwitcher, + private readonly string $logoPath = '' + ) { } @@ -62,6 +66,9 @@ public function configureCrud(): Crud { /** @var User $user */ $user = $this->getUser(); + if (null !== $user->getLocale()) { + $this->localeSwitcher->setLocale($user->getLocale()); + } return parent::configureCrud()->setTimezone($user?->getTimezone() ?? date_default_timezone_get()); } } diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 895e6f5..18482c6 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -13,6 +13,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; +use EasyCorp\Bundle\EasyAdminBundle\Field\LocaleField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TimezoneField; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; @@ -72,6 +73,7 @@ public function configureFields(string $pageName): iterable ->setFormTypeOptions(['multiple' => true, 'expanded' => true]); yield FormField::addTab('Intl.')->setIcon('fa fa-flag'); yield TimezoneField::new('timezone'); + yield LocaleField::new('locale'); } public function configureActions(Actions $actions): Actions diff --git a/src/Entity/User.php b/src/Entity/User.php index 03e5d05..37f2413 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -36,6 +36,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $timezone; + #[ORM\Column(type: 'string', length: 255, nullable: true)] + private ?string $locale; + #[ORM\Column(type: 'string', length: 255, nullable: true)] private ?string $token; @@ -107,6 +110,18 @@ public function setTimezone(?string $timezone): self return $this; } + public function getLocale(): ?string + { + return $this->locale; + } + + public function setLocale(?string $locale): self + { + $this->locale = $locale; + + return $this; + } + /** * @see UserInterface diff --git a/src/Migrations/Version20241009075733.php b/src/Migrations/Version20241009075733.php new file mode 100644 index 0000000..1281ae3 --- /dev/null +++ b/src/Migrations/Version20241009075733.php @@ -0,0 +1,30 @@ +hasTable('process_user') && !$schema->getTable('process_user')->hasColumn('locale')) { + $this->addSql('ALTER TABLE process_user ADD locale VARCHAR(255) DEFAULT NULL'); + } + } + + public function down(Schema $schema): void + { + if ($schema->hasTable('process_user') && $schema->getTable('process_user')->hasColumn('locale')) { + $this->addSql('ALTER TABLE process_user DROP locale'); + } + } +} diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 899a671..ac6d384 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -7,12 +7,12 @@ {% block table_head %} - Process code - Last execution - Status - Source - Target - Actions + {{ 'Process code'|trans }} + {{ 'Last execution'|trans }} + {{ 'Status'|trans }} + {{ 'Source'|trans }} + {{ 'Target'|trans }} + {{ 'Actions'|trans }} {% endblock %} diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml new file mode 100644 index 0000000..4d276e3 --- /dev/null +++ b/translations/messages.fr.yaml @@ -0,0 +1,54 @@ +Generate Token: Générer un jeton +Credentials: Informations d'identification +User: Utilisateur +Dashboard: Tableau de bord +Process: Processus +Process list: Liste des processus +Executions: Exécutions +Logs: Logs +Scheduler: Planificateur +Users: Utilisateurs +User List: Liste des utilisateurs +Informations: Informations +Roles: Rôles +Intl.: Internationalisation +Email: Email +New password: Nouveau mot de passe +Repeat password: Répéter le mot de passe +Firstname: Prénom +Lastname: Nom +Timezone: Fuseau horaire +Locale: Locale +ProcessExecution: Exécution des processus +Code: Code +Status: Status +Start Date: Date de début +End Date: Date de fin +Source: Source +Target: Destination +Duration: Durée +Report: Rapport +Context: Context +Launch: Exécuter +View executions: Voir les éxécutions +Process code: Code du processus +Last execution: Dernière exécution +Actions: Actions +LogRecord: Logs +Level: Niveau +Message: Message +Created At: Date de création +Has context info ?: Context ? +ProcessSchedule: Planificateur +To run scheduler, ensure "bin/console messenger:consume scheduler_cron" console is alive. See https://symfony.com/doc/current/messenger.html#supervisor-configuration.: "Pour fonctionner, assurez vous que la commande \"bin/console messenger:consume scheduler_cron\" soit exécutée. Plus d''informations sur https://symfony.com/doc/current/messenger.html#supervisor-configuration." +Delete: Supprimer +Type: Type +Expression: Expression +Next Execution: Prochaîne exécution +Input: Input +General: Général +Context (key/value): Context (clé/valeur) +key: clé +value: valeur +Context Key: Context clé +Context Value: Context valeur From 6734e40e5fa006175cb130a800499571e28f3fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 9 Oct 2024 10:50:20 +0200 Subject: [PATCH 030/115] PHPCS Fix --- src/Admin/Field/EnumField.php | 2 +- src/Admin/Field/LogLevelField.php | 2 +- src/Admin/Filter/LogProcessCodeFilter.php | 7 +++++-- .../Admin/LogRecordCrudController.php | 21 +++++++------------ src/Controller/Admin/Process/LaunchAction.php | 2 ++ src/Controller/Admin/Process/ListAction.php | 2 +- .../Admin/ProcessDashboardController.php | 4 ++-- .../Admin/ProcessExecutionCrudController.php | 12 +---------- .../Admin/ProcessScheduleCrudController.php | 11 +++++----- src/Controller/Admin/UserCrudController.php | 3 +-- src/Controller/ProcessExecuteController.php | 3 +-- src/Entity/ProcessExecution.php | 3 ++- src/Entity/ProcessSchedule.php | 4 ++-- src/Entity/User.php | 2 -- src/Form/Type/LaunchType.php | 20 ++++++++---------- src/Form/Type/ProcessContextType.php | 5 ++--- src/Http/Model/HttpProcessExecution.php | 8 +++---- .../HttpProcessExecuteValueResolver.php | 8 +++---- src/Manager/ProcessConfigurationsManager.php | 11 +++++----- src/Message/CronProcessMessage.php | 2 +- src/Message/CronProcessMessageHandler.php | 4 ++-- src/Migrations/Version20231006111525.php | 8 +++---- src/Migrations/Version20240729151928.php | 1 - src/Migrations/Version20240730090403.php | 4 ---- src/Migrations/Version20241007152613.php | 1 - src/Scheduler/CronScheduler.php | 9 ++++---- .../HttpProcessExecutionAuthenticator.php | 2 +- src/Twig/Runtime/LogLevelExtensionRuntime.php | 12 +++++------ .../ProcessExecutionExtensionRuntime.php | 3 +-- 29 files changed, 75 insertions(+), 101 deletions(-) diff --git a/src/Admin/Field/EnumField.php b/src/Admin/Field/EnumField.php index 6f39f7b..6c9ab87 100644 --- a/src/Admin/Field/EnumField.php +++ b/src/Admin/Field/EnumField.php @@ -11,7 +11,7 @@ class EnumField implements FieldInterface { use FieldTrait; - public static function new(string $propertyName, string $label = null): self + public static function new(string $propertyName, ?string $label = null): self { return (new self()) ->setProperty($propertyName) diff --git a/src/Admin/Field/LogLevelField.php b/src/Admin/Field/LogLevelField.php index df0c2bf..67250c8 100644 --- a/src/Admin/Field/LogLevelField.php +++ b/src/Admin/Field/LogLevelField.php @@ -11,7 +11,7 @@ class LogLevelField implements FieldInterface { use FieldTrait; - public static function new(string $propertyName, string $label = null): self + public static function new(string $propertyName, ?string $label = null): self { return (new self()) ->setProperty($propertyName) diff --git a/src/Admin/Filter/LogProcessCodeFilter.php b/src/Admin/Filter/LogProcessCodeFilter.php index 6d738ff..e4af123 100644 --- a/src/Admin/Filter/LogProcessCodeFilter.php +++ b/src/Admin/Filter/LogProcessCodeFilter.php @@ -1,4 +1,5 @@ getPublicProcesses(); - $choices = array_map(fn(ProcessConfiguration $cfg) => $cfg->getCode(), $choices); + $choices = array_map(fn (ProcessConfiguration $cfg) => $cfg->getCode(), $choices); $this->setFormTypeOption('choices', $choices); return $this; @@ -43,6 +44,7 @@ public function setCurrentProcessExecutionId(?int $currentProcessExecutionId): s if (0 !== $this->currentProcessExecutionId) { $this->setFormTypeOption('disabled', true); } + return $this; } @@ -52,9 +54,10 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, if (null !== $this->currentProcessExecutionId) { $queryBuilder->andWhere($queryBuilder->expr()->eq('pe.id', ':id')); $queryBuilder->setParameter('id', $this->currentProcessExecutionId); + return; } $queryBuilder->where('pe.code IN (:codes)'); $queryBuilder->setParameter('codes', $filterDataDto->getValue()); } -} \ No newline at end of file +} diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index c954bc6..f840c62 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -25,12 +25,10 @@ #[IsGranted('ROLE_USER')] class LogRecordCrudController extends AbstractCrudController { - public function __construct( private readonly ProcessConfigurationsManager $processConfigurationsManager, private readonly RequestStack $request - ) - { + ) { } public static function getEntityFqcn(): string @@ -76,16 +74,13 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { $id = $this->request->getMainRequest()->query->all('filters')['processExecution']['value'] ?? null; + return $filters->add( - LogProcessCodeFilter::new('process') - ->addChoices($this->processConfigurationsManager) - ->setCurrentProcessExecutionId((int) $id) - ) - ->add( - ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) - ) - ->add('message') - ->add('context') - ->add('createdAt'); + LogProcessCodeFilter::new('process') + ->addChoices($this->processConfigurationsManager) + ->setCurrentProcessExecutionId((int) $id) + )->add( + ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) + )->add('message')->add('context')->add('createdAt'); } } diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index b3e56cd..5d5b98c 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -86,6 +86,7 @@ public function __invoke( return $this->redirectToRoute('process', ['routeName' => 'process_list']); } $context->getAssets()->addJsAsset(Asset::fromEasyAdminAssetPackage('field-collection.js')->getAsDto()); + return $this->render( '@CleverAgeProcessUi/admin/process/launch.html.twig', [ @@ -98,6 +99,7 @@ protected function getUser(): ?User { /** @var User $user */ $user = parent::getUser(); + return $user; } } diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php index 26726b1..1af4a0f 100644 --- a/src/Controller/Admin/Process/ListAction.php +++ b/src/Controller/Admin/Process/ListAction.php @@ -19,7 +19,7 @@ public function __invoke(ProcessConfigurationsManager $processConfigurationsMana return $this->render( '@CleverAgeProcessUi/admin/process/list.html.twig', [ - 'processes' => $processConfigurationsManager->getPublicProcesses() + 'processes' => $processConfigurationsManager->getPublicProcesses(), ] ); } diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 35d9cc6..41bfcd1 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -24,8 +24,7 @@ class ProcessDashboardController extends AbstractDashboardController public function __construct( private readonly LocaleSwitcher $localeSwitcher, private readonly string $logoPath = '' - ) - { + ) { } #[Route('/process', name: 'process')] @@ -69,6 +68,7 @@ public function configureCrud(): Crud if (null !== $user->getLocale()) { $this->localeSwitcher->setLocale($user->getLocale()); } + return parent::configureCrud()->setTimezone($user?->getTimezone() ?? date_default_timezone_get()); } } diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index 220ea6d..fad622f 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -4,21 +4,14 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; -use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Admin\Field\EnumField; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; -use Doctrine\ORM\QueryBuilder; -use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; -use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; -use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; -use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; @@ -32,9 +25,6 @@ #[IsGranted('ROLE_USER')] class ProcessExecutionCrudController extends AbstractCrudController { - public function __construct(private readonly ProcessConfigurationsManager $processConfigurationsManager) - { - } public static function getEntityFqcn(): string { return ProcessExecution::class; @@ -49,7 +39,7 @@ public function configureFields(string $pageName): iterable DateTimeField::new('endDate')->setFormat('Y/M/dd H:mm:ss'), TextField::new('source')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_source.html.twig'), TextField::new('target')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_target.html.twig'), - TextField::new('duration')->formatValue(function($value, ProcessExecution $entity) { + TextField::new('duration')->formatValue(function ($value, ProcessExecution $entity) { return $entity->duration(); // returned format can be changed here }), ArrayField::new('report')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), diff --git a/src/Controller/Admin/ProcessScheduleCrudController.php b/src/Controller/Admin/ProcessScheduleCrudController.php index 7193165..9aff0e9 100644 --- a/src/Controller/Admin/ProcessScheduleCrudController.php +++ b/src/Controller/Admin/ProcessScheduleCrudController.php @@ -4,11 +4,11 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; +use CleverAge\ProcessUiBundle\Admin\Field\EnumField; use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; use CleverAge\ProcessUiBundle\Entity\ProcessScheduleType; use CleverAge\ProcessUiBundle\Form\Type\ProcessContextType; -use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; -use CleverAge\ProcessUiBundle\Admin\Field\EnumField; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; @@ -68,10 +68,10 @@ public static function getEntityFqcn(): string public function configureFields(string $pageName): iterable { - - $choices = array_map(function(ProcessConfiguration $configuration) { + $choices = array_map(function (ProcessConfiguration $configuration) { return [$configuration->getCode()]; }, $this->processConfigurationsManager->getPublicProcesses()); + return [ FormField::addTab('General'), TextField::new('process') @@ -99,7 +99,7 @@ public function configureFields(string $pageName): iterable ->hideOnIndex() ->setFormTypeOption('entry_options.label', 'Context (key/value)') ->setFormTypeOption('label', '') - ->setFormTypeOption('required', false) + ->setFormTypeOption('required', false), ]; } @@ -114,7 +114,6 @@ public function index(AdminContext $context): KeyValueStore|RedirectResponse|Res private function schedulerIsRunning(): bool { - $process = Process::fromShellCommandline('ps -faux'); $process->run(); $out = $process->getOutput(); diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 18482c6..16b4fbf 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -97,7 +97,6 @@ public function configureActions(Actions $actions): Actions })->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')); } - public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adminUrlGenerator): Response { /** @var User $user */ @@ -108,7 +107,7 @@ public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adm $this->container->get('doctrine')->getManagerForClass($adminContext->getEntity()->getFqcn()), $user ); - $this->addFlash('success', 'New token generated ' . $token . ' (keep it in secured area. This token will never be displayed anymore)'); + $this->addFlash('success', 'New token generated '.$token.' (keep it in secured area. This token will never be displayed anymore)'); return $this->redirect( $adminUrlGenerator diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php index dd745cd..a20eb17 100644 --- a/src/Controller/ProcessExecuteController.php +++ b/src/Controller/ProcessExecuteController.php @@ -21,8 +21,7 @@ public function __invoke( #[ValueResolver('http_process_execution')] HttpProcessExecution $httpProcessExecution, ValidatorInterface $validator, MessageBusInterface $bus - ): JsonResponse - { + ): JsonResponse { $violations = $validator->validate($httpProcessExecution); if ($violations->count() > 0) { $violationsMessages = []; diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index b75083f..aff3b13 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -74,7 +74,7 @@ public function addReport(string $key, mixed $value): void $this->report[$key] = $value; } - public function getReport(string $key = null, mixed $default = null): mixed + public function getReport(?string $key = null, mixed $default = null): mixed { if (null === $key) { return $this->report; @@ -89,6 +89,7 @@ public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string return null; } $diff = $this->endDate->diff($this->startDate); + return $diff->format($format); } diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 8a26e88..1bdb677 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -13,8 +13,8 @@ enum ProcessScheduleType: string { - case CRON = "cron"; - case EVERY = "every"; + case CRON = 'cron'; + case EVERY = 'every'; } #[ORM\Entity(repositoryClass: ProcessScheduleRepository::class)] diff --git a/src/Entity/User.php b/src/Entity/User.php index 37f2413..a65df93 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -122,7 +122,6 @@ public function setLocale(?string $locale): self return $this; } - /** * @see UserInterface */ @@ -168,7 +167,6 @@ public function setToken(?string $token): self return $this; } - /** * Returning a salt is only needed, if you are not using a modern * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml. diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 0a8e9bb..60027d1 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -20,10 +20,9 @@ class LaunchType extends AbstractType public function __construct( private readonly ProcessConfigurationRegistry $registry, private readonly ProcessConfigurationsManager $configurationsManager, - ) - { - + ) { } + public function buildForm(FormBuilderInterface $builder, array $options): void { $code = $options['process_code']; @@ -31,7 +30,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $uiOptions = $this->configurationsManager->getUiOptions($code); $builder->add( 'input', - "file" === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, + 'file' === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, [ 'required' => !(null === $configuration->getEntryPoint()), ] @@ -39,12 +38,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->add( 'context', CollectionType::class, - [ - 'entry_type' => ProcessContextType::class, - 'allow_add' => true, - 'allow_delete' => true, - 'required' => false, - ] + [ + 'entry_type' => ProcessContextType::class, + 'allow_add' => true, + 'allow_delete' => true, + 'required' => false, + ] ); $builder->get('context')->addModelTransformer(new CallbackTransformer( function ($data) { @@ -54,7 +53,6 @@ function ($data) { return array_column($data ?? [], 'value', 'key'); }, )); - } public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php index 204aeb8..daa48d1 100644 --- a/src/Form/Type/ProcessContextType.php +++ b/src/Form/Type/ProcessContextType.php @@ -19,7 +19,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void [ 'label' => 'Context Key', 'attr' => ['placeholder' => 'key'], - 'constraints' => [new NotBlank()] + 'constraints' => [new NotBlank()], ] )->add( 'value', @@ -27,12 +27,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void [ 'label' => 'Context Value', 'attr' => ['placeholder' => 'value'], - 'constraints' => [new NotBlank()] + 'constraints' => [new NotBlank()], ] ); } - public function configureOptions(OptionsResolver $resolver): void { } diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index 7e770dc..7f66563 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -1,5 +1,7 @@ get('input', $request->files->get('input')); if ($input instanceof UploadedFile) { - $uploadFileName = $this->storageDir . DIRECTORY_SEPARATOR . date('YmdHis') . '_' . uniqid() . '_' . $input->getClientOriginalName(); + $uploadFileName = $this->storageDir.DIRECTORY_SEPARATOR.date('YmdHis').'_'.uniqid().'_'.$input->getClientOriginalName(); (new Filesystem())->dumpFile($uploadFileName, $input->getContent()); $input = $uploadFileName; - } return [new HttpProcessExecution($request->get('code'), $input, $request->get('context', []))]; } -} \ No newline at end of file +} diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 68c3e74..489f188 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -1,4 +1,5 @@ getConfigurations(), fn(ProcessConfiguration $cfg) => $cfg->isPublic()); + return array_filter($this->getConfigurations(), fn (ProcessConfiguration $cfg) => $cfg->isPublic()); } /** @return ProcessConfiguration[] */ public function getPrivateProcesses(): array { - return array_filter($this->getConfigurations(), fn(ProcessConfiguration $cfg) => !$cfg->isPublic()); + return array_filter($this->getConfigurations(), fn (ProcessConfiguration $cfg) => !$cfg->isPublic()); } public function getUiOptions(string $processCode): ?array @@ -49,13 +50,13 @@ private function resolveUiOptions(array $options): array 'entrypoint_type' => 'text', 'constraints' => [], 'run' => null, - 'default' => function(OptionsResolver $defaultResolver) { + 'default' => function (OptionsResolver $defaultResolver) { $defaultResolver->setDefault('input', null); - $defaultResolver->setDefault('context', function(OptionsResolver $contextResolver) { + $defaultResolver->setDefault('context', function (OptionsResolver $contextResolver) { $contextResolver->setPrototype(true); $contextResolver->setRequired(['key', 'value']); }); - } + }, ] ); $uiResolver->setDeprecated( diff --git a/src/Message/CronProcessMessage.php b/src/Message/CronProcessMessage.php index 6d8bc86..2a86db1 100644 --- a/src/Message/CronProcessMessage.php +++ b/src/Message/CronProcessMessage.php @@ -6,7 +6,7 @@ use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; -readonly final class CronProcessMessage +final readonly class CronProcessMessage { public function __construct(public ProcessSchedule $processSchedule) { diff --git a/src/Message/CronProcessMessageHandler.php b/src/Message/CronProcessMessageHandler.php index d4ab4f9..8f114cf 100644 --- a/src/Message/CronProcessMessageHandler.php +++ b/src/Message/CronProcessMessageHandler.php @@ -8,12 +8,12 @@ use Symfony\Component\Messenger\MessageBusInterface; #[AsMessageHandler] -readonly final class CronProcessMessageHandler +final readonly class CronProcessMessageHandler { public function __construct(private MessageBusInterface $bus) { - } + public function __invoke(CronProcessMessage $message): void { $schedule = $message->processSchedule; diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php index 3fe032f..9cfabc3 100644 --- a/src/Migrations/Version20231006111525.php +++ b/src/Migrations/Version20231006111525.php @@ -17,7 +17,7 @@ public function getDescription(): string public function up(Schema $schema): void { $platform = $this->connection->getDatabasePlatform()->getName(); - if ("sqlite" === $platform) { + if ('sqlite' === $platform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE TABLE log_record (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, process_execution_id INTEGER DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INTEGER NOT NULL, message VARCHAR(512) NOT NULL, context CLOB NOT NULL --(DC2Type:json) , created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) @@ -42,7 +42,7 @@ public function up(Schema $schema): void } } - if ("mysql" === $platform) { + if ('mysql' === $platform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE TABLE log_record (id INT AUTO_INCREMENT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL COMMENT \'(DC2Type:json)\', created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_8ECECC333DAC0075 (process_execution_id), INDEX idx_log_record_level (level), INDEX idx_log_record_created_at (created_at), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); } @@ -55,7 +55,7 @@ public function up(Schema $schema): void } } - if ("postgresql" === $platform) { + if ('postgresql' === $platform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE SEQUENCE log_record_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); $this->addSql('CREATE TABLE log_record (id INT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); @@ -79,8 +79,6 @@ public function up(Schema $schema): void $this->addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); } - - } } diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php index b3c9adf..1ddabe2 100644 --- a/src/Migrations/Version20240729151928.php +++ b/src/Migrations/Version20240729151928.php @@ -42,4 +42,3 @@ public function down(Schema $schema): void $this->addSql('DROP TABLE process_schedule'); } } - diff --git a/src/Migrations/Version20240730090403.php b/src/Migrations/Version20240730090403.php index 205f650..be4aeee 100644 --- a/src/Migrations/Version20240730090403.php +++ b/src/Migrations/Version20240730090403.php @@ -4,10 +4,6 @@ namespace CleverAge\ProcessUiBundle\Migrations; -use Doctrine\DBAL\Platforms\MariaDBPlatform; -use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Platforms\PostgreSQLPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php index c5e1ddf..5785598 100644 --- a/src/Migrations/Version20241007152613.php +++ b/src/Migrations/Version20241007152613.php @@ -28,7 +28,6 @@ public function down(Schema $schema): void { if ($schema->hasTable('process_execution') && $schema->getTable('process_execution')->hasColumn('context')) { $this->addSql('ALTER TABLE process_execution DROP context'); - } } } diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index b9e647d..e200dce 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -1,5 +1,7 @@ $exception->getMessage() + 'message' => $exception->getMessage(), ]; return new JsonResponse($data, Response::HTTP_UNAUTHORIZED); diff --git a/src/Twig/Runtime/LogLevelExtensionRuntime.php b/src/Twig/Runtime/LogLevelExtensionRuntime.php index bded8d2..aef2855 100644 --- a/src/Twig/Runtime/LogLevelExtensionRuntime.php +++ b/src/Twig/Runtime/LogLevelExtensionRuntime.php @@ -23,11 +23,11 @@ public function getCssClass(string|int $value): string Level::Debug->value, Level::Info->value => 'success', default => '' } - : match ($value) { - Level::Warning->name => 'warning', - Level::Error->name, Level::Emergency->name, Level::Critical->name, Level::Alert->name => 'danger', - Level::Debug->name, Level::Info->name => 'success', - default => '' - }; + : match ($value) { + Level::Warning->name => 'warning', + Level::Error->name, Level::Emergency->name, Level::Critical->name, Level::Alert->name => 'danger', + Level::Debug->name, Level::Info->name => 'success', + default => '' + }; } } diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 1ad0a7b..0f90ef5 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -14,8 +14,7 @@ public function __construct( private ProcessExecutionRepository $processExecutionRepository, private ProcessConfigurationsManager $processConfigurationsManager, - ) - { + ) { } public function getLastExecutionDate(string $code): ?ProcessExecution From 2080fe51d6777f58e99cb7a195541e313a76d7e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 9 Oct 2024 10:53:28 +0200 Subject: [PATCH 031/115] Fix locale set on logout user --- src/Controller/Admin/ProcessDashboardController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 41bfcd1..d2fe033 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -65,7 +65,7 @@ public function configureCrud(): Crud { /** @var User $user */ $user = $this->getUser(); - if (null !== $user->getLocale()) { + if (null !== $user?->getLocale()) { $this->localeSwitcher->setLocale($user->getLocale()); } From c567e7b0041cc5248993b6c2f650ecae82f5b6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 9 Oct 2024 14:28:49 +0200 Subject: [PATCH 032/115] Use default monolog config for process and doctrine handlers --- src/CleverAgeProcessUiBundle.php | 8 --- .../CleverAgeProcessUiExtension.php | 61 ++++++++++++++++++- .../Compiler/RegisterLogHandler.php | 34 ----------- .../Handler/DoctrineProcessHandler.php | 9 --- 4 files changed, 58 insertions(+), 54 deletions(-) delete mode 100644 src/DependencyInjection/Compiler/RegisterLogHandler.php diff --git a/src/CleverAgeProcessUiBundle.php b/src/CleverAgeProcessUiBundle.php index 90d6971..c3dcad2 100644 --- a/src/CleverAgeProcessUiBundle.php +++ b/src/CleverAgeProcessUiBundle.php @@ -4,18 +4,10 @@ namespace CleverAge\ProcessUiBundle; -use CleverAge\ProcessUiBundle\DependencyInjection\Compiler\RegisterLogHandler; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class CleverAgeProcessUiBundle extends Bundle { - public function build(ContainerBuilder $container): void - { - parent::build($container); - $container->addCompilerPass(new RegisterLogHandler()); - } - public function getPath(): string { return \dirname(__DIR__); diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index addd734..16ecfa6 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -10,6 +10,7 @@ use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; +use Monolog\Level; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; @@ -27,9 +28,6 @@ public function load(array $configs, ContainerBuilder $container): void $config = $this->processConfiguration($configuration, $configs); $container->getDefinition(UserCrudController::class) ->setArgument('$roles', array_combine($config['security']['roles'], $config['security']['roles'])); - $container->getDefinition(DoctrineProcessHandler::class) - ->addMethodCall('setEnabled', [$config['logs']['store_in_database']]) - ->addMethodCall('setLevel', [$config['logs']['database_level']]); $container->getDefinition(ProcessHandler::class) ->addMethodCall('setReportIncrementLevel', [$config['logs']['report_increment_level']]); $container->getDefinition(ProcessDashboardController::class) @@ -41,6 +39,63 @@ public function load(array $configs, ContainerBuilder $container): void */ public function prepend(ContainerBuilder $container): void { + $env = $container->getParameter("kernel.environment"); + $container->loadFromExtension( + 'monolog', + [ + 'handlers' => [ + 'pb_ui_file' => [ + 'type' => 'service', + 'id' => ProcessHandler::class + ], + 'pb_ui_orm' => [ + 'type' => 'service', + 'id' => DoctrineProcessHandler::class + ] + ] + ] + ); + if ("dev" === $env) { + $container->loadFromExtension( + 'monolog', + [ + 'handlers' => [ + 'pb_ui_file_filter' => [ + 'type' => 'filter', + 'min_level' => Level::Debug->name, + 'handler' => 'pb_ui_file', + 'channels' => ['cleverage_process', 'cleverage_process_task'] + ], + 'pb_ui_orm_filter' => [ + 'type' => 'filter', + 'min_level' => Level::Debug->name, + 'handler' => 'pb_ui_orm', + 'channels' => ["cleverage_process", "cleverage_process_task"] + ], + ] + ] + ); + } else { + $container->loadFromExtension( + 'monolog', + [ + 'handlers' => [ + 'pb_ui_file_filter' => [ + 'type' => 'filter', + 'min_level' => Level::Info->name, + 'handler' => 'pb_ui_file', + 'channels' => ['cleverage_process', 'cleverage_process_task'] + ], + 'pb_ui_orm_filter' => [ + 'type' => 'filter', + 'min_level' => Level::Info->name, + 'handler' => 'pb_ui_orm', + 'channels' => ["cleverage_process", "cleverage_process_task"] + ], + ] + ] + ); + } $container->loadFromExtension( 'doctrine_migrations', [ diff --git a/src/DependencyInjection/Compiler/RegisterLogHandler.php b/src/DependencyInjection/Compiler/RegisterLogHandler.php deleted file mode 100644 index a4c258d..0000000 --- a/src/DependencyInjection/Compiler/RegisterLogHandler.php +++ /dev/null @@ -1,34 +0,0 @@ -hasDefinition('monolog.logger')) { - return; - } - $loggers = [ - 'monolog.logger.cleverage_process', - 'monolog.logger.cleverage_process_task', - 'monolog.logger.cleverage_process_transformer', - ]; - foreach ($loggers as $logger) { - if ($container->has($logger)) { - $container - ->getDefinition($logger) - ->addMethodCall('pushHandler', [new Reference(ProcessHandler::class)]) - ->addMethodCall('pushHandler', [new Reference(DoctrineProcessHandler::class)]); - } - } - } -} diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index fee6318..d2159c1 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -18,7 +18,6 @@ class DoctrineProcessHandler extends AbstractProcessingHandler private ArrayCollection $records; private ?ProcessExecutionManager $processExecutionManager; private ?EntityManagerInterface $em = null; - private bool $enabled = false; public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) { @@ -38,11 +37,6 @@ public function setProcessExecutionManager(ProcessExecutionManager $processExecu $this->processExecutionManager = $processExecutionManager; } - public function setEnabled(bool $flag): void - { - $this->enabled = $flag; - } - public function __destruct() { $this->flush(); @@ -66,9 +60,6 @@ public function flush(): void protected function write(LogRecord $record): void { - if (false === $this->enabled) { - return; - } $this->records->add($record); if (500 === $this->records->count()) { $this->flush(); From 38d80eb104f0a99ed4e51eae2b2c8fdafd32eb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 16 Oct 2024 16:01:26 +0200 Subject: [PATCH 033/115] Fix on scheduler to set context --- src/Message/CronProcessMessageHandler.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Message/CronProcessMessageHandler.php b/src/Message/CronProcessMessageHandler.php index 8f114cf..868803e 100644 --- a/src/Message/CronProcessMessageHandler.php +++ b/src/Message/CronProcessMessageHandler.php @@ -17,8 +17,11 @@ public function __construct(private MessageBusInterface $bus) public function __invoke(CronProcessMessage $message): void { $schedule = $message->processSchedule; + $context = array_merge(...array_map(function($ctx) { + return [$ctx['key'] => $ctx['value']]; + }, $schedule->getContext())); $this->bus->dispatch( - new ProcessExecuteMessage($schedule->getProcess(), $schedule->getInput(), $message->processSchedule->getContext()) + new ProcessExecuteMessage($schedule->getProcess(), $schedule->getInput(), $context) ); } } From d9b127cc612a7dbdbbf3d975ce8029f6a27030a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 16 Oct 2024 16:01:52 +0200 Subject: [PATCH 034/115] Stop workers on scheduler updates --- src/EventListener/SchedulerStopWorkers.php | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/EventListener/SchedulerStopWorkers.php diff --git a/src/EventListener/SchedulerStopWorkers.php b/src/EventListener/SchedulerStopWorkers.php new file mode 100644 index 0000000..e41fda7 --- /dev/null +++ b/src/EventListener/SchedulerStopWorkers.php @@ -0,0 +1,33 @@ +kernel); + $application->setAutoExit(false); + $input = new ArrayInput(['command' => 'messenger:stop-workers']); + $output = new NullOutput(); + $application->run($input, $output); + } +} From 1ecdfa8cb742f79885701f0fd4d7c60a45d9883c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 23 Oct 2024 06:18:08 +0200 Subject: [PATCH 035/115] FIX - Process filter on log page --- src/Admin/Filter/LogProcessCodeFilter.php | 63 ------------------- src/Admin/Filter/LogProcessFilter.php | 52 +++++++++++++++ .../Admin/LogRecordCrudController.php | 11 ++-- .../Admin/ProcessExecutionCrudController.php | 2 +- src/EventListener/SchedulerStopWorkers.php | 33 ---------- 5 files changed, 59 insertions(+), 102 deletions(-) delete mode 100644 src/Admin/Filter/LogProcessCodeFilter.php create mode 100644 src/Admin/Filter/LogProcessFilter.php delete mode 100644 src/EventListener/SchedulerStopWorkers.php diff --git a/src/Admin/Filter/LogProcessCodeFilter.php b/src/Admin/Filter/LogProcessCodeFilter.php deleted file mode 100644 index e4af123..0000000 --- a/src/Admin/Filter/LogProcessCodeFilter.php +++ /dev/null @@ -1,63 +0,0 @@ -setFilterFqcn(__CLASS__) - ->setProperty('processExecution') - ->setLabel($label) - ->setFormType(ChoiceType::class); - } - - public function addChoices(ProcessConfigurationsManager $manager): self - { - $choices = $manager->getPublicProcesses(); - $choices = array_map(fn (ProcessConfiguration $cfg) => $cfg->getCode(), $choices); - $this->setFormTypeOption('choices', $choices); - - return $this; - } - - public function setCurrentProcessExecutionId(?int $currentProcessExecutionId): self - { - $this->currentProcessExecutionId = $currentProcessExecutionId; - if (0 !== $this->currentProcessExecutionId) { - $this->setFormTypeOption('disabled', true); - } - - return $this; - } - - public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, ?FieldDto $fieldDto, EntityDto $entityDto): void - { - $queryBuilder->join('entity.processExecution', 'pe'); - if (null !== $this->currentProcessExecutionId) { - $queryBuilder->andWhere($queryBuilder->expr()->eq('pe.id', ':id')); - $queryBuilder->setParameter('id', $this->currentProcessExecutionId); - - return; - } - $queryBuilder->where('pe.code IN (:codes)'); - $queryBuilder->setParameter('codes', $filterDataDto->getValue()); - } -} diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php new file mode 100644 index 0000000..bbb3099 --- /dev/null +++ b/src/Admin/Filter/LogProcessFilter.php @@ -0,0 +1,52 @@ + $executionId]; + } + + return (new self()) + ->setFilterFqcn(__CLASS__) + ->setProperty('process') + ->setLabel($label) + ->setFormType(ChoiceFilterType::class) + ->setFormTypeOption('value_type_options', ['choices' => $choices]) + ->setFormTypeOption('data', ['comparison' => ComparisonType::EQ, 'value' => $executionId]); + } + + public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, ?FieldDto $fieldDto, EntityDto $entityDto): void + { + $value = $filterDataDto->getValue(); + $queryBuilder->join('entity.processExecution', 'pe'); + if (is_numeric($value)) { + $queryBuilder->andWhere($queryBuilder->expr()->eq('pe.id', ':id')); + $queryBuilder->setParameter('id', $value); + + return; + } + $queryBuilder->where('pe.code IN (:codes)'); + $queryBuilder->setParameter('codes', $filterDataDto->getValue()); + } +} diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index f840c62..adf3b6f 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -4,8 +4,9 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessUiBundle\Admin\Field\LogLevelField; -use CleverAge\ProcessUiBundle\Admin\Filter\LogProcessCodeFilter; +use CleverAge\ProcessUiBundle\Admin\Filter\LogProcessFilter; use CleverAge\ProcessUiBundle\Entity\LogRecord; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; @@ -73,12 +74,12 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { - $id = $this->request->getMainRequest()->query->all('filters')['processExecution']['value'] ?? null; + $id = $this->request->getMainRequest()->query->all('filters')['process']['value'] ?? null; + $processList = $this->processConfigurationsManager->getPublicProcesses(); + $processList = array_map(fn (ProcessConfiguration $cfg) => $cfg->getCode(), $processList); return $filters->add( - LogProcessCodeFilter::new('process') - ->addChoices($this->processConfigurationsManager) - ->setCurrentProcessExecutionId((int) $id) + LogProcessFilter::new('process', $processList, $id) )->add( ChoiceFilter::new('level')->setChoices(array_combine(Level::NAMES, Level::VALUES)) )->add('message')->add('context')->add('createdAt'); diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index fad622f..c7eae3f 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -94,7 +94,7 @@ public function showLogs(AdminContext $adminContext): RedirectResponse ->set( 'filters', [ - 'processExecution' => [ + 'process' => [ 'comparison' => '=', 'value' => $this->getContext()->getEntity()->getInstance()->getId(), ], diff --git a/src/EventListener/SchedulerStopWorkers.php b/src/EventListener/SchedulerStopWorkers.php deleted file mode 100644 index e41fda7..0000000 --- a/src/EventListener/SchedulerStopWorkers.php +++ /dev/null @@ -1,33 +0,0 @@ -kernel); - $application->setAutoExit(false); - $input = new ArrayInput(['command' => 'messenger:stop-workers']); - $output = new NullOutput(); - $application->run($input, $output); - } -} From b0d8999eea2a04a317a69911ed44fb7c2b0e69c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Wed, 23 Oct 2024 08:46:36 +0200 Subject: [PATCH 036/115] Fix roles error --- src/DependencyInjection/Configuration.php | 2 +- src/Entity/User.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 57473bb..64ecaad 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -21,7 +21,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->arrayNode('security') ->addDefaultsIfNotSet() ->children() - ->scalarNode('roles')->defaultValue(['ROLE_ADMIN'])->end(); // Roles displayed inside user edit form + ->arrayNode('roles')->defaultValue(['ROLE_ADMIN'])->scalarPrototype()->end(); // Roles displayed inside user edit form $rootNode ->children() ->arrayNode('logs') diff --git a/src/Entity/User.php b/src/Entity/User.php index a65df93..6deb611 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -127,7 +127,7 @@ public function setLocale(?string $locale): self */ public function getRoles(): array { - return array_unique(['ROLE_USER'] + $this->roles); + return array_merge(['ROLE_USER'], $this->roles); } /** From a3d25875ef9ab04f02c75abc0d84be26fda9c112 Mon Sep 17 00:00:00 2001 From: Xavier Marchegay Date: Thu, 24 Oct 2024 09:25:37 +0200 Subject: [PATCH 037/115] Increase the length of the message of the LogRecord --- src/Controller/Admin/LogRecordCrudController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index adf3b6f..4170313 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -41,7 +41,7 @@ public function configureFields(string $pageName): iterable { return [ LogLevelField::new('level'), - TextField::new('message'), + TextField::new('message')->setMaxLength(512), DateTimeField::new('createdAt')->setFormat('Y/M/dd H:mm:ss'), ArrayField::new('context') ->setTemplatePath('@CleverAgeProcessUi/admin/field/array.html.twig') From f3801394c7a10cd89b95a95fa02fdbff74c04887 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 24 Oct 2024 16:47:55 +0200 Subject: [PATCH 038/115] #1 Update README. Add docs, CHANGELOG & CONTRIBUTING. --- CHANGELOG.md | 55 ++++++++++++++++++++ CONTRIBUTING.md | 52 +++++++++++++++++++ LICENSE | 21 ++++++++ README.md | 82 ++++++++---------------------- docs/index.md | 84 +++++++++++++++++++++++++++++++ docs/reference/tasks/_template.md | 44 ++++++++++++++++ 6 files changed, 278 insertions(+), 60 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 docs/index.md create mode 100644 docs/reference/tasks/_template.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1f309e8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +v2.0 +------ + +## BC breaks + +### Changes + +### Fixes + +v1.0.6 +------ + +### Fixes + +* Update ProcessExecutionCrudController.php. Avoid fatal error if no permission to display row + +v1.0.5 +------ + +### Fixes + +* [#1](https://github.com/cleverage/processuibundle/issues/1) fix fatal error + +v1.0.4 +------ + +### Changes + +* Only logs errors to level >= INFO + +v1.0.3 +------ + +### Changes + +* Add search fields to the ProcessExecution Crud + +v1.0.2 +------ + +### Fixes + +* Fix setSearchFields on ProcessCrudController + +v1.0.1 +------ + +### Changes + +* Php-cs-fixer & phpstan rules applying. Update README + +v1.0.0 +------ + +* Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d06b733 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,52 @@ +Contributing +============ + +First of all, **thank you** for contributing, **you are awesome**! + +Here are a few rules to follow in order to ease code reviews, and discussions before +maintainers accept and merge your work. + +You MUST run the quality & test suites. + +You SHOULD write (or update) unit tests. + +You SHOULD write documentation. + +Please, write [commit messages that make sense](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), +and [rebase your branch](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) before submitting your Pull Request. + +One may ask you to [squash your commits](https://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) +too. This is used to "clean" your Pull Request before merging it (we don't want +commits such as `fix tests`, `fix 2`, `fix 3`, etc.). + +Thank you! + +## Running the quality & test suites + +Tests suite uses Docker environments in order to be idempotent to OS's. More than this +PHP version is written inside the Dockerfile; this assures to test the bundle with +the same resources. No need to have PHP installed. + +You only need Docker set it up. + +To allow testing environments more smooth we implemented **Makefile**. +You have two commands available: + +```bash +make quality +``` + +```bash +make tests +``` + +## Deprecations notices + +When a feature should be deprecated, or when you have a breaking change for a future version, please : +* [Fill an issue](https://github.com/cleverage/ui-process-bundle/issues/new) +* Add TODO comments with the following format: `@TODO deprecated v2.0` +* Trigger a deprecation error: `@trigger_error('This feature will be deprecated in v2.0', E_USER_DEPRECATED);` + +You can check which deprecation notice is triggered in tests +* `make bash` +* `SYMFONY_DEPRECATIONS_HELPER=0 ./vendor/bin/phpunit` diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..045d824 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Clever-Age + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 475ceab..d65d342 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,22 @@ -![Code Style](https://github.com/cleverage/processuibundle/actions/workflows/super-linter.yml/badge.svg) ![Composer](https://github.com/cleverage/processuibundle/actions/workflows/php.yml/badge.svg) - -## CleverAge/ProcessUIBundle -A simple UX for cleverage/processbundle using EasyAdmin - -**Installation** -* Import routes -```yaml -#config/routes.yaml -process-ui: - resource: '@CleverAgeProcessUiBundle/Resources/config/routes.yaml' -``` -* Run doctrine migration -* Create an user using cleverage:process-ui:user-create console. - -Now you can access Process UI via http://your-domain.com/process - -**Indexing logs** - -You can index logs line into database to perform search on ****Process > History**** page. -See configuration section. - -When indexation is enabled you can perform it async. - -```yaml -#config/messenger.yaml -framework: - messenger: - transports: - log_index: 'doctrine://default' - - routing: - CleverAge\ProcessUiBundle\Message\LogIndexerMessage: log_index -``` - -Then you have to consume messages by running (use a supervisor to keep consumer alive) -``` -bin/console messenger:consume log_index --memory-limit=64M -``` - -See official symfony/messenger component documentations for more informations https://symfony.com/doc/current/messenger.html - -**Integrate CrudController** - -Of course you can integrate ProcessUI CRUD into your own easy admin Dashboard -```php - public function configureMenuItems(): iterable - { - /* ... your configuration */ - yield MenuItem::linkToCrud('History', null, ProcessExecution::class); - } -``` - -**Configuration** -```yaml -clever_age_process_ui: - index_logs: - enabled: false - level: ERROR #Minimum log level to index. Allowed values are DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY -``` +CleverAge/UiProcessBundle +======================= + +This bundle is a part of the [CleverAge/ProcessBundle](https://github.com/cleverage/process-bundle) project. +It provides a simple UX using [EasyAdmin](https://symfony.com/bundles/EasyAdminBundle/4.x/index.html) on Process bundle. + +Compatible with [Symfony stable version and latest Long-Term Support (LTS) release](https://symfony.com/releases). + +## Documentation + +For usage documentation, see: +[docs/index.md](docs/index.md) + +## Support & Contribution + +For general support and questions, please use [Github](https://github.com/cleverage/ui-process-bundle/issues). +If you think you found a bug or you have a feature idea to propose, feel free to open an issue after looking at the [contributing](CONTRIBUTING.md) guide. + +## License + +This bundle is under the MIT license. +For the whole copyright, see the [LICENSE](LICENSE) file distributed with this source code. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..0e45131 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,84 @@ +## Prerequisite + +CleverAge/ProcessBundle must be [installed](https://github.com/cleverage/process-bundle/blob/main/docs/01-quick_start.md#installation. + +## Installation + +Make sure Composer is installed globally, as explained in the [installation chapter](https://getcomposer.org/doc/00-intro.md) +of the Composer documentation. + +Open a command console, enter your project directory and install it using composer: + +```bash +composer require cleverage/ui-process-bundle +``` + +Remember to add the following line to config/bundles.php (not required if Symfony Flex is used) + +```php +CleverAge\UiProcessBundle\CleverAgeUiProcessBundle::class => ['all' => true], +``` + +## Import routes + +```yaml +#config/routes.yaml +ui-process: + resource: '@CleverAgeUiProcessBundle/Resources/config/routes.yaml' +``` +* Run doctrine migration +* Create an user using cleverage:ui-process:user-create console. + +Now you can access Process UI via http://your-domain.com/process + +## Indexing logs + +You can index logs line into database to perform search on ****Process > History**** page. +See configuration section. + +When indexation is enabled you can perform it async. + +```yaml +#config/messenger.yaml +framework: + messenger: + transports: + log_index: 'doctrine://default' + + routing: + CleverAge\UiProcessBundle\Message\LogIndexerMessage: log_index +``` + +Then you have to consume messages by running (use a supervisor to keep consumer alive) +``` +bin/console messenger:consume log_index --memory-limit=64M +``` + +See official `symfony/messenger` component documentations for more informations https://symfony.com/doc/current/messenger.html + +## Manual EasyAdmin integration + +### Integrate CrudController + +Of course, you can integrate UiProcess CRUD into your own easy admin Dashboard +```php + public function configureMenuItems(): iterable + { + /* ... your configuration */ + yield MenuItem::linkToCrud('History', null, ProcessExecution::class); + } +``` + +### Configuration + +```yaml +#config/cleverage_process_ui.yaml +cleverage_ui_process: + index_logs: + enabled: false + level: ERROR #Minimum log level to index. Allowed values are DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY +``` + +## Reference + +_TODO_ diff --git a/docs/reference/tasks/_template.md b/docs/reference/tasks/_template.md new file mode 100644 index 0000000..ed1d4a5 --- /dev/null +++ b/docs/reference/tasks/_template.md @@ -0,0 +1,44 @@ +TaskName +======== + +_Describe main goal an use cases of the task_ + +Task reference +-------------- + +* **Service**: `ClassName` + +Accepted inputs +--------------- + +_Description of allowed types_ + +Possible outputs +---------------- + +_Description of possible types_ + +Options +------- + +| Code | Type | Required | Default | Description | +| ---- | ---- | :------: | ------- | ----------- | +| `code` | `type` | **X** _or nothing_ | `default value` _if available_ | _description_ | + +Examples +-------- + +_YAML samples and explanations_ + +* Example 1 + - details + - details + +```yaml +# Task configuration level +code: + service: '@service_ref' + options: + a: 1 + b: 2 +``` From fb4e41b8c772bc0d1e812782627be541fa2e3648 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 14:23:25 +0100 Subject: [PATCH 039/115] #4 Update composer : "doctrine/*" using same versions of doctrine-process-bundle. "sensio/framework-extra-bundle", remove it and use php annotation as replacement. Remove "symfony/flex". Update require-dev using "process-bundle" standard. Reinstall "symfony/debug-pack". Reorder composer.yaml & add missing informations. Remove "scripts", "conflict" & "extra". Remove "symfony.lock" --- composer.json | 100 +++++----- symfony.lock | 512 -------------------------------------------------- 2 files changed, 46 insertions(+), 566 deletions(-) delete mode 100644 symfony.lock diff --git a/composer.json b/composer.json index 152db2c..4695d42 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,18 @@ { - "name": "cleverage/process-ui-bundle", + "name": "cleverage/ui-process-bundle", + "description": "UI for cleverage/process-bundle", + "keywords": [ + "process", + "task", + "etl", + "transformation", + "import", + "export", + "ui" + ], + "homepage": "https://github.com/cleverage/ui-process-bundle", "type": "symfony-bundle", "license": "MIT", - "description": "UI for cleverage/process-bundle", - "minimum-stability": "dev", - "prefer-stable": true, "authors": [ { "name": "Baudouin Douliery", @@ -22,11 +30,27 @@ "role": "Developer" } ], + "autoload": { + "psr-4": { + "CleverAge\\ProcessUiBundle\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "CleverAge\\ProcessUiBundle\\Tests\\": "tests/" + } + }, "require": { - "php": ">=8.0", + "php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", - "cleverage/process-bundle": "^3.2", + "cleverage/process-bundle": "dev-prepare-release", + "ddtraceweb/monolog-parser": "^1.3", + "doctrine/common": "^3.0", + "doctrine/dbal": "^2.9 || ^3.0", + "doctrine/doctrine-bundle": "^2.5", + "doctrine/doctrine-migrations-bundle": "^3.2", + "doctrine/orm": "^2.9 || ^3.0", "easycorp/easyadmin-bundle": "^4.0", "ddtraceweb/monolog-parser": "^1.3", "league/flysystem": "^2.2", @@ -56,60 +80,28 @@ }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^3.4", - "friendsofphp/php-cs-fixer": "^3.6", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1", - "phpstan/phpstan-doctrine": "^1.2", - "phpstan/phpstan-symfony": "^1.1", - "rector/rector": "^0.12.13", + "friendsofphp/php-cs-fixer": "*", + "phpstan/extension-installer": "*", + "phpstan/phpstan": "*", + "phpstan/phpstan-doctrine": "*", + "phpstan/phpstan-symfony": "*", + "phpunit/phpunit": "*", + "rector/rector": "*", "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6", - "symfony/dotenv": "^5.4", + "symfony/browser-kit": "^6.4|^7.1", + "symfony/css-selector": "^6.4|^7.1", + "symfony/debug-bundle": "^6.4|^7.1", "symfony/maker-bundle": "^1.31", - "symfony/web-profiler-bundle": "^5.4" + "symfony/monolog-bundle": "^3.0", + "symfony/phpunit-bridge": "^7.1", + "symfony/web-profiler-bundle": "^6.4|^7.1" }, "config": { - "optimize-autoloader": true, - "preferred-install": { - "*": "dist" - }, - "sort-packages": true, "allow-plugins": { - "composer/package-versions-deprecated": true, + "phpstan/extension-installer": true, "symfony/flex": true, - "symfony/runtime": true, - "phpstan/extension-installer": true - } - }, - "autoload": { - "psr-4": { - "CleverAge\\ProcessUiBundle\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "CleverAge\\ProcessUiBundle\\Tests\\": "tests/" - } - }, - "scripts": { - "auto-scripts": { - "cache:clear": "symfony-cmd", - "assets:install %PUBLIC_DIR%": "symfony-cmd" + "symfony/runtime": true }, - "post-install-cmd": [ - "@auto-scripts" - ], - "post-update-cmd": [ - "@auto-scripts" - ] - }, - "conflict": { - "symfony/symfony": "*" - }, - "extra": { - "symfony": { - "allow-contrib": false, - "require": "5.4.*" - } + "sort-packages": true } } diff --git a/symfony.lock b/symfony.lock deleted file mode 100644 index ea6af83..0000000 --- a/symfony.lock +++ /dev/null @@ -1,512 +0,0 @@ -{ - "cleverage/process-bundle": { - "version": "v3.2.3" - }, - "composer/package-versions-deprecated": { - "version": "1.11.99.2" - }, - "composer/semver": { - "version": "3.2.9" - }, - "composer/xdebug-handler": { - "version": "2.0.1" - }, - "doctrine/annotations": { - "version": "1.0", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "1.0", - "ref": "a2759dd6123694c8d901d0ec80006e044c2e6457" - }, - "files": [ - "config/routes/annotations.yaml" - ] - }, - "doctrine/cache": { - "version": "2.0.3" - }, - "doctrine/collections": { - "version": "1.6.7" - }, - "doctrine/common": { - "version": "3.1.2" - }, - "doctrine/data-fixtures": { - "version": "1.5.0" - }, - "doctrine/dbal": { - "version": "2.13.x-dev" - }, - "doctrine/deprecations": { - "version": "v0.5.3" - }, - "doctrine/doctrine-bundle": { - "version": "2.4", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "2.4", - "ref": "dda18c8830b143bc31c0e0457fb13b9029614d76" - }, - "files": [ - "config/packages/doctrine.yaml", - "config/packages/prod/doctrine.yaml", - "config/packages/test/doctrine.yaml", - "src/Entity/.gitignore", - "src/Repository/.gitignore" - ] - }, - "doctrine/doctrine-fixtures-bundle": { - "version": "3.0", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.0", - "ref": "e5b542d4ef47d8a003c91beb35650c76907f7e53" - }, - "files": [ - "src/DataFixtures/AppFixtures.php" - ] - }, - "doctrine/doctrine-migrations-bundle": { - "version": "3.1", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.1", - "ref": "ee609429c9ee23e22d6fa5728211768f51ed2818" - }, - "files": [ - "config/packages/doctrine_migrations.yaml", - "migrations/.gitignore" - ] - }, - "doctrine/event-manager": { - "version": "1.1.1" - }, - "doctrine/inflector": { - "version": "2.0.3" - }, - "doctrine/instantiator": { - "version": "1.4.0" - }, - "doctrine/lexer": { - "version": "1.2.1" - }, - "doctrine/migrations": { - "version": "3.1.3" - }, - "doctrine/orm": { - "version": "2.9.2" - }, - "doctrine/persistence": { - "version": "2.2.1" - }, - "doctrine/sql-formatter": { - "version": "1.1.1" - }, - "friendsofphp/php-cs-fixer": { - "version": "3.6", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.0", - "ref": "be2103eb4a20942e28a6dd87736669b757132435" - }, - "files": [ - ".php-cs-fixer.dist.php" - ] - }, - "friendsofphp/proxy-manager-lts": { - "version": "v1.0.5" - }, - "laminas/laminas-code": { - "version": "4.3.0" - }, - "laminas/laminas-eventmanager": { - "version": "3.3.1" - }, - "laminas/laminas-zendframework-bridge": { - "version": "1.2.0" - }, - "monolog/monolog": { - "version": "2.2.0" - }, - "nikic/php-parser": { - "version": "v4.10.5" - }, - "php-cs-fixer/diff": { - "version": "v2.0.2" - }, - "phpstan/extension-installer": { - "version": "1.1.0" - }, - "phpstan/phpstan": { - "version": "0.12.89" - }, - "phpstan/phpstan-doctrine": { - "version": "1.2.10" - }, - "phpstan/phpstan-symfony": { - "version": "1.1.5" - }, - "psr/cache": { - "version": "1.0.1" - }, - "psr/container": { - "version": "1.1.1" - }, - "psr/event-dispatcher": { - "version": "1.0.0" - }, - "psr/log": { - "version": "1.1.4" - }, - "rector/rector": { - "version": "0.12.13" - }, - "roave/security-advisories": { - "version": "dev-latest" - }, - "sensio/framework-extra-bundle": { - "version": "5.2", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.2", - "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" - }, - "files": [ - "config/packages/sensio_framework_extra.yaml" - ] - }, - "squizlabs/php_codesniffer": { - "version": "3.6", - "recipe": { - "repo": "github.com/symfony/recipes-contrib", - "branch": "master", - "version": "3.6", - "ref": "1019e5c08d4821cb9b77f4891f8e9c31ff20ac6f" - }, - "files": [ - "phpcs.xml.dist" - ] - }, - "symfony/asset": { - "version": "v5.3.0" - }, - "symfony/cache": { - "version": "v5.3.0" - }, - "symfony/cache-contracts": { - "version": "v2.4.0" - }, - "symfony/config": { - "version": "v5.3.0" - }, - "symfony/console": { - "version": "5.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.3", - "ref": "da0c8be8157600ad34f10ff0c9cc91232522e047" - }, - "files": [ - "bin/console" - ] - }, - "symfony/dependency-injection": { - "version": "v5.3.0" - }, - "symfony/deprecation-contracts": { - "version": "v2.4.0" - }, - "symfony/doctrine-bridge": { - "version": "v5.3.1" - }, - "symfony/dotenv": { - "version": "v5.3.0" - }, - "symfony/error-handler": { - "version": "v5.3.0" - }, - "symfony/event-dispatcher": { - "version": "v5.3.0" - }, - "symfony/event-dispatcher-contracts": { - "version": "v2.4.0" - }, - "symfony/expression-language": { - "version": "v5.3.0" - }, - "symfony/filesystem": { - "version": "v5.3.0" - }, - "symfony/finder": { - "version": "v5.3.0" - }, - "symfony/flex": { - "version": "1.0", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "1.0", - "ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e" - }, - "files": [ - ".env" - ] - }, - "symfony/form": { - "version": "v5.3.3" - }, - "symfony/framework-bundle": { - "version": "5.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.3", - "ref": "772b77cfb5017644547ef7f9364c54e4eb9a6c61" - }, - "files": [ - "config/packages/cache.yaml", - "config/packages/framework.yaml", - "config/preload.php", - "config/routes/framework.yaml", - "config/services.yaml", - "public/index.php", - "src/Controller/.gitignore", - "src/Kernel.php" - ] - }, - "symfony/http-client-contracts": { - "version": "v2.4.0" - }, - "symfony/http-foundation": { - "version": "v5.3.1" - }, - "symfony/http-kernel": { - "version": "v5.3.1" - }, - "symfony/intl": { - "version": "v5.3.4" - }, - "symfony/maker-bundle": { - "version": "1.0", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "1.0", - "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" - } - }, - "symfony/mime": { - "version": "v5.3.2" - }, - "symfony/monolog-bridge": { - "version": "v5.3.0" - }, - "symfony/monolog-bundle": { - "version": "3.7", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.7", - "ref": "329f6a5ef2e7aa033f802be833ef8d1268dd0848" - }, - "files": [ - "config/packages/dev/monolog.yaml", - "config/packages/prod/deprecations.yaml", - "config/packages/prod/monolog.yaml", - "config/packages/test/monolog.yaml" - ] - }, - "symfony/options-resolver": { - "version": "v5.3.0" - }, - "symfony/orm-pack": { - "version": "v2.1.0" - }, - "symfony/password-hasher": { - "version": "v5.3.0" - }, - "symfony/polyfill-intl-grapheme": { - "version": "v1.23.0" - }, - "symfony/polyfill-intl-icu": { - "version": "v1.23.0" - }, - "symfony/polyfill-intl-idn": { - "version": "v1.23.0" - }, - "symfony/polyfill-intl-normalizer": { - "version": "v1.23.0" - }, - "symfony/polyfill-mbstring": { - "version": "v1.23.0" - }, - "symfony/polyfill-php73": { - "version": "v1.23.0" - }, - "symfony/polyfill-php80": { - "version": "v1.23.0" - }, - "symfony/polyfill-php81": { - "version": "v1.23.0" - }, - "symfony/process": { - "version": "v5.3.0" - }, - "symfony/profiler-pack": { - "version": "v1.0.5" - }, - "symfony/property-access": { - "version": "v5.3.0" - }, - "symfony/property-info": { - "version": "v5.3.1" - }, - "symfony/proxy-manager-bridge": { - "version": "v5.3.0" - }, - "symfony/routing": { - "version": "5.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.3", - "ref": "2d706bd8c6a9e6730343bb22092dabba1f42f4f3" - }, - "files": [ - "config/packages/routing.yaml", - "config/routes.yaml" - ] - }, - "symfony/runtime": { - "version": "v5.3.0" - }, - "symfony/security-bundle": { - "version": "5.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.3", - "ref": "8b35bfc00a7716db4ca5a764a4b338476ca3a704" - }, - "files": [ - "config/packages/security.yaml" - ] - }, - "symfony/security-core": { - "version": "v5.3.1" - }, - "symfony/security-csrf": { - "version": "v5.3.0" - }, - "symfony/security-guard": { - "version": "v5.3.0" - }, - "symfony/security-http": { - "version": "v5.3.1" - }, - "symfony/serializer": { - "version": "v5.3.1" - }, - "symfony/service-contracts": { - "version": "v2.4.0" - }, - "symfony/stopwatch": { - "version": "v5.3.0" - }, - "symfony/string": { - "version": "v5.3.0" - }, - "symfony/translation-contracts": { - "version": "v2.4.0" - }, - "symfony/twig-bridge": { - "version": "v5.3.0" - }, - "symfony/twig-bundle": { - "version": "5.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "5.3", - "ref": "b416645602504d22d15912e0918001e6d71bb9fa" - }, - "files": [ - "config/packages/twig.yaml", - "templates/base.html.twig" - ] - }, - "symfony/validator": { - "version": "4.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "4.3", - "ref": "d902da3e4952f18d3bf05aab29512eb61cabd869" - }, - "files": [ - "config/packages/test/validator.yaml", - "config/packages/validator.yaml" - ] - }, - "symfony/var-dumper": { - "version": "v5.3.0" - }, - "symfony/var-exporter": { - "version": "v5.3.0" - }, - "symfony/web-profiler-bundle": { - "version": "3.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.3", - "ref": "6bdfa1a95f6b2e677ab985cd1af2eae35d62e0f6" - }, - "files": [ - "config/packages/dev/web_profiler.yaml", - "config/packages/test/web_profiler.yaml", - "config/routes/dev/web_profiler.yaml" - ] - }, - "symfony/webpack-encore-bundle": { - "version": "1.9", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "1.9", - "ref": "9399a0bfc6ee7a0c019f952bca46d6a6045dd451" - }, - "files": [ - "assets/app.js", - "assets/bootstrap.js", - "assets/controllers.json", - "assets/controllers/hello_controller.js", - "assets/styles/app.css", - "config/packages/assets.yaml", - "config/packages/prod/webpack_encore.yaml", - "config/packages/test/webpack_encore.yaml", - "config/packages/webpack_encore.yaml", - "package.json", - "webpack.config.js" - ] - }, - "symfony/yaml": { - "version": "v5.3.0" - }, - "twig/extra-bundle": { - "version": "v3.3.1" - }, - "twig/intl-extra": { - "version": "v3.3.0" - }, - "twig/twig": { - "version": "v3.3.2" - } -} From da70ea170004b6333bc44bdd59d6e7ca97bea416 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 14:25:16 +0100 Subject: [PATCH 040/115] #4 "symfony/*" from ^5.4 to ^6.4|^7.1 => Update changes on code. "league/flysystem-bundle" from ^2.2 to ^3.0" (same as flysystem-process-bundle). twig/extra-bundle" and "twig/intl-extra" to ^3.8 --- composer.json | 39 +++++++------------ src/Command/PurgeProcessExecution.php | 4 +- src/Command/UserCreateCommand.php | 11 +----- src/Controller/Crud/ProcessCrudController.php | 25 +++++------- src/Controller/SecurityController.php | 6 +-- src/Message/LogIndexerHandler.php | 5 ++- src/Message/ProcessRunHandler.php | 9 +++-- src/Repository/UserRepository.php | 9 ++--- src/Security/LoginFormAuthAuthenticator.php | 7 ++-- tests/.gitkeep | 0 10 files changed, 45 insertions(+), 70 deletions(-) create mode 100644 tests/.gitkeep diff --git a/composer.json b/composer.json index 4695d42..8486f2c 100644 --- a/composer.json +++ b/composer.json @@ -52,31 +52,22 @@ "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.9 || ^3.0", "easycorp/easyadmin-bundle": "^4.0", - "ddtraceweb/monolog-parser": "^1.3", - "league/flysystem": "^2.2", - "composer/package-versions-deprecated": "^1.11", - "doctrine/doctrine-bundle": "^2.4", - "doctrine/doctrine-migrations-bundle": "^3.1", - "doctrine/orm": "^2.9", - "sensio/framework-extra-bundle": "^6.1", - "symfony/console": "^5.4", - "symfony/messenger": "^5.4", - "symfony/doctrine-messenger": "^5.4", - "symfony/filesystem": "^5.4", - "symfony/flex": "^1.3.1", - "symfony/form": "^5.4", - "symfony/framework-bundle": "^5.4", - "symfony/mime": "^5.4", - "symfony/proxy-manager-bridge": "^5.4", - "symfony/runtime": "^5.4", - "symfony/security-bundle": "^5.4", - "symfony/stopwatch": "^5.4", - "symfony/twig-bundle": "^5.4", - "symfony/validator": "^5.4", + "league/flysystem": "^3.0", + "symfony/doctrine-messenger": "^6.4|^7.1", + "symfony/filesystem": "^6.4|^7.1", + "symfony/form": "^6.4|^7.1", + "symfony/framework-bundle": "^6.4|^7.1", + "symfony/messenger": "^6.4|^7.1", + "symfony/mime": "^6.4|^7.1", + "symfony/runtime": "^6.4|^7.1", + "symfony/security-bundle": "^6.4|^7.1", + "symfony/stopwatch": "^6.4|^7.1", + "symfony/twig-bundle": "^6.4|^7.1", + "symfony/validator": "^6.4|^7.1", "symfony/webpack-encore-bundle": "^1.11", - "symfony/yaml": "^5.4", - "twig/extra-bundle": "^2.12|^3.0", - "twig/intl-extra": "^3.3" + "symfony/yaml": "^6.4|^7.1", + "twig/extra-bundle": "^3.8", + "twig/intl-extra": "^3.8" }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^3.4", diff --git a/src/Command/PurgeProcessExecution.php b/src/Command/PurgeProcessExecution.php index ba4e480..24013da 100644 --- a/src/Command/PurgeProcessExecution.php +++ b/src/Command/PurgeProcessExecution.php @@ -8,6 +8,7 @@ use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; use DateTimeInterface; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; @@ -16,6 +17,7 @@ use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; +#[AsCommand(name: 'cleverage:process-ui:purge', description: 'Purge process_execution table.')] class PurgeProcessExecution extends Command { private ManagerRegistry $managerRegistry; @@ -39,8 +41,6 @@ public function setProcessLogDir(string $processLogDir): void protected function configure(): void { - $this->setName('cleverage:process-ui:purge'); - $this->setDescription('Purge process_execution table.'); $this->setDefinition( new InputDefinition([ new InputOption( diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index adeb90f..98e19af 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -6,6 +6,7 @@ use CleverAge\ProcessUiBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -16,9 +17,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Validator\ValidatorInterface; -/** - * Class UserCreateCommand. - */ +#[AsCommand(name: 'cleverage:process-ui:user-create', description: 'Command to create a new admin into database for process ui.')] final class UserCreateCommand extends Command { private ValidatorInterface $validator; @@ -36,12 +35,6 @@ public function __construct( parent::__construct(); } - protected function configure(): void - { - $this->setName('cleverage:process-ui:user-create'); - $this->setDescription('Command to create a new admin into database for process ui.'); - } - protected function execute(InputInterface $input, OutputInterface $output): int { $style = new SymfonyStyle($input, $output); diff --git a/src/Controller/Crud/ProcessCrudController.php b/src/Controller/Crud/ProcessCrudController.php index ee17c4b..592d50c 100644 --- a/src/Controller/Crud/ProcessCrudController.php +++ b/src/Controller/Crud/ProcessCrudController.php @@ -21,17 +21,15 @@ use Exception; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Messenger\MessageBusInterface; class ProcessCrudController extends AbstractCrudController { - private ProcessUiConfigurationManager $processUiConfigurationManager; - - /** - * @required - */ - public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void - { - $this->processUiConfigurationManager = $processUiConfigurationManager; + public function __construct( + private ProcessUiConfigurationManager $processUiConfigurationManager, + private AdminUrlGenerator $adminUrlGenerator, + private MessageBusInterface $messageBus, + ) { } public static function getEntityFqcn(): string @@ -100,7 +98,7 @@ public function runProcessAction(AdminContext $context): Response ); } else { $message = new ProcessRunMessage($process->getProcessCode()); - $this->dispatchMessage($message); + $this->messageBus->dispatch($message); $this->addFlash( 'success', 'Process has been added to queue. It will start as soon as possible' @@ -110,23 +108,18 @@ public function runProcessAction(AdminContext $context): Response $this->addFlash('warning', 'Cannot run process.'); } - /** @var AdminUrlGenerator $routeBuilder */ - $routeBuilder = $this->get(AdminUrlGenerator::class); - return $this->redirect( - $routeBuilder->setController(__CLASS__)->setAction(Action::INDEX)->generateUrl() + $this->adminUrlGenerator->setController(__CLASS__)->setAction(Action::INDEX)->generateUrl() ); } public function viewHistoryAction(AdminContext $adminContext): RedirectResponse { - /** @var AdminUrlGenerator $routeBuilder */ - $routeBuilder = $this->get(AdminUrlGenerator::class); /** @var Process $process */ $process = $adminContext->getEntity()->getInstance(); return $this->redirect( - $routeBuilder + $this->adminUrlGenerator ->setController(ProcessExecutionCrudController::class) ->setEntityId(null) ->setAction(Action::INDEX) diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index 2c7c54f..4879dce 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -15,7 +15,7 @@ class SecurityController extends AbstractController public function login(AuthenticationUtils $authenticationUtils): Response { if ($this->getUser()) { - return $this->redirectToRoute('/'); + return $this->redirectToRoute('process_admin'); } // get the login error if there is one @@ -34,9 +34,7 @@ public function login(AuthenticationUtils $authenticationUtils): Response ]); } - /** - * @Route("/logout", name="app_logout") - */ + #[Route('/logout', name: 'app_logout')] public function logout(): void { throw new \LogicException( diff --git a/src/Message/LogIndexerHandler.php b/src/Message/LogIndexerHandler.php index deced04..c591e70 100644 --- a/src/Message/LogIndexerHandler.php +++ b/src/Message/LogIndexerHandler.php @@ -9,9 +9,10 @@ use Doctrine\Persistence\ManagerRegistry; use Dubture\Monolog\Parser\LineLogParser; use Monolog\Logger; -use Symfony\Component\Messenger\Handler\MessageHandlerInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; -class LogIndexerHandler implements MessageHandlerInterface +#[AsMessageHandler] +class LogIndexerHandler { public const INDEX_LOG_RECORD = 'index_log_record'; private ManagerRegistry $managerRegistry; diff --git a/src/Message/ProcessRunHandler.php b/src/Message/ProcessRunHandler.php index f9e46b9..30ae3dd 100644 --- a/src/Message/ProcessRunHandler.php +++ b/src/Message/ProcessRunHandler.php @@ -5,12 +5,13 @@ namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessBundle\Command\ExecuteProcessCommand; -use Exception; +use Symfony\Component\Console\Exception\ExceptionInterface; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Messenger\Handler\MessageHandlerInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; -class ProcessRunHandler implements MessageHandlerInterface +#[AsMessageHandler] +class ProcessRunHandler { private ExecuteProcessCommand $command; @@ -20,7 +21,7 @@ public function __construct(ExecuteProcessCommand $command) } /** - * @throws Exception + * @throws ExceptionInterface */ public function __invoke(ProcessRunMessage $processRunMessage): void { diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index e03ffa9..83294b9 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -24,14 +24,13 @@ public function __construct(ManagerRegistry $registry) /** * Used to upgrade (rehash) the user's password automatically over time. */ - public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newEncodedPassword): void + public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void { if (!$user instanceof User) { throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); } - - $user->setPassword($newEncodedPassword); - $this->_em->persist($user); - $this->_em->flush(); + $user->setPassword($newHashedPassword); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); } } diff --git a/src/Security/LoginFormAuthAuthenticator.php b/src/Security/LoginFormAuthAuthenticator.php index fc08421..cc2c7b7 100644 --- a/src/Security/LoginFormAuthAuthenticator.php +++ b/src/Security/LoginFormAuthAuthenticator.php @@ -9,13 +9,12 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\SecurityRequestAttributes; use Symfony\Component\Security\Http\Util\TargetPathTrait; class LoginFormAuthAuthenticator extends AbstractLoginFormAuthenticator @@ -31,11 +30,11 @@ public function __construct(UrlGeneratorInterface $urlGenerator) $this->urlGenerator = $urlGenerator; } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { $username = (string) $request->request->get('email', ''); - $request->getSession()->set(Security::LAST_USERNAME, $username); + $request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $username); return new Passport( new UserBadge($username), diff --git a/tests/.gitkeep b/tests/.gitkeep new file mode 100644 index 0000000..e69de29 From 74dd8938942ff97a3f503e433930e2da11d43398 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 14:27:47 +0100 Subject: [PATCH 041/115] #1 Add Makefile & .docker for local standalone usage. Add rector, phpstan & php-cs-fixer configurations. Remove phpcs configuration. --- .docker/compose.yaml | 14 +++++++++ .docker/php/Dockerfile | 29 +++++++++++++++++++ .docker/php/conf.d/dev.ini | 5 ++++ .gitignore | 44 ++++++++++++++++------------ .php-cs-fixer.dist.php | 59 ++++++++++++++++++++++++-------------- Makefile | 54 ++++++++++++++++++++++++++++++++++ phpcs.xml.dist | 19 ------------ phpstan.neon | 28 ++++++++++++------ phpunit.xml.dist | 27 +++++++++++++++++ rector.php | 30 +++++++++++++++++++ 10 files changed, 240 insertions(+), 69 deletions(-) create mode 100644 .docker/compose.yaml create mode 100644 .docker/php/Dockerfile create mode 100644 .docker/php/conf.d/dev.ini create mode 100644 Makefile delete mode 100644 phpcs.xml.dist create mode 100644 phpunit.xml.dist create mode 100644 rector.php diff --git a/.docker/compose.yaml b/.docker/compose.yaml new file mode 100644 index 0000000..fbb442b --- /dev/null +++ b/.docker/compose.yaml @@ -0,0 +1,14 @@ +x-build-args: &build-args + UID: "${UID:-1000}" + GID: "${GID:-1000}" + +name: cleverage-ui-process-bundle + +services: + php: + build: + context: php + args: + <<: *build-args + volumes: + - ../:/var/www diff --git a/.docker/php/Dockerfile b/.docker/php/Dockerfile new file mode 100644 index 0000000..f98c3ba --- /dev/null +++ b/.docker/php/Dockerfile @@ -0,0 +1,29 @@ +FROM php:8.2-fpm-alpine + +ARG UID +ARG GID + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" +COPY /conf.d/ "$PHP_INI_DIR/conf.d/" + +RUN apk update && apk add \ + tzdata \ + shadow \ + nano \ + bash \ + icu-dev \ + && docker-php-ext-configure intl \ + && docker-php-ext-install intl opcache \ + && docker-php-ext-enable opcache + +RUN ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime \ + && sed -i "s/^;date.timezone =.*/date.timezone = Europe\/Paris/" $PHP_INI_DIR/php.ini + +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + +RUN usermod -u $UID www-data \ + && groupmod -g $GID www-data + +USER www-data:www-data + +WORKDIR /var/www diff --git a/.docker/php/conf.d/dev.ini b/.docker/php/conf.d/dev.ini new file mode 100644 index 0000000..2a141be --- /dev/null +++ b/.docker/php/conf.d/dev.ini @@ -0,0 +1,5 @@ +display_errors = 1 +error_reporting = E_ALL + +opcache.validate_timestamps = 1 +opcache.revalidate_freq = 0 diff --git a/.gitignore b/.gitignore index 60f5bb4..b13d896 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,37 @@ +/composer.lock +/vendor +.env +.idea +/phpunit.xml +.phpunit.result.cache +.phpunit.cache +.php-cs-fixer.cache +coverage-report + +###> phpunit/phpunit ### +/phpunit.xml +.phpunit.result.cache +###< phpunit/phpunit ### + +###> symfony/phpunit-bridge ### +.phpunit.result.cache +/phpunit.xml +###< symfony/phpunit-bridge ### + ###> symfony/framework-bundle ### -/.env /.env.local /.env.local.php -/.env.test /.env.*.local /config/secrets/prod/prod.decrypt.private.php /public/bundles/ /var/ /vendor/ ###< symfony/framework-bundle ### -###> custom ### -/docker-compose.override.yml -/.idea -/.pdepend -/.composer/cache -###< custom ### + +###> friendsofphp/php-cs-fixer ### +/.php-cs-fixer.php +/.php-cs-fixer.cache +###< friendsofphp/php-cs-fixer ### ###> symfony/webpack-encore-bundle ### /node_modules/ @@ -22,14 +39,3 @@ npm-debug.log yarn-error.log ###< symfony/webpack-encore-bundle ### - -###> squizlabs/php_codesniffer ### -/.phpcs-cache -/phpcs.xml -/.php-cs-fixer.cache -###< squizlabs/php_codesniffer ### - -###> friendsofphp/php-cs-fixer ### -/.php-cs-fixer.php -/.php-cs-fixer.cache -###< friendsofphp/php-cs-fixer ### diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 0fd58f8..e910756 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -1,31 +1,46 @@ in(__DIR__.'/src') - ->ignoreDotFiles(true) - ->ignoreVCS(true) - ->exclude(['build', 'vendor']) - ->files() - ->name('*.php') -; +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ -$config = new PhpCsFixer\Config(); +if (!file_exists(__DIR__.'/src')) { + exit(0); +} -return $config - ->setUsingCache(true) - ->setRiskyAllowed(true) - ->setFinder($finder) +$fileHeaderComment = <<<'EOF' + This file is part of the CleverAge/UiProcessBundle package. + + Copyright (c) Clever-Age + + For the full copyright and license information, please view the LICENSE + file that was distributed with this source code. + EOF; + +return (new PhpCsFixer\Config()) ->setRules([ - '@PHP80Migration' => true, - '@PHP80Migration:risky' => true, + '@PHP71Migration' => true, + '@PHP82Migration' => true, + '@PHPUnit75Migration:risky' => true, '@Symfony' => true, '@Symfony:risky' => true, - 'array_syntax' => ['syntax' => 'short'], - 'fopen_flags' => false, - 'ordered_imports' => true, 'protected_to_private' => false, - 'single_line_throw' => false, - // this must be disabled because the output of some tests include NBSP characters - 'non_printable_character' => false, + 'native_constant_invocation' => ['strict' => false], + 'header_comment' => ['header' => $fileHeaderComment], + 'modernize_strpos' => true, + 'get_class_to_class_keyword' => true, ]) - ; + ->setRiskyAllowed(true) + ->setFinder( + (new PhpCsFixer\Finder()) + ->in(__DIR__.'/src') + ->in(__DIR__.'/tests') + ->append([__FILE__]) + ) + ->setCacheFile('.php-cs-fixer.cache') +; diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0a58e32 --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +.ONESHELL: +SHELL := /bin/bash + +DOCKER_RUN_PHP = docker compose -f .docker/compose.yaml run --rm php "bash" "-c" +DOCKER_COMPOSE = docker compose -f .docker/compose.yaml + +start: upd #[Global] Start application + +src/vendor: #[Composer] install dependencies + $(DOCKER_RUN_PHP) "composer install --no-interaction" + +upd: #[Docker] Start containers detached + touch .docker/.env + make src/vendor + $(DOCKER_COMPOSE) up --remove-orphans --detach + +up: #[Docker] Start containers + touch .docker/.env + make src/vendor + $(DOCKER_COMPOSE) up --remove-orphans + +stop: #[Docker] Down containers + $(DOCKER_COMPOSE) stop + +down: #[Docker] Down containers + $(DOCKER_COMPOSE) down + +build: #[Docker] Build containers + $(DOCKER_COMPOSE) build + +ps: # [Docker] Show running containers + $(DOCKER_COMPOSE) ps + +bash: #[Docker] Connect to php container with current host user + $(DOCKER_COMPOSE) exec php bash + +logs: #[Docker] Show logs + $(DOCKER_COMPOSE) logs -f + +quality: phpstan php-cs-fixer rector #[Quality] Run all quality checks + +phpstan: #[Quality] Run PHPStan + $(DOCKER_RUN_PHP) "vendor/bin/phpstan --no-progress --memory-limit=1G analyse" + +php-cs-fixer: #[Quality] Run PHP-CS-Fixer + $(DOCKER_RUN_PHP) "vendor/bin/php-cs-fixer fix --diff --verbose" + +rector: #[Quality] Run Rector + $(DOCKER_RUN_PHP) "vendor/bin/rector" + +tests: phpunit #[Tests] Run all tests + +phpunit: #[Tests] Run PHPUnit + $(DOCKER_RUN_PHP) "vendor/bin/phpunit" diff --git a/phpcs.xml.dist b/phpcs.xml.dist deleted file mode 100644 index 89195e2..0000000 --- a/phpcs.xml.dist +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - bin/ - config/ - public/ - src/ - tests/ - - diff --git a/phpstan.neon b/phpstan.neon index 648f580..8f1e7db 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,10 +1,20 @@ parameters: - level: 8 - paths: - - src - excludePaths: - - src/DependencyInjection/Configuration.php - ignoreErrors: - - '#is never written, only read#' - - '#has no value type specified in iterable type#' - - '#has parameter .* with no value type specified in iterable type#' \ No newline at end of file + level: 8 + paths: + - src + - tests + excludePaths: + - src/DependencyInjection/Configuration.php + ignoreErrors: + - '#type has no value type specified in iterable type#' + - '#has parameter .* with no value type specified in iterable type#' + - '#has no value type specified in iterable type array#' + - '#configureOptions\(\) has no return type specified.#' + - '#configure\(\) has no return type specified#' + - '#process\(\) has no return type specified#' + - '#should return Iterator but returns Traversable#' + - '#Negated boolean expression is always false#' + checkGenericClassInNonGenericObjectType: false + reportUnmatchedIgnoredErrors: false + inferPrivatePropertyTypeFromConstructor: true + treatPhpDocTypesAsCertain: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..766495c --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,27 @@ + + + + + tests + + + + + + src + + + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..72a2408 --- /dev/null +++ b/rector.php @@ -0,0 +1,30 @@ +withPhpVersion(PhpVersion::PHP_82) + ->withPaths([ + __DIR__.'/src', + __DIR__.'/tests', + ]) + ->withPhpSets(php82: true) + // here we can define, what prepared sets of rules will be applied + ->withPreparedSets( + deadCode: true, + codeQuality: true + ) + ->withSets([ + LevelSetList::UP_TO_PHP_82, + SymfonySetList::SYMFONY_64, + SymfonySetList::SYMFONY_71, + SymfonySetList::SYMFONY_CODE_QUALITY, + SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, + SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES, + ]) +; From 652bd17c9ebd85aef8df873f672c939daf87e548 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 14:30:54 +0100 Subject: [PATCH 042/115] #1 Add notifications, quality & test github workflows. Remove super-linter workflow, replaced by quality one. --- .github/ISSUE_TEMPLATE.md | 14 ++++++ .github/PULL_REQUEST_TEMPLATE.md | 14 ++++++ .github/dependabot.yml.old | 26 ---------- .github/workflows/notifications.yml | 23 +++++++++ .github/workflows/quality.yml | 62 ++++++++++++++++++++++++ .github/workflows/super-linter.yml | 17 ------- .github/workflows/test.yml | 74 +++++++++++++++++++++++++++++ 7 files changed, 187 insertions(+), 43 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/dependabot.yml.old create mode 100644 .github/workflows/notifications.yml create mode 100644 .github/workflows/quality.yml delete mode 100644 .github/workflows/super-linter.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..7711713 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,14 @@ +## Description + + + +## Requirements + +* Documentation updates + - [ ] Reference + - [ ] Changelog +* [ ] Unit tests + +## Breaking changes + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..58db37d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ +## Description + + + +## Requirements + +* Documentation updates + - [ ] Reference + - [ ] Changelog +* [ ] Unit tests + +## Breaking changes + + diff --git a/.github/dependabot.yml.old b/.github/dependabot.yml.old deleted file mode 100644 index 3bcc9ea..0000000 --- a/.github/dependabot.yml.old +++ /dev/null @@ -1,26 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "composer" - directory: "/" - target-branch: "v2-dev" - schedule: - interval: "weekly" - allow: - - dependency-type: "all" - groups: - symfony: - patterns: - - "symfony*" - update-types: - - "minor" - - "patch" - - package-ecosystem: "npm" - directory: "/" - target-branch: "v2-dev" - schedule: - interval: "weekly" - - package-ecosystem: "github-actions" - directory: "/" - target-branch: "v2-dev" - schedule: - interval: "weekly" diff --git a/.github/workflows/notifications.yml b/.github/workflows/notifications.yml new file mode 100644 index 0000000..7ebf430 --- /dev/null +++ b/.github/workflows/notifications.yml @@ -0,0 +1,23 @@ +name: Rocket chat notifications + +# Controls when the action will run. +on: + push: + tags: + - '*' + +jobs: + notification: + runs-on: ubuntu-latest + + steps: + - name: Get the tag short reference + id: get_tag + run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT + + - name: Rocket.Chat Notification + uses: madalozzo/Rocket.Chat.GitHub.Action.Notification@master + with: + type: success + job_name: "[cleverage/ui-process-bundle](https://github.com/cleverage/ui-process-bundle) : ${{ steps.get_tag.outputs.TAG }} has been released" + url: ${{ secrets.CLEVER_AGE_ROCKET_CHAT_WEBOOK_URL }} diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..9f1580f --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,62 @@ +name: Quality + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + tools: composer:v2 + - name: Install Composer dependencies (locked) + uses: ramsey/composer-install@v3 + - name: PHPStan + run: vendor/bin/phpstan --no-progress --memory-limit=1G analyse --error-format=github + + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + tools: composer:v2 + - name: Install Composer dependencies (locked) + uses: ramsey/composer-install@v3 + - name: PHP-CS-Fixer + run: vendor/bin/php-cs-fixer fix --diff --dry-run --show-progress=none + + rector: + name: Rector + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + tools: composer:v2 + - name: Install Composer dependencies (locked) + uses: ramsey/composer-install@v3 + - name: Rector + run: vendor/bin/rector --no-progress-bar --dry-run diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml deleted file mode 100644 index e40efa0..0000000 --- a/.github/workflows/super-linter.yml +++ /dev/null @@ -1,17 +0,0 @@ -# It checks the syntax of the PHP code (using PHP-CS-Fixer) -name: "Linter: Code Syntax" -on: - push: - branches: [ v2-dev ] - pull_request: - branches: [ v2-dev ] -jobs: - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: PHP-CS-Fixer - uses: docker://oskarstark/php-cs-fixer-ga - with: - args: --config=.project.php_cs --dry-run diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..2d7e7a4 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,74 @@ +name: Test + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + test: + name: PHP ${{ matrix.php-version }} + ${{ matrix.dependencies }} + ${{ matrix.variant }} + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.allowed-to-fail }} + env: + SYMFONY_REQUIRE: ${{matrix.symfony-require}} + + strategy: + matrix: + php-version: + - '8.2' + - '8.3' + dependencies: [highest] + allowed-to-fail: [false] + symfony-require: [''] + variant: [normal] + include: + - php-version: '8.2' + dependencies: highest + allowed-to-fail: false + symfony-require: 6.4.* + variant: symfony/symfony:"6.4.*" + - php-version: '8.2' + dependencies: highest + allowed-to-fail: false + symfony-require: 7.1.* + variant: symfony/symfony:"7.1.*" + - php-version: '8.3' + dependencies: highest + allowed-to-fail: false + symfony-require: 6.4.* + variant: symfony/symfony:"6.4.*" + - php-version: '8.3' + dependencies: highest + allowed-to-fail: false + symfony-require: 7.1.* + variant: symfony/symfony:"7.1.*" + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: pcov + tools: composer:v2, flex + - name: Add PHPUnit matcher + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + - name: Install variant + if: matrix.variant != 'normal' && !startsWith(matrix.variant, 'symfony/symfony') + run: composer require ${{ matrix.variant }} --no-update + - name: Install Composer dependencies (${{ matrix.dependencies }}) + uses: ramsey/composer-install@v3 + with: + dependency-versions: ${{ matrix.dependencies }} + - name: Run Tests with coverage + run: vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover build/logs/clover.xml + #- name: Send coverage to Codecov + # uses: codecov/codecov-action@v4 + # with: + # files: build/logs/clover.xml From 486b2d3117a1ec6435643b1723738083ee612178 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 15:41:30 +0100 Subject: [PATCH 043/115] #1 Apply phpstan, php-cs-fixer & rector rules --- src/CleverAgeProcessUiBundle.php | 9 ++ src/Command/PurgeProcessExecution.php | 23 +++-- src/Command/UserCreateCommand.php | 22 +++-- src/Controller/.gitignore | 0 src/Controller/Crud/ProcessCrudController.php | 36 +++++--- .../Crud/ProcessExecutionCrudController.php | 42 +++++---- src/Controller/Crud/UserCrudController.php | 50 +++++----- src/Controller/DashboardController.php | 13 ++- src/Controller/SecurityController.php | 23 +++-- .../CleverAgeProcessUiExtension.php | 9 ++ .../RegisterLogHandlerCompilerPass.php | 9 ++ src/DependencyInjection/Configuration.php | 9 ++ src/Entity/Process.php | 91 ++++++++++--------- src/Entity/ProcessExecution.php | 63 +++++++------ src/Entity/ProcessExecutionLogRecord.php | 45 +++++---- src/Entity/User.php | 22 ++++- src/Event/IncrementReportInfoEvent.php | 15 ++- src/Event/SetReportInfoEvent.php | 17 ++-- .../Crud/ProcessCrudListener.php | 14 ++- .../ProcessEventSubscriber.php | 44 ++++----- src/Manager/ProcessUiConfigurationManager.php | 14 ++- src/Message/LogIndexerHandler.php | 17 +++- src/Message/LogIndexerMessage.php | 25 ++--- src/Message/ProcessRunHandler.php | 14 ++- src/Message/ProcessRunMessage.php | 18 ++-- src/Migrations/Version20210903142035.php | 11 ++- src/Migrations/Version20211028081845.php | 11 ++- src/Monolog/Handler/ProcessLogHandler.php | 17 +++- src/Repository/ProcessExecutionRepository.php | 9 ++ src/Repository/ProcessRepository.php | 18 ++-- src/Repository/UserRepository.php | 11 ++- src/Security/LoginFormAuthAuthenticator.php | 16 +++- 32 files changed, 464 insertions(+), 273 deletions(-) delete mode 100644 src/Controller/.gitignore diff --git a/src/CleverAgeProcessUiBundle.php b/src/CleverAgeProcessUiBundle.php index b89f243..c68bf2c 100644 --- a/src/CleverAgeProcessUiBundle.php +++ b/src/CleverAgeProcessUiBundle.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle; use CleverAge\ProcessUiBundle\DependencyInjection\Compiler\RegisterLogHandlerCompilerPass; diff --git a/src/Command/PurgeProcessExecution.php b/src/Command/PurgeProcessExecution.php index 24013da..b00c8dc 100644 --- a/src/Command/PurgeProcessExecution.php +++ b/src/Command/PurgeProcessExecution.php @@ -2,11 +2,19 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Command; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; -use DateTimeInterface; use Doctrine\Persistence\ManagerRegistry; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -16,6 +24,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; +use Symfony\Contracts\Service\Attribute\Required; #[AsCommand(name: 'cleverage:process-ui:purge', description: 'Purge process_execution table.')] class PurgeProcessExecution extends Command @@ -23,17 +32,13 @@ class PurgeProcessExecution extends Command private ManagerRegistry $managerRegistry; private string $processLogDir; - /** - * @required - */ + #[Required] public function setManagerRegistry(ManagerRegistry $managerRegistry): void { $this->managerRegistry = $managerRegistry; } - /** - * @required - */ + #[Required] public function setProcessLogDir(string $processLogDir): void { $this->processLogDir = $processLogDir; @@ -70,7 +75,7 @@ public function execute(InputInterface $input, OutputInterface $output): int if ($removeFiles) { $finder = new Finder(); $fs = new Filesystem(); - $finder->in($this->processLogDir)->date('before '.$date->format(DateTimeInterface::ATOM)); + $finder->in($this->processLogDir)->date('before '.$date->format(\DateTimeInterface::ATOM)); $count = $finder->count(); $fs->remove($finder); $output->writeln("$count log files are deleted on filesystem."); @@ -80,7 +85,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $repository->deleteBefore($date); $output->writeln(<<Process Execution before {$date->format(DateTimeInterface::ATOM)} are deleted into database. + Process Execution before {$date->format(\DateTimeInterface::ATOM)} are deleted into database. EOT); return Command::SUCCESS; diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index 98e19af..0591c7b 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Command; use CleverAge\ProcessUiBundle\Entity\User; @@ -20,18 +29,11 @@ #[AsCommand(name: 'cleverage:process-ui:user-create', description: 'Command to create a new admin into database for process ui.')] final class UserCreateCommand extends Command { - private ValidatorInterface $validator; - private UserPasswordHasherInterface $passwordEncoder; - private EntityManagerInterface $em; - public function __construct( - ValidatorInterface $validator, - UserPasswordHasherInterface $passwordEncoder, - EntityManagerInterface $em + private readonly ValidatorInterface $validator, + private readonly UserPasswordHasherInterface $passwordEncoder, + private readonly EntityManagerInterface $em, ) { - $this->validator = $validator; - $this->passwordEncoder = $passwordEncoder; - $this->em = $em; parent::__construct(); } diff --git a/src/Controller/.gitignore b/src/Controller/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/Controller/Crud/ProcessCrudController.php b/src/Controller/Crud/ProcessCrudController.php index 592d50c..517e1a0 100644 --- a/src/Controller/Crud/ProcessCrudController.php +++ b/src/Controller/Crud/ProcessCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Crud; use CleverAge\ProcessUiBundle\Entity\Process; @@ -18,7 +27,6 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; -use Exception; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\MessageBusInterface; @@ -26,9 +34,9 @@ class ProcessCrudController extends AbstractCrudController { public function __construct( - private ProcessUiConfigurationManager $processUiConfigurationManager, - private AdminUrlGenerator $adminUrlGenerator, - private MessageBusInterface $messageBus, + private readonly ProcessUiConfigurationManager $processUiConfigurationManager, + private readonly AdminUrlGenerator $adminUrlGenerator, + private readonly MessageBusInterface $messageBus, ) { } @@ -57,13 +65,11 @@ public function configureFields(string $pageName): array 'source', 'target', 'lastExecutionDate', - IntegerField::new('lastExecutionStatus')->formatValue(static function (?int $value) { - return match ($value) { - ProcessExecution::STATUS_FAIL => '', - ProcessExecution::STATUS_START => '', - ProcessExecution::STATUS_SUCCESS => '', - default => '', - }; + IntegerField::new('lastExecutionStatus')->formatValue(static fn (?int $value) => match ($value) { + ProcessExecution::STATUS_FAIL => '', + ProcessExecution::STATUS_START => '', + ProcessExecution::STATUS_SUCCESS => '', + default => '', }), ]; } @@ -86,7 +92,7 @@ public function configureActions(Actions $actions): Actions return $actions; } - public function runProcessAction(AdminContext $context): Response + public function runProcess(AdminContext $context): Response { try { /** @var Process $process */ @@ -104,16 +110,16 @@ public function runProcessAction(AdminContext $context): Response 'Process has been added to queue. It will start as soon as possible' ); } - } catch (Exception $e) { + } catch (\Exception) { $this->addFlash('warning', 'Cannot run process.'); } return $this->redirect( - $this->adminUrlGenerator->setController(__CLASS__)->setAction(Action::INDEX)->generateUrl() + $this->adminUrlGenerator->setController(self::class)->setAction(Action::INDEX)->generateUrl() ); } - public function viewHistoryAction(AdminContext $adminContext): RedirectResponse + public function viewHistory(AdminContext $adminContext): RedirectResponse { /** @var Process $process */ $process = $adminContext->getEntity()->getInstance(); diff --git a/src/Controller/Crud/ProcessExecutionCrudController.php b/src/Controller/Crud/ProcessExecutionCrudController.php index c5e8a4c..c76ca75 100644 --- a/src/Controller/Crud/ProcessExecutionCrudController.php +++ b/src/Controller/Crud/ProcessExecutionCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Crud; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; @@ -18,6 +27,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Filter\ChoiceFilter; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Contracts\Service\Attribute\Required; class ProcessExecutionCrudController extends AbstractCrudController { @@ -25,25 +35,19 @@ class ProcessExecutionCrudController extends AbstractCrudController private string $processLogDir; private ProcessUiConfigurationManager $processUiConfigurationManager; - /** - * @required - */ + #[Required] public function setIndexLogs(bool $indexLogs): void { $this->indexLogs = $indexLogs; } - /** - * @required - */ + #[Required] public function setProcessLogDir(string $processLogDir): void { $this->processLogDir = $processLogDir; } - /** - * @required true - */ + #[Required] public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void { $this->processUiConfigurationManager = $processUiConfigurationManager; @@ -59,7 +63,7 @@ public function configureCrud(Crud $crud): Crud $crud->showEntityActionsInlined(); $crud->setDefaultSort(['startDate' => SortOrder::DESC]); $crud->setEntityPermission('ROLE_ADMIN'); - $crud->setSearchFields(true === $this->indexLogs ? ['processCode', 'source', 'target', 'logRecords.message'] : ['processCode', 'source', 'target']); + $crud->setSearchFields($this->indexLogs ? ['processCode', 'source', 'target', 'logRecords.message'] : ['processCode', 'source', 'target']); return $crud; } @@ -75,13 +79,11 @@ public function configureFields(string $pageName): array 'target', 'startDate', 'endDate', - IntegerField::new('status')->formatValue(static function (?int $value) { - return match ($value) { - ProcessExecution::STATUS_FAIL => '', - ProcessExecution::STATUS_START => '', - ProcessExecution::STATUS_SUCCESS => '', - default => '', - }; + IntegerField::new('status')->formatValue(static fn (?int $value) => match ($value) { + ProcessExecution::STATUS_FAIL => '', + ProcessExecution::STATUS_START => '', + ProcessExecution::STATUS_SUCCESS => '', + default => '', }), ]; } @@ -89,17 +91,17 @@ public function configureFields(string $pageName): array public function configureFilters(Filters $filters): Filters { $processCodeChoices = $this->processUiConfigurationManager->getProcessChoices(); - if (\count($processCodeChoices) > 0) { + if ([] !== $processCodeChoices) { $filters->add(ChoiceFilter::new('processCode', 'Process')->setChoices($processCodeChoices)); } $sourceChoices = $this->processUiConfigurationManager->getSourceChoices(); - if (\count($sourceChoices) > 0) { + if ([] !== $sourceChoices) { $filters->add(ChoiceFilter::new('source')->setChoices($sourceChoices)); } $targetChoices = $this->processUiConfigurationManager->getTargetChoices(); - if (\count($targetChoices) > 0) { + if ([] !== $targetChoices) { $filters->add(ChoiceFilter::new('target')->setChoices($targetChoices)); } $filters->add(ChoiceFilter::new('status')->setChoices([ diff --git a/src/Controller/Crud/UserCrudController.php b/src/Controller/Crud/UserCrudController.php index d432029..9ee2f36 100644 --- a/src/Controller/Crud/UserCrudController.php +++ b/src/Controller/Crud/UserCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Crud; use CleverAge\ProcessUiBundle\CleverAgeProcessUiBundle; @@ -26,11 +35,8 @@ class UserCrudController extends AbstractCrudController { - private UserPasswordHasherInterface $passwordHasher; - - public function __construct(UserPasswordHasherInterface $passwordHasher) + public function __construct(private readonly UserPasswordHasherInterface $passwordHasher) { - $this->passwordHasher = $passwordHasher; } public function configureCrud(Crud $crud): Crud @@ -72,28 +78,28 @@ public function configureFields(string $pageName): iterable public function configureActions(Actions $actions): Actions { return $actions - ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_NEW) - ->setLabel(CleverAgeProcessUiBundle::LABEL_NEW) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_NEW); - })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_EDIT) - ->setLabel(CleverAgeProcessUiBundle::LABEL_EDIT) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_EDIT); - })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { - return $action->setIcon(CleverAgeProcessUiBundle::ICON_DELETE) - ->setLabel(CleverAgeProcessUiBundle::LABEL_DELETE) - ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE); - })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { - return $action->setLabel('Delete') - ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE); - }); + ->update(Crud::PAGE_INDEX, Action::NEW, fn (Action $action) => $action + ->setIcon(CleverAgeProcessUiBundle::ICON_NEW) + ->setLabel(CleverAgeProcessUiBundle::LABEL_NEW) + ->addCssClass(CleverAgeProcessUiBundle::CLASS_NEW) + )->update(Crud::PAGE_INDEX, Action::EDIT, fn (Action $action) => $action + ->setIcon(CleverAgeProcessUiBundle::ICON_EDIT) + ->setLabel(CleverAgeProcessUiBundle::LABEL_EDIT) + ->addCssClass(CleverAgeProcessUiBundle::CLASS_EDIT) + )->update(Crud::PAGE_INDEX, Action::DELETE, fn (Action $action) => $action + ->setIcon(CleverAgeProcessUiBundle::ICON_DELETE) + ->setLabel(CleverAgeProcessUiBundle::LABEL_DELETE) + ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE) + )->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, fn (Action $action) => $action + ->setLabel('Delete') + ->addCssClass(CleverAgeProcessUiBundle::CLASS_DELETE) + ); } public function createEditFormBuilder( EntityDto $entityDto, KeyValueStore $formOptions, - AdminContext $context + AdminContext $context, ): FormBuilderInterface { $formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context); @@ -105,7 +111,7 @@ public function createEditFormBuilder( public function createNewFormBuilder( EntityDto $entityDto, KeyValueStore $formOptions, - AdminContext $context + AdminContext $context, ): FormBuilderInterface { $formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context); diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php index dc90303..6c4c49b 100644 --- a/src/Controller/DashboardController.php +++ b/src/Controller/DashboardController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller; use CleverAge\ProcessUiBundle\Controller\Crud\ProcessCrudController; @@ -13,11 +22,11 @@ use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; class DashboardController extends AbstractDashboardController { - #[Route('/', name: 'process_admin')] + #[Route('/', name: 'cleverage_ui_process_admin')] public function index(): Response { /** @var AdminUrlGenerator $routeBuilder */ diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index 4879dce..819e8ee 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -2,20 +2,29 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; class SecurityController extends AbstractController { - #[Route('/login', name: 'app_login')] + #[Route('/login', name: 'cleverage_ui_process_login')] public function login(AuthenticationUtils $authenticationUtils): Response { - if ($this->getUser()) { - return $this->redirectToRoute('process_admin'); + if ($this->getUser() instanceof \Symfony\Component\Security\Core\User\UserInterface) { + return $this->redirectToRoute('cleverage_ui_process_admin'); } // get the login error if there is one @@ -34,11 +43,9 @@ public function login(AuthenticationUtils $authenticationUtils): Response ]); } - #[Route('/logout', name: 'app_logout')] + #[Route('/logout', name: 'cleverage_ui_process_logout')] public function logout(): void { - throw new \LogicException( - 'This method can be blank - it will be intercepted by the logout key on your firewall.' - ); + throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); } } diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index 504ae37..bfe2077 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\DependencyInjection; use CleverAge\ProcessUiBundle\Message\LogIndexerMessage; diff --git a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php b/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php index 3b28378..da0eddd 100644 --- a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php +++ b/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\DependencyInjection\Compiler; use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler; diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 0e5c270..f919fe6 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; diff --git a/src/Entity/Process.php b/src/Entity/Process.php index 7d0ca7b..78e6c55 100644 --- a/src/Entity/Process.php +++ b/src/Entity/Process.php @@ -2,11 +2,19 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Repository\ProcessRepository; -use DateTime; -use DateTimeInterface; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -17,54 +25,47 @@ class Process { /** * @ORM\Id + * * @ORM\Column(type="integer") + * * @ORM\GeneratedValue() */ - private ?int $id; - - /** - * @ORM\Column(name="process_code", type="text", length=255) - */ - private string $processCode; - - /** - * @ORM\Column(name="source", type="text", length=255, nullable=true) - */ - private ?string $source; - - /** - * @ORM\Column(name="target", type="text", length=255, nullable=true) - */ - private ?string $target; - - /** - * @ORM\Column(name="last_execution_date", type="datetime", nullable=true) - */ - private ?DateTimeInterface $lastExecutionDate; + private ?int $id = null; /** * @var Collection + * * @ORM\OneToMany(targetEntity="CleverAge\ProcessUiBundle\Entity\ProcessExecution", mappedBy="process") */ - private $executions; - - /** - * @ORM\Column(name="last_execution_status", type="integer", nullable=true) - */ - private ?int $lastExecutionStatus; + private Collection $executions; public function __construct( - string $processCode, - ?string $source = null, - ?string $target = null, - ?DateTime $lastExecutionDate = null, - ?int $lastExecutionStatus = null + /** + * @ORM\Column(name="process_code", type="text", length=255) + */ + private readonly string $processCode, + + /** + * @ORM\Column(name="source", type="text", length=255, nullable=true) + */ + private readonly ?string $source = null, + + /** + * @ORM\Column(name="target", type="text", length=255, nullable=true) + */ + private readonly ?string $target = null, + + /** + * @ORM\Column(name="last_execution_date", type="datetime", nullable=true) + */ + private ?\DateTimeInterface $lastExecutionDate = null, + + /** + * @ORM\Column(name="last_execution_status", type="integer", nullable=true) + */ + private ?int $lastExecutionStatus = null, ) { - $this->processCode = $processCode; - $this->source = $source; - $this->target = $target; - $this->lastExecutionDate = $lastExecutionDate; - $this->lastExecutionStatus = $lastExecutionStatus; + $this->executions = new ArrayCollection(); } public function getId(): ?int @@ -87,7 +88,7 @@ public function getTarget(): ?string return $this->target; } - public function getLastExecutionDate(): ?DateTimeInterface + public function getLastExecutionDate(): ?\DateTimeInterface { return $this->lastExecutionDate; } @@ -97,7 +98,15 @@ public function getLastExecutionStatus(): ?int return $this->lastExecutionStatus; } - public function setLastExecutionDate(DateTimeInterface $lastExecutionDate): self + /** + * @return Collection + */ + public function getExecutions(): Collection + { + return $this->executions; + } + + public function setLastExecutionDate(\DateTimeInterface $lastExecutionDate): self { $this->lastExecutionDate = $lastExecutionDate; diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 47ff1ac..90411e1 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -2,11 +2,18 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; -use DateTime; -use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -22,66 +29,62 @@ class ProcessExecution /** * @ORM\Id + * * @ORM\Column(type="integer") + * * @ORM\GeneratedValue() */ - private ?int $id; + private ?int $id = null; /** * @ORM\Column(name="process_code", type="string", length=255, nullable=true) */ - private ?string $processCode; + private ?string $processCode = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $source; + private ?string $source = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $target; + private ?string $target = null; /** * @ORM\Column(type="datetime") */ - private DateTimeInterface $startDate; + private \DateTimeInterface $startDate; /** * @ORM\Column(type="datetime", nullable=true) */ - private ?DateTimeInterface $endDate; + private ?\DateTimeInterface $endDate = null; /** * @ORM\Column(type="integer") */ - private int $status; + private int $status = self::STATUS_START; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $response; + private ?string $response = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $data; + private ?string $data = null; /** * @ORM\Column(type="json", nullable=true) */ - private ?array $report; + private ?array $report = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $log; - - /** - * @ORM\ManyToOne(targetEntity="CleverAge\ProcessUiBundle\Entity\Process", inversedBy="executions") - * @ORM\JoinColumn(name="process_id", referencedColumnName="id", onDelete="SET NULL") - */ - private Process $process; + private ?string $log = null; /** * @ORM\OneToMany(targetEntity="ProcessExecutionLogRecord", mappedBy="processExecution", cascade={"persist"}) @@ -90,11 +93,15 @@ class ProcessExecution */ private Collection $logRecords; - public function __construct(Process $process) - { - $this->process = $process; - $this->status = self::STATUS_START; - $this->startDate = new DateTime(); + public function __construct( + /** + * @ORM\ManyToOne(targetEntity="CleverAge\ProcessUiBundle\Entity\Process", inversedBy="executions") + * + * @ORM\JoinColumn(name="process_id", referencedColumnName="id", onDelete="SET NULL") + */ + private readonly Process $process, + ) { + $this->startDate = new \DateTime(); $this->logRecords = new ArrayCollection(); } @@ -139,24 +146,24 @@ public function setTarget(?string $target): self return $this; } - public function getStartDate(): DateTimeInterface + public function getStartDate(): \DateTimeInterface { return $this->startDate; } - public function setStartDate(DateTimeInterface $startDate): self + public function setStartDate(\DateTimeInterface $startDate): self { $this->startDate = $startDate; return $this; } - public function getEndDate(): ?DateTimeInterface + public function getEndDate(): ?\DateTimeInterface { return $this->endDate; } - public function setEndDate(DateTimeInterface $endDate): self + public function setEndDate(\DateTimeInterface $endDate): self { $this->endDate = $endDate; diff --git a/src/Entity/ProcessExecutionLogRecord.php b/src/Entity/ProcessExecutionLogRecord.php index c70807b..b0d3f38 100644 --- a/src/Entity/ProcessExecutionLogRecord.php +++ b/src/Entity/ProcessExecutionLogRecord.php @@ -2,14 +2,25 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity + * * @ORM\Table( * indexes={ + * * @ORM\Index(name="process_execution_log_message", columns={"message"}) * } * ) @@ -18,31 +29,31 @@ class ProcessExecutionLogRecord { /** * @ORM\Id + * * @ORM\Column(type="integer") + * * @ORM\GeneratedValue() */ - private ?int $id; - - /** - * @ORM\Column(type="integer") - */ - private int $logLevel; - - /** - * @ORM\Column(type="string") - */ - private string $message; + private ?int $id = null; /** * @ORM\ManyToOne(targetEntity="ProcessExecution", inversedBy="logRecords") + * * @ORM\JoinColumn(name="process_execution_id", referencedColumnName="id", onDelete="CASCADE") */ - private ?ProcessExecution $processExecution; - - public function __construct(int $logLevel, string $message) - { - $this->logLevel = $logLevel; - $this->message = $message; + private ?ProcessExecution $processExecution = null; + + public function __construct( + /** + * @ORM\Column(type="integer") + */ + private int $logLevel, + + /** + * @ORM\Column(type="string") + */ + private string $message, + ) { } public function getId(): ?int diff --git a/src/Entity/User.php b/src/Entity/User.php index 20dbed5..d057ad3 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Repository\UserRepository; @@ -11,31 +20,34 @@ /** * @ORM\Entity(repositoryClass=UserRepository::class) + * * @ORM\Table(name="user") */ class User implements UserInterface, PasswordAuthenticatedUserInterface { /** * @ORM\Id + * * @ORM\GeneratedValue + * * @ORM\Column(type="integer") */ - private ?int $id; + private ?int $id = null; /** * @ORM\Column(type="string", length=255, unique=true) */ - private ?string $email; + private ?string $email = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $firstname; + private ?string $firstname = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private ?string $lastname; + private ?string $lastname = null; /** * @ORM\Column(type="json") @@ -47,7 +59,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface /** * @ORM\Column(type="string") */ - private ?string $password; + private ?string $password = null; public function getId(): ?int { diff --git a/src/Event/IncrementReportInfoEvent.php b/src/Event/IncrementReportInfoEvent.php index 4d10e7e..e16fc24 100644 --- a/src/Event/IncrementReportInfoEvent.php +++ b/src/Event/IncrementReportInfoEvent.php @@ -2,18 +2,23 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Event; class IncrementReportInfoEvent { public const NAME = 'cleverage_process_ui.increment_report_info'; - private string $key; - private string $processCode; - public function __construct(string $processCode, string $key) + public function __construct(private readonly string $processCode, private readonly string $key) { - $this->key = $key; - $this->processCode = $processCode; } public function getKey(): string diff --git a/src/Event/SetReportInfoEvent.php b/src/Event/SetReportInfoEvent.php index 20d14af..eed2c42 100644 --- a/src/Event/SetReportInfoEvent.php +++ b/src/Event/SetReportInfoEvent.php @@ -2,20 +2,23 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Event; class SetReportInfoEvent { public const NAME = 'cleverage_process_ui.set_report_info'; - private string $key; - private mixed $value; - private string $processCode; - public function __construct(string $processCode, string $key, mixed $value) + public function __construct(private readonly string $processCode, private readonly string $key, private readonly mixed $value) { - $this->key = $key; - $this->value = $value; - $this->processCode = $processCode; } public function getKey(): string diff --git a/src/EventSubscriber/Crud/ProcessCrudListener.php b/src/EventSubscriber/Crud/ProcessCrudListener.php index f8a7543..c272580 100644 --- a/src/EventSubscriber/Crud/ProcessCrudListener.php +++ b/src/EventSubscriber/Crud/ProcessCrudListener.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\EventSubscriber\Crud; use CleverAge\ProcessUiBundle\Entity\Process; @@ -12,11 +21,8 @@ class ProcessCrudListener implements EventSubscriberInterface { - private EntityManagerInterface $entityManager; - - public function __construct(EntityManagerInterface $entityManager) + public function __construct(private readonly EntityManagerInterface $entityManager) { - $this->entityManager = $entityManager; } /** diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index e9ed92f..f8c988b 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\EventSubscriber; use CleverAge\ProcessBundle\Event\ProcessEvent; @@ -13,37 +22,16 @@ use CleverAge\ProcessUiBundle\Message\LogIndexerMessage; use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler; use CleverAge\ProcessUiBundle\Repository\ProcessRepository; -use DateTime; use Doctrine\ORM\EntityManagerInterface; -use RuntimeException; -use SplFileObject; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Messenger\MessageBusInterface; class ProcessEventSubscriber implements EventSubscriberInterface { private array $processExecution = []; - private EntityManagerInterface $entityManager; - private ProcessLogHandler $processLogHandler; - private MessageBusInterface $messageBus; - private ProcessUiConfigurationManager $processUiConfigurationManager; - private string $processLogDir; - private bool $indexLogs; - public function __construct( - EntityManagerInterface $entityManager, - ProcessLogHandler $processLogHandler, - MessageBusInterface $messageBus, - ProcessUiConfigurationManager $processUiConfigurationManager, - string $processLogDir, - bool $indexLogs - ) { - $this->entityManager = $entityManager; - $this->processLogHandler = $processLogHandler; - $this->messageBus = $messageBus; - $this->processUiConfigurationManager = $processUiConfigurationManager; - $this->processLogDir = $processLogDir; - $this->indexLogs = $indexLogs; + public function __construct(private readonly EntityManagerInterface $entityManager, private readonly ProcessLogHandler $processLogHandler, private readonly MessageBusInterface $messageBus, private readonly ProcessUiConfigurationManager $processUiConfigurationManager, private readonly string $processLogDir, private readonly bool $indexLogs) + { } public static function getSubscribedEvents(): array @@ -73,13 +61,13 @@ public function onProcessStarted(ProcessEvent $event): void $process = $this->entityManager->getRepository(Process::class) ->findOneBy(['processCode' => $event->getProcessCode()]); if (null === $process) { - throw new RuntimeException('Unable to found process into database.'); + throw new \RuntimeException('Unable to found process into database.'); } $processExecution = new ProcessExecution($process); $processExecution->setProcessCode($event->getProcessCode()); $processExecution->setSource($this->processUiConfigurationManager->getSource($event->getProcessCode())); $processExecution->setTarget($this->processUiConfigurationManager->getTarget($event->getProcessCode())); - $logFilename = sprintf( + $logFilename = \sprintf( 'process_%s_%s.log', $event->getProcessCode(), sha1(uniqid((string) mt_rand(), true)) @@ -98,7 +86,7 @@ public function onProcessEnded(ProcessEvent $processEvent): void $this->processExecution = array_filter($this->processExecution); array_pop($this->processExecution); $this->processLogHandler->setCurrentProcessCode((string) array_key_last($this->processExecution)); - $processExecution->setEndDate(new DateTime()); + $processExecution->setEndDate(new \DateTime()); $processExecution->setStatus(ProcessExecution::STATUS_SUCCESS); $processExecution->getProcess()->setLastExecutionDate($processExecution->getStartDate()); $processExecution->getProcess()->setLastExecutionStatus( @@ -114,7 +102,7 @@ public function onProcessEnded(ProcessEvent $processEvent): void public function onProcessFailed(ProcessEvent $processEvent): void { if ($processExecution = ($this->processExecution[$processEvent->getProcessCode()] ?? null)) { - $processExecution->setEndDate(new DateTime()); + $processExecution->setEndDate(new \DateTime()); $processExecution->setStatus(ProcessExecution::STATUS_FAIL); $processExecution->getProcess()->setLastExecutionDate($processExecution->getStartDate()); $processExecution->getProcess()->setLastExecutionStatus(ProcessExecution::STATUS_FAIL); @@ -136,7 +124,7 @@ protected function dispatchLogIndexerMessage(ProcessExecution $processExecution) { if ($this->indexLogs && null !== $processExecutionId = $processExecution->getId()) { $filePath = $this->processLogDir.\DIRECTORY_SEPARATOR.$processExecution->getLog(); - $file = new SplFileObject($filePath); + $file = new \SplFileObject($filePath); $file->seek(\PHP_INT_MAX); $chunkSize = LogIndexerMessage::DEFAULT_OFFSET; $chunk = (int) ($file->key() / $chunkSize) + 1; diff --git a/src/Manager/ProcessUiConfigurationManager.php b/src/Manager/ProcessUiConfigurationManager.php index d852b1e..a87d89d 100644 --- a/src/Manager/ProcessUiConfigurationManager.php +++ b/src/Manager/ProcessUiConfigurationManager.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Manager; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -15,11 +24,8 @@ class ProcessUiConfigurationManager public const UI_OPTION_TARGET = 'target'; public const UI_OPTION_RUN = 'ui_run'; - private ProcessConfigurationRegistry $processConfigurationRegistry; - - public function __construct(ProcessConfigurationRegistry $processConfigurationRegistry) + public function __construct(private readonly ProcessConfigurationRegistry $processConfigurationRegistry) { - $this->processConfigurationRegistry = $processConfigurationRegistry; } /** diff --git a/src/Message/LogIndexerHandler.php b/src/Message/LogIndexerHandler.php index c591e70..8cb7836 100644 --- a/src/Message/LogIndexerHandler.php +++ b/src/Message/LogIndexerHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessUiBundle\Entity\ProcessExecutionLogRecord; @@ -15,11 +24,9 @@ class LogIndexerHandler { public const INDEX_LOG_RECORD = 'index_log_record'; - private ManagerRegistry $managerRegistry; - public function __construct(ManagerRegistry $managerRegistry) + public function __construct(private readonly ManagerRegistry $managerRegistry) { - $this->managerRegistry = $managerRegistry; } public function __invoke(LogIndexerMessage $logIndexerMessage): void @@ -39,12 +46,12 @@ public function __invoke(LogIndexerMessage $logIndexerMessage): void if (!empty($parsedLine) && true === ($parsedLine['context'][self::INDEX_LOG_RECORD] ?? false)) { $parameters[] = $logIndexerMessage->getProcessExecutionId(); $parameters[] = Logger::toMonologLevel($parsedLine['level']); - $parameters[] = substr($parsedLine['message'], 0, 255); + $parameters[] = substr((string) $parsedLine['message'], 0, 255); } $file->next(); --$offset; } - if (\count($parameters) > 0) { + if ([] !== $parameters) { $statement = $this->getStatement($table, (int) (\count($parameters) / 3)); $manager->getConnection()->executeStatement($statement, $parameters); } diff --git a/src/Message/LogIndexerMessage.php b/src/Message/LogIndexerMessage.php index 760b63d..e6a893c 100644 --- a/src/Message/LogIndexerMessage.php +++ b/src/Message/LogIndexerMessage.php @@ -2,26 +2,27 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; class LogIndexerMessage { public const DEFAULT_OFFSET = 2500; - private int $processExecutionId; - private string $logPath; - private int $start; - private int $offset; public function __construct( - int $processExecutionId, - string $logPath, - int $start, - int $offset = self::DEFAULT_OFFSET + private readonly int $processExecutionId, + private readonly string $logPath, + private readonly int $start, + private readonly int $offset = self::DEFAULT_OFFSET, ) { - $this->processExecutionId = $processExecutionId; - $this->logPath = $logPath; - $this->start = $start; - $this->offset = $offset; } public function getProcessExecutionId(): int diff --git a/src/Message/ProcessRunHandler.php b/src/Message/ProcessRunHandler.php index 30ae3dd..9bc7e08 100644 --- a/src/Message/ProcessRunHandler.php +++ b/src/Message/ProcessRunHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessBundle\Command\ExecuteProcessCommand; @@ -13,11 +22,8 @@ #[AsMessageHandler] class ProcessRunHandler { - private ExecuteProcessCommand $command; - - public function __construct(ExecuteProcessCommand $command) + public function __construct(private readonly ExecuteProcessCommand $command) { - $this->command = $command; } /** diff --git a/src/Message/ProcessRunMessage.php b/src/Message/ProcessRunMessage.php index 5b9682a..188e27c 100644 --- a/src/Message/ProcessRunMessage.php +++ b/src/Message/ProcessRunMessage.php @@ -2,22 +2,24 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; class ProcessRunMessage { - private string $processCode; - - /** @var array */ - private array $processInput; - /** * @param array $processInput */ - public function __construct(string $processCode, array $processInput = []) + public function __construct(private readonly string $processCode, private readonly array $processInput = []) { - $this->processCode = $processCode; - $this->processInput = $processInput; } public function getProcessCode(): string diff --git a/src/Migrations/Version20210903142035.php b/src/Migrations/Version20210903142035.php index 88e869c..3f4e991 100644 --- a/src/Migrations/Version20210903142035.php +++ b/src/Migrations/Version20210903142035.php @@ -2,7 +2,16 @@ declare(strict_types=1); -namespace CleverAgeProcessUi; +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Migrations/Version20211028081845.php b/src/Migrations/Version20211028081845.php index 0b2ff9e..fcd13af 100644 --- a/src/Migrations/Version20211028081845.php +++ b/src/Migrations/Version20211028081845.php @@ -2,7 +2,16 @@ declare(strict_types=1); -namespace CleverAgeProcessUi; +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Monolog/Handler/ProcessLogHandler.php b/src/Monolog/Handler/ProcessLogHandler.php index 1278e5f..5dcbf01 100644 --- a/src/Monolog/Handler/ProcessLogHandler.php +++ b/src/Monolog/Handler/ProcessLogHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Monolog\Handler; use League\Flysystem\Filesystem; @@ -9,7 +18,7 @@ use League\Flysystem\Local\LocalFilesystemAdapter; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; - +use Symfony\Contracts\Service\Attribute\Required; class ProcessLogHandler extends AbstractProcessingHandler { @@ -18,9 +27,7 @@ class ProcessLogHandler extends AbstractProcessingHandler private ?string $currentProcessCode = null; private ?Filesystem $filesystem = null; - /** - * @required - */ + #[Required] public function setLogDir(string $processLogDir): void { $this->logDir = $processLogDir; @@ -41,7 +48,7 @@ protected function write(array $record): void return; } - if (null === $this->filesystem) { + if (!$this->filesystem instanceof Filesystem) { $this->filesystem = new Filesystem( new LocalFilesystemAdapter($this->logDir, null, \FILE_APPEND) ); diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index 9294fa7..07c8cb9 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; diff --git a/src/Repository/ProcessRepository.php b/src/Repository/ProcessRepository.php index 71140df..c0eb33f 100644 --- a/src/Repository/ProcessRepository.php +++ b/src/Repository/ProcessRepository.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; @@ -9,6 +18,7 @@ use CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Contracts\Service\Attribute\Required; /** * @extends ServiceEntityRepository @@ -18,17 +28,13 @@ class ProcessRepository extends ServiceEntityRepository private ProcessUiConfigurationManager $processUiConfigurationManager; private ProcessConfigurationRegistry $processConfigurationRegistry; - /** - * @required - */ + #[Required] public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void { $this->processUiConfigurationManager = $processUiConfigurationManager; } - /** - * @required - */ + #[Required] public function setProcessConfigurationRegistry(ProcessConfigurationRegistry $processConfigurationRegistry): void { $this->processConfigurationRegistry = $processConfigurationRegistry; diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 83294b9..366e57d 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessUiBundle\Entity\User; @@ -27,7 +36,7 @@ public function __construct(ManagerRegistry $registry) public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void { if (!$user instanceof User) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); + throw new UnsupportedUserException(\sprintf('Instances of "%s" are not supported.', $user::class)); } $user->setPassword($newHashedPassword); $this->getEntityManager()->persist($user); diff --git a/src/Security/LoginFormAuthAuthenticator.php b/src/Security/LoginFormAuthAuthenticator.php index cc2c7b7..6898e8c 100644 --- a/src/Security/LoginFormAuthAuthenticator.php +++ b/src/Security/LoginFormAuthAuthenticator.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Security; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -23,11 +32,8 @@ class LoginFormAuthAuthenticator extends AbstractLoginFormAuthenticator public const LOGIN_ROUTE = 'app_login'; - private UrlGeneratorInterface $urlGenerator; - - public function __construct(UrlGeneratorInterface $urlGenerator) + public function __construct(private readonly UrlGeneratorInterface $urlGenerator) { - $this->urlGenerator = $urlGenerator; } public function authenticate(Request $request): Passport @@ -51,7 +57,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token, return new RedirectResponse($targetPath); } - return new RedirectResponse($this->urlGenerator->generate('process_admin')); + return new RedirectResponse($this->urlGenerator->generate('cleverage_ui_process_admin')); } protected function getLoginUrl(Request $request): string From f8427035c8295529837f9947ac70fad1b2ede823 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 15:52:45 +0100 Subject: [PATCH 044/115] #1 Add Doctrine rules on php-cs-fixer & rector. Apply it. --- .php-cs-fixer.dist.php | 1 + rector.php | 3 ++ src/Entity/Process.php | 40 +++++--------- src/Entity/ProcessExecution.php | 67 +++++++----------------- src/Entity/ProcessExecutionLogRecord.php | 38 ++++---------- src/Entity/User.php | 37 ++++--------- 6 files changed, 56 insertions(+), 130 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index e910756..ed5c8c5 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -29,6 +29,7 @@ '@PHPUnit75Migration:risky' => true, '@Symfony' => true, '@Symfony:risky' => true, + '@DoctrineAnnotation' => true, 'protected_to_private' => false, 'native_constant_invocation' => ['strict' => false], 'header_comment' => ['header' => $fileHeaderComment], diff --git a/rector.php b/rector.php index 72a2408..997c7e5 100644 --- a/rector.php +++ b/rector.php @@ -3,6 +3,7 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\Doctrine\Set\DoctrineSetList; use Rector\Set\ValueObject\LevelSetList; use Rector\Symfony\Set\SymfonySetList; use Rector\ValueObject\PhpVersion; @@ -26,5 +27,7 @@ SymfonySetList::SYMFONY_CODE_QUALITY, SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES, + DoctrineSetList::DOCTRINE_CODE_QUALITY, + DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES, ]) ; diff --git a/src/Entity/Process.php b/src/Entity/Process.php index 78e6c55..217b5e7 100644 --- a/src/Entity/Process.php +++ b/src/Entity/Process.php @@ -16,53 +16,37 @@ use CleverAge\ProcessUiBundle\Repository\ProcessRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity(repositoryClass=ProcessRepository::class) - */ +#[ORM\Entity(repositoryClass: ProcessRepository::class)] class Process { - /** - * @ORM\Id - * - * @ORM\Column(type="integer") - * - * @ORM\GeneratedValue() - */ + #[ORM\Id] + #[ORM\Column(type: Types::INTEGER)] + #[ORM\GeneratedValue] private ?int $id = null; /** * @var Collection - * - * @ORM\OneToMany(targetEntity="CleverAge\ProcessUiBundle\Entity\ProcessExecution", mappedBy="process") */ - private Collection $executions; + #[ORM\OneToMany(targetEntity: ProcessExecution::class, mappedBy: 'process')] + private readonly Collection $executions; public function __construct( - /** - * @ORM\Column(name="process_code", type="text", length=255) - */ + #[ORM\Column(name: 'process_code', type: Types::TEXT, length: 255)] private readonly string $processCode, - /** - * @ORM\Column(name="source", type="text", length=255, nullable=true) - */ + #[ORM\Column(name: 'source', type: Types::TEXT, length: 255, nullable: true)] private readonly ?string $source = null, - /** - * @ORM\Column(name="target", type="text", length=255, nullable=true) - */ + #[ORM\Column(name: 'target', type: Types::TEXT, length: 255, nullable: true)] private readonly ?string $target = null, - /** - * @ORM\Column(name="last_execution_date", type="datetime", nullable=true) - */ + #[ORM\Column(name: 'last_execution_date', type: Types::DATETIME_MUTABLE, nullable: true)] private ?\DateTimeInterface $lastExecutionDate = null, - /** - * @ORM\Column(name="last_execution_status", type="integer", nullable=true) - */ + #[ORM\Column(name: 'last_execution_status', type: Types::INTEGER, nullable: true)] private ?int $lastExecutionStatus = null, ) { $this->executions = new ArrayCollection(); diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 90411e1..8967623 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -16,89 +16,60 @@ use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity(repositoryClass=ProcessExecutionRepository::class) - */ +#[ORM\Entity(repositoryClass: ProcessExecutionRepository::class)] class ProcessExecution { public const STATUS_START = 0; public const STATUS_SUCCESS = 1; public const STATUS_FAIL = -1; - /** - * @ORM\Id - * - * @ORM\Column(type="integer") - * - * @ORM\GeneratedValue() - */ + #[ORM\Id] + #[ORM\Column(type: Types::INTEGER)] + #[ORM\GeneratedValue] private ?int $id = null; - /** - * @ORM\Column(name="process_code", type="string", length=255, nullable=true) - */ + #[ORM\Column(name: 'process_code', type: Types::STRING, length: 255, nullable: true)] private ?string $processCode = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $source = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $target = null; - /** - * @ORM\Column(type="datetime") - */ + #[ORM\Column(type: Types::DATETIME_MUTABLE)] private \DateTimeInterface $startDate; - /** - * @ORM\Column(type="datetime", nullable=true) - */ + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] private ?\DateTimeInterface $endDate = null; - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: Types::INTEGER)] private int $status = self::STATUS_START; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $response = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $data = null; - /** - * @ORM\Column(type="json", nullable=true) - */ + #[ORM\Column(type: Types::JSON, nullable: true)] private ?array $report = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $log = null; /** - * @ORM\OneToMany(targetEntity="ProcessExecutionLogRecord", mappedBy="processExecution", cascade={"persist"}) - * * @var Collection */ - private Collection $logRecords; + #[ORM\OneToMany(targetEntity: ProcessExecutionLogRecord::class, mappedBy: 'processExecution', cascade: ['persist'])] + private readonly Collection $logRecords; public function __construct( - /** - * @ORM\ManyToOne(targetEntity="CleverAge\ProcessUiBundle\Entity\Process", inversedBy="executions") - * - * @ORM\JoinColumn(name="process_id", referencedColumnName="id", onDelete="SET NULL") - */ + #[ORM\ManyToOne(targetEntity: Process::class, inversedBy: 'executions')] + #[ORM\JoinColumn(name: 'process_id', referencedColumnName: 'id', onDelete: 'SET NULL')] private readonly Process $process, ) { $this->startDate = new \DateTime(); diff --git a/src/Entity/ProcessExecutionLogRecord.php b/src/Entity/ProcessExecutionLogRecord.php index b0d3f38..6c0bee8 100644 --- a/src/Entity/ProcessExecutionLogRecord.php +++ b/src/Entity/ProcessExecutionLogRecord.php @@ -13,45 +13,27 @@ namespace CleverAge\ProcessUiBundle\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity - * - * @ORM\Table( - * indexes={ - * - * @ORM\Index(name="process_execution_log_message", columns={"message"}) - * } - * ) - */ +#[ORM\Entity] +#[ORM\Index(name: 'process_execution_log_message', columns: ['message'])] class ProcessExecutionLogRecord { - /** - * @ORM\Id - * - * @ORM\Column(type="integer") - * - * @ORM\GeneratedValue() - */ + #[ORM\Id] + #[ORM\Column(type: Types::INTEGER)] + #[ORM\GeneratedValue] private ?int $id = null; - /** - * @ORM\ManyToOne(targetEntity="ProcessExecution", inversedBy="logRecords") - * - * @ORM\JoinColumn(name="process_execution_id", referencedColumnName="id", onDelete="CASCADE") - */ + #[ORM\ManyToOne(targetEntity: ProcessExecution::class, inversedBy: 'logRecords')] + #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE')] private ?ProcessExecution $processExecution = null; public function __construct( - /** - * @ORM\Column(type="integer") - */ + #[ORM\Column(type: Types::INTEGER)] private int $logLevel, - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: Types::STRING)] private string $message, ) { } diff --git a/src/Entity/User.php b/src/Entity/User.php index d057ad3..8f12f2f 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -14,51 +14,36 @@ namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Repository\UserRepository; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; -/** - * @ORM\Entity(repositoryClass=UserRepository::class) - * - * @ORM\Table(name="user") - */ +#[ORM\Entity(repositoryClass: UserRepository::class)] +#[ORM\Table(name: 'user')] class User implements UserInterface, PasswordAuthenticatedUserInterface { - /** - * @ORM\Id - * - * @ORM\GeneratedValue - * - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: Types::INTEGER)] private ?int $id = null; - /** - * @ORM\Column(type="string", length=255, unique=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, unique: true)] private ?string $email = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $firstname = null; - /** - * @ORM\Column(type="string", length=255, nullable=true) - */ + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $lastname = null; /** - * @ORM\Column(type="json") - * * @var array */ + #[ORM\Column(type: Types::JSON)] private array $roles = []; - /** - * @ORM\Column(type="string") - */ + #[ORM\Column(type: Types::STRING)] private ?string $password = null; public function getId(): ?int From ae1379597aa5aa5a080f6a307dedbd3237605672 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 15:55:11 +0100 Subject: [PATCH 045/115] #2 Routes must be prefixed with the bundle alias => `cleverage_ui_process` --- config/routes.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/routes.yaml b/config/routes.yaml index 8cfca5b..f70ff14 100755 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1,4 +1,4 @@ -_process-ui: +_cleverage_ui_process: prefix: '/process' resource: ../src/Controller/ - type: annotation \ No newline at end of file + type: attribute From 913a51fda7563af09e1de4d9089f2a1818f0e9ad Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 17:45:02 +0100 Subject: [PATCH 046/115] #2 Update services according to Symfony best practices. Services should not use autowiring or autoconfiguration. Instead, all services should be defined explicitly. Services must be prefixed with the bundle alias instead of using fully qualified class names => `cleverage_ui_process` --- CHANGELOG.md | 11 +++- config/services.yaml | 20 ------ config/services/command.yaml | 19 ++++++ config/services/controller.yaml | 61 +++++++++++++++++++ config/services/event_subscriber.yaml | 21 +++++++ config/services/manager.yaml | 7 +++ config/services/message.yaml | 13 ++++ config/services/monolog_handler.yaml | 7 +++ config/services/parameters.yaml | 2 + config/services/repository.yaml | 19 ++++++ config/services/security.yaml | 7 +++ src/Command/PurgeProcessExecution.php | 15 +---- .../Crud/ProcessExecutionCrudController.php | 26 ++------ .../CleverAgeProcessUiExtension.php | 20 +++++- src/Entity/.gitignore | 0 .../ProcessEventSubscriber.php | 10 ++- src/Monolog/Handler/ProcessLogHandler.php | 9 +-- 17 files changed, 201 insertions(+), 66 deletions(-) delete mode 100644 config/services.yaml create mode 100644 config/services/command.yaml create mode 100644 config/services/controller.yaml create mode 100644 config/services/event_subscriber.yaml create mode 100644 config/services/manager.yaml create mode 100644 config/services/message.yaml create mode 100644 config/services/monolog_handler.yaml create mode 100644 config/services/parameters.yaml create mode 100644 config/services/repository.yaml create mode 100644 config/services/security.yaml delete mode 100644 src/Entity/.gitignore diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f309e8..9bcaf59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,18 @@ v2.0 ## BC breaks +* [#4](https://github.com/cleverage/ui-process-bundle/issues/4) Update composer : "doctrine/*" using same versions of doctrine-process-bundle. + Remove "sensio/framework-extra-bundle" & "symfony/flex". Update require-dev using "process-bundle" standard. Reinstall "symfony/debug-pack". + "symfony/*" from ^5.4 to ^6.4|^7.1 => Update changes on code. "league/flysystem-bundle" from ^2.2 to ^3.0" (same as flysystem-process-bundle). + "twig/extra-bundle" and "twig/intl-extra" to ^3.8 +* [#2](https://github.com/cleverage/ui-process-bundle/issues/2) Routes must be prefixed with the bundle alias => `cleverage_ui_process` +* [#2](https://github.com/cleverage/ui-process-bundle/issues/2) Update services according to Symfony best practices. Services should not use autowiring or autoconfiguration. Instead, all services should be defined explicitly. + Services must be prefixed with the bundle alias instead of using fully qualified class names => `cleverage_ui_process` + ### Changes -### Fixes +* [#1](https://github.com/cleverage/ui-process-bundle/issues/1) Add Makefile & .docker for local standalone usage +* [#1](https://github.com/cleverage/ui-process-bundle/issues/1) Add rector, phpstan & php-cs-fixer configurations & apply it. Remove phpcs configuration. v1.0.6 ------ diff --git a/config/services.yaml b/config/services.yaml deleted file mode 100644 index 3b371fb..0000000 --- a/config/services.yaml +++ /dev/null @@ -1,20 +0,0 @@ -parameters: - uploads_directory: '%kernel.project_dir%/public/uploads' - cleverage_processes: '%kernel.project_dir%/config/packages' - process_logs_dir: '%kernel.logs_dir%/process' - -services: - _defaults: - autowire: true - autoconfigure: true - bind: - $processLogDir: '%process_logs_dir%' - $indexLogs: '%clever_age_process_ui.index_logs.enabled%' - - CleverAge\ProcessUiBundle\: - resource: '../src' - exclude: - - '../src/DependencyInjection/' - - '../src/Entity/' - - '../src/Tests/' - - '../src/Migrations' \ No newline at end of file diff --git a/config/services/command.yaml b/config/services/command.yaml new file mode 100644 index 0000000..a7e34b6 --- /dev/null +++ b/config/services/command.yaml @@ -0,0 +1,19 @@ +services: + cleverage_ui_process.command.purge_process_execution: + class: CleverAge\ProcessUiBundle\Command\PurgeProcessExecution + public: false + tags: + - { name: console.command } + arguments: + - '@doctrine' + - '%process_logs_dir%' + + cleverage_ui_process.command.user_create: + class: CleverAge\ProcessUiBundle\Command\UserCreateCommand + public: false + tags: + - { name: console.command } + arguments: + - '@validator' + - '@security.user_password_hasher' + - '@doctrine.orm.entity_manager.abstract' diff --git a/config/services/controller.yaml b/config/services/controller.yaml new file mode 100644 index 0000000..500fb32 --- /dev/null +++ b/config/services/controller.yaml @@ -0,0 +1,61 @@ +services: + abstract_controller.locator: + class: Symfony\Component\DependencyInjection\ServiceLocator + arguments: + - router: '@router' + request_stack: '@request_stack' + http_kernel: '@http_kernel' + parameter_bag: '@parameter_bag' + # you can add more services here as you need them (e.g. the `serializer` + # service) and have a look at the AbstractController class to see + # which services are defined in the locator + + cleverage_ui_process.controller.dashboard: + class: CleverAge\ProcessUiBundle\Controller\DashboardController + public: false + tags: + - { name: controller.service_arguments } + calls: + - [setContainer, ['@abstract_controller.locator']] + + cleverage_ui_process.controller.security: + class: CleverAge\ProcessUiBundle\Controller\SecurityController + public: false + tags: + - { name: controller.service_arguments } + calls: + - [setContainer, ['@abstract_controller.locator']] + + cleverage_ui_process.controller.crud.process: + class: CleverAge\ProcessUiBundle\Controller\Crud\ProcessCrudController + public: false + tags: + - { name: controller.service_arguments } + calls: + - [setContainer, ['@abstract_controller.locator']] + arguments: + - '@cleverage_ui_process.manager.configuration' + - '@EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator' + - '@messenger.default_bus' + + cleverage_ui_process.controller.crud.process_execution: + class: CleverAge\ProcessUiBundle\Controller\Crud\ProcessExecutionCrudController + public: false + tags: + - { name: controller.service_arguments } + calls: + - [setContainer, ['@abstract_controller.locator']] + arguments: + - '%clever_age_process_ui.index_logs.enabled%' + - '%process_logs_dir%' + - '@cleverage_ui_process.manager.configuration' + + cleverage_ui_process.controller.crud.user: + class: CleverAge\ProcessUiBundle\Controller\Crud\UserCrudController + public: false + tags: + - { name: controller.service_arguments } + calls: + - [setContainer, ['@abstract_controller.locator']] + arguments: + - '@security.user_password_hasher' diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml new file mode 100644 index 0000000..08945b0 --- /dev/null +++ b/config/services/event_subscriber.yaml @@ -0,0 +1,21 @@ +services: + cleverage_ui_process.event_subscriber.process: + class: CleverAge\ProcessUiBundle\EventSubscriber\ProcessEventSubscriber + public: false + tags: + - { name: 'kernel.event_listener' } + arguments: + - '@doctrine.orm.entity_manager.abstract' + - '@cleverage_ui_process.monolog_handler.process_log' + - '@messenger.default_bus' + - '@cleverage_ui_process.manager.configuration' + - '%process_logs_dir%' + - '%clever_age_process_ui.index_logs.enabled%' + + cleverage_ui_process.event_subscriber.crud.process: + class: CleverAge\ProcessUiBundle\EventSubscriber\Crud\ProcessCrudListener + public: false + tags: + - { name: 'kernel.event_listener' } + arguments: + - '@doctrine.orm.entity_manager.abstract' diff --git a/config/services/manager.yaml b/config/services/manager.yaml new file mode 100644 index 0000000..ef4d671 --- /dev/null +++ b/config/services/manager.yaml @@ -0,0 +1,7 @@ +services: + cleverage_ui_process.manager.configuration: + class: CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager + public: false + arguments: + - '@cleverage_process.registry.process_configuration' + diff --git a/config/services/message.yaml b/config/services/message.yaml new file mode 100644 index 0000000..af59384 --- /dev/null +++ b/config/services/message.yaml @@ -0,0 +1,13 @@ +services: + cleverage_ui_process.message.log_indexer_handler: + class: CleverAge\ProcessUiBundle\Message\LogIndexerHandler + public: false + arguments: + - '@doctrine' + + cleverage_ui_process.message.process_run_handler: + class: CleverAge\ProcessUiBundle\Message\ProcessRunHandler + public: false + arguments: + - '@cleverage_process.command.execute_process' + diff --git a/config/services/monolog_handler.yaml b/config/services/monolog_handler.yaml new file mode 100644 index 0000000..cacc088 --- /dev/null +++ b/config/services/monolog_handler.yaml @@ -0,0 +1,7 @@ +services: + cleverage_ui_process.monolog_handler.process_log: + class: CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler + public: false + arguments: + - '%process_logs_dir%' + diff --git a/config/services/parameters.yaml b/config/services/parameters.yaml new file mode 100644 index 0000000..e10f4a1 --- /dev/null +++ b/config/services/parameters.yaml @@ -0,0 +1,2 @@ +parameters: + process_logs_dir: '%kernel.logs_dir%/process' diff --git a/config/services/repository.yaml b/config/services/repository.yaml new file mode 100644 index 0000000..1339da3 --- /dev/null +++ b/config/services/repository.yaml @@ -0,0 +1,19 @@ +services: + cleverage_ui_process.repository.process_execution: + class: CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository + public: false + arguments: + - '@doctrine' + + cleverage_ui_process.repository.process: + class: CleverAge\ProcessUiBundle\Repository\ProcessRepository + public: false + arguments: + - '@doctrine' + + cleverage_ui_process.repository.user: + class: CleverAge\ProcessUiBundle\Repository\UserRepository + public: false + arguments: + - '@doctrine' + diff --git a/config/services/security.yaml b/config/services/security.yaml new file mode 100644 index 0000000..ba5a36d --- /dev/null +++ b/config/services/security.yaml @@ -0,0 +1,7 @@ +services: + cleverage_ui_process.security.login_form_auth_authenticator: + class: CleverAge\ProcessUiBundle\Security\LoginFormAuthAuthenticator + public: false + arguments: + - '@router' + diff --git a/src/Command/PurgeProcessExecution.php b/src/Command/PurgeProcessExecution.php index b00c8dc..98cd318 100644 --- a/src/Command/PurgeProcessExecution.php +++ b/src/Command/PurgeProcessExecution.php @@ -24,24 +24,13 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; -use Symfony\Contracts\Service\Attribute\Required; #[AsCommand(name: 'cleverage:process-ui:purge', description: 'Purge process_execution table.')] class PurgeProcessExecution extends Command { - private ManagerRegistry $managerRegistry; - private string $processLogDir; - - #[Required] - public function setManagerRegistry(ManagerRegistry $managerRegistry): void - { - $this->managerRegistry = $managerRegistry; - } - - #[Required] - public function setProcessLogDir(string $processLogDir): void + public function __construct(private readonly ManagerRegistry $managerRegistry, private readonly string $processLogDir) { - $this->processLogDir = $processLogDir; + parent::__construct(); } protected function configure(): void diff --git a/src/Controller/Crud/ProcessExecutionCrudController.php b/src/Controller/Crud/ProcessExecutionCrudController.php index c76ca75..6bd1c10 100644 --- a/src/Controller/Crud/ProcessExecutionCrudController.php +++ b/src/Controller/Crud/ProcessExecutionCrudController.php @@ -27,30 +27,14 @@ use EasyCorp\Bundle\EasyAdminBundle\Filter\ChoiceFilter; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Contracts\Service\Attribute\Required; class ProcessExecutionCrudController extends AbstractCrudController { - private bool $indexLogs; - private string $processLogDir; - private ProcessUiConfigurationManager $processUiConfigurationManager; - - #[Required] - public function setIndexLogs(bool $indexLogs): void - { - $this->indexLogs = $indexLogs; - } - - #[Required] - public function setProcessLogDir(string $processLogDir): void - { - $this->processLogDir = $processLogDir; - } - - #[Required] - public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void - { - $this->processUiConfigurationManager = $processUiConfigurationManager; + public function __construct( + private readonly bool $indexLogs, + private readonly string $processLogDir, + private readonly ProcessUiConfigurationManager $processUiConfigurationManager, + ) { } public static function getEntityFqcn(): string diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index bfe2077..2d173d3 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -20,13 +20,13 @@ use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\Finder\Finder; class CleverAgeProcessUiExtension extends Extension implements PrependExtensionInterface { public function load(array $configs, ContainerBuilder $container): void { - $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../../config')); - $loader->load('services.yaml'); + $this->findServices($container, __DIR__.'/../../config/services'); $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); @@ -41,7 +41,7 @@ public function prepend(ContainerBuilder $container): void $container->loadFromExtension( 'doctrine_migrations', [ - 'migrations_paths' => ['CleverAgeProcessUi' => \dirname(__DIR__).'/Migrations'], + 'migrations_paths' => ['CleverAgeUiProcess' => \dirname(__DIR__).'/Migrations'], ] ); $container->loadFromExtension( @@ -69,4 +69,18 @@ public function prepend(ContainerBuilder $container): void ] ); } + + /** + * Recursively import config files into container. + */ + protected function findServices(ContainerBuilder $container, string $path, string $extension = 'yaml'): void + { + $finder = new Finder(); + $finder->in($path) + ->name('*.'.$extension)->files(); + $loader = new YamlFileLoader($container, new FileLocator($path)); + foreach ($finder as $file) { + $loader->load($file->getFilename()); + } + } } diff --git a/src/Entity/.gitignore b/src/Entity/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index f8c988b..c21a547 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -30,8 +30,14 @@ class ProcessEventSubscriber implements EventSubscriberInterface { private array $processExecution = []; - public function __construct(private readonly EntityManagerInterface $entityManager, private readonly ProcessLogHandler $processLogHandler, private readonly MessageBusInterface $messageBus, private readonly ProcessUiConfigurationManager $processUiConfigurationManager, private readonly string $processLogDir, private readonly bool $indexLogs) - { + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly ProcessLogHandler $processLogHandler, + private readonly MessageBusInterface $messageBus, + private readonly ProcessUiConfigurationManager $processUiConfigurationManager, + private readonly string $processLogDir, + private readonly bool $indexLogs, + ) { } public static function getSubscribedEvents(): array diff --git a/src/Monolog/Handler/ProcessLogHandler.php b/src/Monolog/Handler/ProcessLogHandler.php index 5dcbf01..35dcfd8 100644 --- a/src/Monolog/Handler/ProcessLogHandler.php +++ b/src/Monolog/Handler/ProcessLogHandler.php @@ -18,19 +18,16 @@ use League\Flysystem\Local\LocalFilesystemAdapter; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; -use Symfony\Contracts\Service\Attribute\Required; class ProcessLogHandler extends AbstractProcessingHandler { - private string $logDir; private ?array $logFilenames = []; private ?string $currentProcessCode = null; private ?Filesystem $filesystem = null; - #[Required] - public function setLogDir(string $processLogDir): void + public function __construct(private readonly string $processLogDir) { - $this->logDir = $processLogDir; + parent::__construct(); } /** @@ -50,7 +47,7 @@ protected function write(array $record): void if (!$this->filesystem instanceof Filesystem) { $this->filesystem = new Filesystem( - new LocalFilesystemAdapter($this->logDir, null, \FILE_APPEND) + new LocalFilesystemAdapter($this->processLogDir, null, \FILE_APPEND) ); } $this->filesystem->write($logFilename, $record['formatted']); From e62fb5eac078b22d2af69fc3274422e59cbf79e9 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 28 Oct 2024 17:57:31 +0100 Subject: [PATCH 047/115] #4 "symfony/webpack-encore-bundle" from "^1.11" to "^1.13|^2.0" --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8486f2c..7d25279 100644 --- a/composer.json +++ b/composer.json @@ -64,7 +64,7 @@ "symfony/stopwatch": "^6.4|^7.1", "symfony/twig-bundle": "^6.4|^7.1", "symfony/validator": "^6.4|^7.1", - "symfony/webpack-encore-bundle": "^1.11", + "symfony/webpack-encore-bundle": "^1.13|^2.0", "symfony/yaml": "^6.4|^7.1", "twig/extra-bundle": "^3.8", "twig/intl-extra": "^3.8" From 9c834ef5d0a34dd17eefb38cf8d72183c9f8a8cd Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 29 Oct 2024 10:29:12 +0100 Subject: [PATCH 048/115] #4 Remove "symfony/monolog-bundle" from require-dev (already required on cleverage/process-bundle) --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 7d25279..b107519 100644 --- a/composer.json +++ b/composer.json @@ -83,7 +83,6 @@ "symfony/css-selector": "^6.4|^7.1", "symfony/debug-bundle": "^6.4|^7.1", "symfony/maker-bundle": "^1.31", - "symfony/monolog-bundle": "^3.0", "symfony/phpunit-bridge": "^7.1", "symfony/web-profiler-bundle": "^6.4|^7.1" }, From a49d7f572080b5f3a66c442ba0b44dbb91a40559 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 29 Oct 2024 11:08:17 +0100 Subject: [PATCH 049/115] #4 Replace "ddtraceweb/monolog-parser": "^1.3" by "syonix/monolog-parser": "dev-master" to fix monolog/monolog dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b107519..ae5283a 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,6 @@ "ext-ctype": "*", "ext-iconv": "*", "cleverage/process-bundle": "dev-prepare-release", - "ddtraceweb/monolog-parser": "^1.3", "doctrine/common": "^3.0", "doctrine/dbal": "^2.9 || ^3.0", "doctrine/doctrine-bundle": "^2.5", @@ -66,6 +65,7 @@ "symfony/validator": "^6.4|^7.1", "symfony/webpack-encore-bundle": "^1.13|^2.0", "symfony/yaml": "^6.4|^7.1", + "syonix/monolog-parser": "dev-master", "twig/extra-bundle": "^3.8", "twig/intl-extra": "^3.8" }, From 94e776a078bb139a56029ea1210aa8535c495e47 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 29 Oct 2024 11:29:57 +0100 Subject: [PATCH 050/115] #4 Apply quality stack after updating monolog-parser which bump "monolog/monolog" from "1.*" to "3.*" --- src/Message/LogIndexerHandler.php | 2 +- src/Monolog/Handler/ProcessLogHandler.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Message/LogIndexerHandler.php b/src/Message/LogIndexerHandler.php index 8cb7836..7c9f226 100644 --- a/src/Message/LogIndexerHandler.php +++ b/src/Message/LogIndexerHandler.php @@ -43,7 +43,7 @@ public function __invoke(LogIndexerMessage $logIndexerMessage): void /** @var string $currentLine */ $currentLine = $file->current(); $parsedLine = $parser->parse($currentLine); - if (!empty($parsedLine) && true === ($parsedLine['context'][self::INDEX_LOG_RECORD] ?? false)) { + if ([] !== $parsedLine && true === ($parsedLine['context'][self::INDEX_LOG_RECORD] ?? false)) { $parameters[] = $logIndexerMessage->getProcessExecutionId(); $parameters[] = Logger::toMonologLevel($parsedLine['level']); $parameters[] = substr((string) $parsedLine['message'], 0, 255); diff --git a/src/Monolog/Handler/ProcessLogHandler.php b/src/Monolog/Handler/ProcessLogHandler.php index 35dcfd8..131bc39 100644 --- a/src/Monolog/Handler/ProcessLogHandler.php +++ b/src/Monolog/Handler/ProcessLogHandler.php @@ -17,7 +17,8 @@ use League\Flysystem\FilesystemException; use League\Flysystem\Local\LocalFilesystemAdapter; use Monolog\Handler\AbstractProcessingHandler; -use Monolog\Logger; +use Monolog\Level; +use Monolog\LogRecord; class ProcessLogHandler extends AbstractProcessingHandler { @@ -35,13 +36,13 @@ public function __construct(private readonly string $processLogDir) * * @throws FilesystemException */ - protected function write(array $record): void + protected function write(array|LogRecord $record): void { if (null === $logFilename = ($this->logFilenames[$this->currentProcessCode] ?? null)) { return; } - if ($record['level'] < Logger::INFO) { + if ($record['level'] < Level::Info) { return; } From 27694a495a559d1f2cfda6809db3554adc6382ac Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 29 Oct 2024 11:39:43 +0100 Subject: [PATCH 051/115] #4 Remove require-dev dependency on "symfony/phpunit-bridge" --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index ae5283a..038bd51 100644 --- a/composer.json +++ b/composer.json @@ -83,7 +83,6 @@ "symfony/css-selector": "^6.4|^7.1", "symfony/debug-bundle": "^6.4|^7.1", "symfony/maker-bundle": "^1.31", - "symfony/phpunit-bridge": "^7.1", "symfony/web-profiler-bundle": "^6.4|^7.1" }, "config": { From 314c038ed4df983a2f73f5fa31e5b7148116c9bb Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 29 Oct 2024 16:57:00 +0100 Subject: [PATCH 052/115] #1 Apply <10.0 restriction on phpunit/phpunit since configuration file is not compatible with 10.0+ --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 038bd51..79f9f6f 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "phpstan/phpstan": "*", "phpstan/phpstan-doctrine": "*", "phpstan/phpstan-symfony": "*", - "phpunit/phpunit": "*", + "phpunit/phpunit": "<10.0", "rector/rector": "*", "roave/security-advisories": "dev-latest", "symfony/browser-kit": "^6.4|^7.1", From 7cec21e515bf3d99d26d21bacb10aadd2501b428 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 30 Oct 2024 10:48:04 +0100 Subject: [PATCH 053/115] #2 Fix some services definitions --- config/services/command.yaml | 2 +- config/services/event_subscriber.yaml | 6 +++--- .../Compiler/RegisterLogHandlerCompilerPass.php | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/config/services/command.yaml b/config/services/command.yaml index a7e34b6..9794de5 100644 --- a/config/services/command.yaml +++ b/config/services/command.yaml @@ -16,4 +16,4 @@ services: arguments: - '@validator' - '@security.user_password_hasher' - - '@doctrine.orm.entity_manager.abstract' + - '@doctrine.orm.entity_manager' diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml index 08945b0..3af20fc 100644 --- a/config/services/event_subscriber.yaml +++ b/config/services/event_subscriber.yaml @@ -3,9 +3,9 @@ services: class: CleverAge\ProcessUiBundle\EventSubscriber\ProcessEventSubscriber public: false tags: - - { name: 'kernel.event_listener' } + - { name: 'kernel.event_subscriber' } arguments: - - '@doctrine.orm.entity_manager.abstract' + - '@doctrine.orm.entity_manager' - '@cleverage_ui_process.monolog_handler.process_log' - '@messenger.default_bus' - '@cleverage_ui_process.manager.configuration' @@ -18,4 +18,4 @@ services: tags: - { name: 'kernel.event_listener' } arguments: - - '@doctrine.orm.entity_manager.abstract' + - '@doctrine.orm.event_subscriber' diff --git a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php b/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php index da0eddd..8624a45 100644 --- a/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php +++ b/src/DependencyInjection/Compiler/RegisterLogHandlerCompilerPass.php @@ -13,7 +13,6 @@ namespace CleverAge\ProcessUiBundle\DependencyInjection\Compiler; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -31,7 +30,7 @@ public function process(ContainerBuilder $container): void if ($container->has($logger)) { $container ->getDefinition($logger) - ->addMethodCall('pushHandler', [new Reference(ProcessLogHandler::class)]); + ->addMethodCall('pushHandler', [new Reference('cleverage_ui_process.monolog_handler.process_log')]); } } } From ca7fe4e4a72a498cf2d5575a838f79a9d6a8283c Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 30 Oct 2024 10:52:45 +0100 Subject: [PATCH 054/115] #2 Rollback controller services defintion that doesn't work with EasyAdmin --- config/services/controller.yaml | 65 +++------------------------------ 1 file changed, 5 insertions(+), 60 deletions(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 500fb32..3ab4252 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -1,61 +1,6 @@ services: - abstract_controller.locator: - class: Symfony\Component\DependencyInjection\ServiceLocator - arguments: - - router: '@router' - request_stack: '@request_stack' - http_kernel: '@http_kernel' - parameter_bag: '@parameter_bag' - # you can add more services here as you need them (e.g. the `serializer` - # service) and have a look at the AbstractController class to see - # which services are defined in the locator - - cleverage_ui_process.controller.dashboard: - class: CleverAge\ProcessUiBundle\Controller\DashboardController - public: false - tags: - - { name: controller.service_arguments } - calls: - - [setContainer, ['@abstract_controller.locator']] - - cleverage_ui_process.controller.security: - class: CleverAge\ProcessUiBundle\Controller\SecurityController - public: false - tags: - - { name: controller.service_arguments } - calls: - - [setContainer, ['@abstract_controller.locator']] - - cleverage_ui_process.controller.crud.process: - class: CleverAge\ProcessUiBundle\Controller\Crud\ProcessCrudController - public: false - tags: - - { name: controller.service_arguments } - calls: - - [setContainer, ['@abstract_controller.locator']] - arguments: - - '@cleverage_ui_process.manager.configuration' - - '@EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator' - - '@messenger.default_bus' - - cleverage_ui_process.controller.crud.process_execution: - class: CleverAge\ProcessUiBundle\Controller\Crud\ProcessExecutionCrudController - public: false - tags: - - { name: controller.service_arguments } - calls: - - [setContainer, ['@abstract_controller.locator']] - arguments: - - '%clever_age_process_ui.index_logs.enabled%' - - '%process_logs_dir%' - - '@cleverage_ui_process.manager.configuration' - - cleverage_ui_process.controller.crud.user: - class: CleverAge\ProcessUiBundle\Controller\Crud\UserCrudController - public: false - tags: - - { name: controller.service_arguments } - calls: - - [setContainer, ['@abstract_controller.locator']] - arguments: - - '@security.user_password_hasher' + CleverAge\ProcessUiBundle\Controller\: + resource: '../../src/Controller/' + autowire: true + autoconfigure: true + tags: [ 'controller.service_arguments' ] From 6bcf10a6470e06f323f9a2c29e4b8125f4881c1c Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 30 Oct 2024 13:39:42 +0100 Subject: [PATCH 055/115] #2 Fix some services & controllers definitions --- config/services/controller.yaml | 6 +++++- config/services/event_subscriber.yaml | 4 ++-- config/services/manager.yaml | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 3ab4252..90405a3 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -3,4 +3,8 @@ services: resource: '../../src/Controller/' autowire: true autoconfigure: true - tags: [ 'controller.service_arguments' ] + bind: + $processLogDir: '%process_logs_dir%' + $indexLogs: '%clever_age_process_ui.index_logs.enabled%' + tags: + - { name: 'controller.service_arguments' } diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml index 3af20fc..c249377 100644 --- a/config/services/event_subscriber.yaml +++ b/config/services/event_subscriber.yaml @@ -16,6 +16,6 @@ services: class: CleverAge\ProcessUiBundle\EventSubscriber\Crud\ProcessCrudListener public: false tags: - - { name: 'kernel.event_listener' } + - { name: 'kernel.event_subscriber' } arguments: - - '@doctrine.orm.event_subscriber' + - '@doctrine.orm.entity_manager' diff --git a/config/services/manager.yaml b/config/services/manager.yaml index ef4d671..973a110 100644 --- a/config/services/manager.yaml +++ b/config/services/manager.yaml @@ -5,3 +5,5 @@ services: arguments: - '@cleverage_process.registry.process_configuration' + CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager: + alias: 'cleverage_ui_process.manager.configuration' From c10cf5c28231d4533b44c190de7c436bd04c7d49 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 30 Oct 2024 17:20:01 +0100 Subject: [PATCH 056/115] #2 Update repositories definitions (that doesn't work on vendor when using ServiceEntityRepository / repositoryClass: ***) with Doctrine\ORM\EntityRepository. Update others services to use injected repostories services instead of $em->getRepository(....) --- config/services/command.yaml | 2 +- config/services/event_subscriber.yaml | 3 +- config/services/repository.yaml | 8 +++-- src/Command/PurgeProcessExecution.php | 12 +++---- src/Entity/Process.php | 3 +- src/Entity/ProcessExecution.php | 3 +- src/Entity/User.php | 3 +- .../Crud/ProcessCrudListener.php | 7 ++-- .../ProcessEventSubscriber.php | 9 ++--- src/Repository/ProcessExecutionRepository.php | 12 +++---- src/Repository/ProcessRepository.php | 33 ++++++------------- src/Repository/UserRepository.php | 12 +++---- 12 files changed, 43 insertions(+), 64 deletions(-) diff --git a/config/services/command.yaml b/config/services/command.yaml index 9794de5..73f5b02 100644 --- a/config/services/command.yaml +++ b/config/services/command.yaml @@ -5,7 +5,7 @@ services: tags: - { name: console.command } arguments: - - '@doctrine' + - '@cleverage_ui_process.repository.process_execution' - '%process_logs_dir%' cleverage_ui_process.command.user_create: diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml index 3af20fc..984045d 100644 --- a/config/services/event_subscriber.yaml +++ b/config/services/event_subscriber.yaml @@ -6,6 +6,7 @@ services: - { name: 'kernel.event_subscriber' } arguments: - '@doctrine.orm.entity_manager' + - '@cleverage_ui_process.repository.process' - '@cleverage_ui_process.monolog_handler.process_log' - '@messenger.default_bus' - '@cleverage_ui_process.manager.configuration' @@ -18,4 +19,4 @@ services: tags: - { name: 'kernel.event_listener' } arguments: - - '@doctrine.orm.event_subscriber' + - '@cleverage_ui_process.repository.process' diff --git a/config/services/repository.yaml b/config/services/repository.yaml index 1339da3..0456ccc 100644 --- a/config/services/repository.yaml +++ b/config/services/repository.yaml @@ -3,17 +3,19 @@ services: class: CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository public: false arguments: - - '@doctrine' + - '@doctrine.orm.entity_manager' cleverage_ui_process.repository.process: class: CleverAge\ProcessUiBundle\Repository\ProcessRepository public: false arguments: - - '@doctrine' + - '@doctrine.orm.entity_manager' + - '@cleverage_ui_process.manager.configuration' + - '@cleverage_process.registry.process_configuration' cleverage_ui_process.repository.user: class: CleverAge\ProcessUiBundle\Repository\UserRepository public: false arguments: - - '@doctrine' + - '@doctrine.orm.entity_manager' diff --git a/src/Command/PurgeProcessExecution.php b/src/Command/PurgeProcessExecution.php index 98cd318..a7c19ed 100644 --- a/src/Command/PurgeProcessExecution.php +++ b/src/Command/PurgeProcessExecution.php @@ -13,9 +13,7 @@ namespace CleverAge\ProcessUiBundle\Command; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; -use Doctrine\Persistence\ManagerRegistry; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputDefinition; @@ -28,8 +26,10 @@ #[AsCommand(name: 'cleverage:process-ui:purge', description: 'Purge process_execution table.')] class PurgeProcessExecution extends Command { - public function __construct(private readonly ManagerRegistry $managerRegistry, private readonly string $processLogDir) - { + public function __construct( + private readonly ProcessExecutionRepository $processExecutionRepository, + private readonly string $processLogDir, + ) { parent::__construct(); } @@ -69,9 +69,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $fs->remove($finder); $output->writeln("$count log files are deleted on filesystem."); } - /** @var ProcessExecutionRepository $repository */ - $repository = $this->managerRegistry->getRepository(ProcessExecution::class); - $repository->deleteBefore($date); + $this->processExecutionRepository->deleteBefore($date); $output->writeln(<<Process Execution before {$date->format(\DateTimeInterface::ATOM)} are deleted into database. diff --git a/src/Entity/Process.php b/src/Entity/Process.php index 217b5e7..5913152 100644 --- a/src/Entity/Process.php +++ b/src/Entity/Process.php @@ -13,13 +13,12 @@ namespace CleverAge\ProcessUiBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\ProcessRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -#[ORM\Entity(repositoryClass: ProcessRepository::class)] +#[ORM\Entity] class Process { #[ORM\Id] diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 8967623..d5a60e9 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -13,13 +13,12 @@ namespace CleverAge\ProcessUiBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -#[ORM\Entity(repositoryClass: ProcessExecutionRepository::class)] +#[ORM\Entity] class ProcessExecution { public const STATUS_START = 0; diff --git a/src/Entity/User.php b/src/Entity/User.php index 8f12f2f..07a1943 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -13,13 +13,12 @@ namespace CleverAge\ProcessUiBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\UserRepository; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; -#[ORM\Entity(repositoryClass: UserRepository::class)] +#[ORM\Entity] #[ORM\Table(name: 'user')] class User implements UserInterface, PasswordAuthenticatedUserInterface { diff --git a/src/EventSubscriber/Crud/ProcessCrudListener.php b/src/EventSubscriber/Crud/ProcessCrudListener.php index c272580..caadd65 100644 --- a/src/EventSubscriber/Crud/ProcessCrudListener.php +++ b/src/EventSubscriber/Crud/ProcessCrudListener.php @@ -15,13 +15,12 @@ use CleverAge\ProcessUiBundle\Entity\Process; use CleverAge\ProcessUiBundle\Repository\ProcessRepository; -use Doctrine\ORM\EntityManagerInterface; use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ProcessCrudListener implements EventSubscriberInterface { - public function __construct(private readonly EntityManagerInterface $entityManager) + public function __construct(private readonly ProcessRepository $processRepository) { } @@ -36,9 +35,7 @@ public static function getSubscribedEvents(): array public function syncProcessIntoDatabase(BeforeCrudActionEvent $event): void { if (Process::class === $event->getAdminContext()?->getEntity()->getFqcn()) { - /** @var ProcessRepository $repository */ - $repository = $this->entityManager->getRepository(Process::class); - $repository->sync(); + $this->processRepository->sync(); } } } diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index c21a547..15c51d7 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -14,7 +14,6 @@ namespace CleverAge\ProcessUiBundle\EventSubscriber; use CleverAge\ProcessBundle\Event\ProcessEvent; -use CleverAge\ProcessUiBundle\Entity\Process; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; use CleverAge\ProcessUiBundle\Event\IncrementReportInfoEvent; use CleverAge\ProcessUiBundle\Event\SetReportInfoEvent; @@ -32,6 +31,7 @@ class ProcessEventSubscriber implements EventSubscriberInterface public function __construct( private readonly EntityManagerInterface $entityManager, + private readonly ProcessRepository $processRepository, private readonly ProcessLogHandler $processLogHandler, private readonly MessageBusInterface $messageBus, private readonly ProcessUiConfigurationManager $processUiConfigurationManager, @@ -64,8 +64,7 @@ public static function getSubscribedEvents(): array public function onProcessStarted(ProcessEvent $event): void { - $process = $this->entityManager->getRepository(Process::class) - ->findOneBy(['processCode' => $event->getProcessCode()]); + $process = $this->processRepository->findOneBy(['processCode' => $event->getProcessCode()]); if (null === $process) { throw new \RuntimeException('Unable to found process into database.'); } @@ -121,9 +120,7 @@ public function onProcessFailed(ProcessEvent $processEvent): void public function syncProcessIntoDatabase(): void { - /** @var ProcessRepository $repository */ - $repository = $this->entityManager->getRepository(Process::class); - $repository->sync(); + $this->processRepository->sync(); } protected function dispatchLogIndexerMessage(ProcessExecution $processExecution): void diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index 07c8cb9..3a52f65 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -14,17 +14,17 @@ namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; /** - * @extends ServiceEntityRepository + * @extends EntityRepository */ -class ProcessExecutionRepository extends ServiceEntityRepository +class ProcessExecutionRepository extends EntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct(EntityManagerInterface $em) { - parent::__construct($registry, ProcessExecution::class); + parent::__construct($em, $em->getClassMetadata(ProcessExecution::class)); } /** diff --git a/src/Repository/ProcessRepository.php b/src/Repository/ProcessRepository.php index c0eb33f..7cbaa25 100644 --- a/src/Repository/ProcessRepository.php +++ b/src/Repository/ProcessRepository.php @@ -16,33 +16,20 @@ use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use CleverAge\ProcessUiBundle\Entity\Process; use CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\Persistence\ManagerRegistry; -use Symfony\Contracts\Service\Attribute\Required; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; /** - * @extends ServiceEntityRepository + * @extends EntityRepository */ -class ProcessRepository extends ServiceEntityRepository +class ProcessRepository extends EntityRepository { - private ProcessUiConfigurationManager $processUiConfigurationManager; - private ProcessConfigurationRegistry $processConfigurationRegistry; - - #[Required] - public function setProcessUiConfigurationManager(ProcessUiConfigurationManager $processUiConfigurationManager): void - { - $this->processUiConfigurationManager = $processUiConfigurationManager; - } - - #[Required] - public function setProcessConfigurationRegistry(ProcessConfigurationRegistry $processConfigurationRegistry): void - { - $this->processConfigurationRegistry = $processConfigurationRegistry; - } - - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, Process::class); + public function __construct( + EntityManagerInterface $em, + private readonly ProcessUiConfigurationManager $processUiConfigurationManager, + private readonly ProcessConfigurationRegistry $processConfigurationRegistry, + ) { + parent::__construct($em, $em->getClassMetadata(Process::class)); } public function sync(): void diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 366e57d..d9ed2db 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -14,20 +14,20 @@ namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessUiBundle\Entity\User; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; /** - * @extends ServiceEntityRepository + * @extends EntityRepository */ -class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface +class UserRepository extends EntityRepository implements PasswordUpgraderInterface { - public function __construct(ManagerRegistry $registry) + public function __construct(EntityManagerInterface $em) { - parent::__construct($registry, User::class); + parent::__construct($em, $em->getClassMetadata(User::class)); } /** From e3bc44f2886449a2b5920756fe8c54970952a291 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 30 Oct 2024 17:26:01 +0100 Subject: [PATCH 057/115] #2 Remove wrong readonly on Process.$executions --- src/Entity/Process.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Process.php b/src/Entity/Process.php index 5913152..d26dd2b 100644 --- a/src/Entity/Process.php +++ b/src/Entity/Process.php @@ -30,7 +30,7 @@ class Process * @var Collection */ #[ORM\OneToMany(targetEntity: ProcessExecution::class, mappedBy: 'process')] - private readonly Collection $executions; + private Collection $executions; public function __construct( #[ORM\Column(name: 'process_code', type: Types::TEXT, length: 255)] From 363d20428ee4a7f479512aa152a976a299dee81a Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 10:11:00 +0100 Subject: [PATCH 058/115] Fix migrations_paths namespace --- src/DependencyInjection/CleverAgeProcessUiExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index 2d173d3..65fd2af 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -41,7 +41,7 @@ public function prepend(ContainerBuilder $container): void $container->loadFromExtension( 'doctrine_migrations', [ - 'migrations_paths' => ['CleverAgeUiProcess' => \dirname(__DIR__).'/Migrations'], + 'migrations_paths' => ['CleverAge\ProcessUiBundle\Migrations' => \dirname(__DIR__).'/Migrations'], ] ); $container->loadFromExtension( From ec7a5943261c3532e650dc168f7dd1de89190d81 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 10:35:21 +0100 Subject: [PATCH 059/115] Remove deprecated github actions --- .github/workflows/php.yml | 32 ------------------------------ .github/workflows/super-linter.yml | 19 ------------------ 2 files changed, 51 deletions(-) delete mode 100644 .github/workflows/php.yml delete mode 100644 .github/workflows/super-linter.yml diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml deleted file mode 100644 index 8231bcc..0000000 --- a/.github/workflows/php.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: PHP Composer - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Validate composer.json and composer.lock - run: composer validate --strict - - name: Cache Composer packages - id: composer-cache - uses: actions/cache@v3 - with: - path: vendor - key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-php- - - - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-scripts - - # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" - # Docs: https://getcomposer.org/doc/articles/scripts.md - - # - name: Run test suite - # run: composer run-script test diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml deleted file mode 100644 index c8b12a9..0000000 --- a/.github/workflows/super-linter.yml +++ /dev/null @@ -1,19 +0,0 @@ -# It checks the syntax of the PHP code (using PHP-CS-Fixer) -name: "Linter: Code Syntax" - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] -jobs: - php-cs-fixer: - name: PHP-CS-Fixer - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - # see https://github.com/OskarStark/php-cs-fixer-ga - - name: PHP-CS-Fixer - uses: docker://oskarstark/php-cs-fixer-ga - with: - args: --diff --dry-run From 6aaf59a304dd5a0c2b50d493e652e86e5b7605ec Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 11:23:56 +0100 Subject: [PATCH 060/115] Fix composer.json & remove sqlite support from DoctrineMigrations --- README.md | 7 +- composer.json | 93 ++++++++++--------- src/Migrations/Version20231006111525.php | 35 ++----- src/Migrations/Version20240729151928.php | 6 +- src/Migrations/Version20240730090403.php | 2 +- src/Migrations/Version20241007134542.php | 2 +- src/Migrations/Version20241007152613.php | 2 +- src/Migrations/Version20241009075733.php | 2 +- .../Handler/DoctrineProcessHandler.php | 2 +- 9 files changed, 67 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index e694372..4e4fa1f 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,8 @@ A simple UX for cleverage/processbundle using EasyAdmin **Installation** * Import routes ```yaml -#config/routes.yaml -processui: - resource: '@CleverAgeProcessUiBundle/src/Controller' type: attribute +processui: + resource: '@CleverAgeProcessUiBundle/src/Controller' type: attribute ``` * Run doctrine migration * Create an user using cleverage:process-ui:user-create console. @@ -99,4 +98,4 @@ stdout_logfile=/var/log/supervisor.process-out.log user=www-data killasgroup=true stopasgroup=true -``` \ No newline at end of file +``` diff --git a/composer.json b/composer.json index ec1fd81..a5d2894 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,18 @@ { - "name": "cleverage/process-bundle-ui", + "name": "cleverage/ui-process-bundle", + "description": "UI for cleverage/process-bundle", + "keywords": [ + "process", + "task", + "etl", + "transformation", + "import", + "export", + "ui" + ], + "homepage": "https://github.com/cleverage/ui-process-bundle", "type": "symfony-bundle", "license": "MIT", - "description": "UI for cleverage/process-bundle", "authors": [ { "name": "Grégory Tonon", @@ -15,58 +25,57 @@ "role": "Developer" } ], + "autoload": { + "psr-4": { + "CleverAge\\ProcessUiBundle\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "CleverAge\\ProcessUiBundle\\Tests\\": "tests/" + } + }, "require": { "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", "ext-pcntl": "*", - "cleverage/process-bundle": "dev-v4-dev", - "symfony/flex": "^2", - "symfony/orm-pack": "^v2.4", - "symfony/dotenv": "^6.4", - "symfony/uid": "^6.4", - "symfony/string": "^6.4", - "symfony/messenger": "^6.4", - "symfony/runtime": "^6.4", - "symfony/doctrine-messenger": "^6.4", + "cleverage/process-bundle": "dev-prepare-release", + "doctrine/common": "^3.0", + "doctrine/dbal": "^2.9 || ^3.0", + "doctrine/doctrine-bundle": "^2.5", + "doctrine/doctrine-migrations-bundle": "^3.2", + "doctrine/orm": "^2.9 || ^3.0", + "symfony/dotenv": "^6.4|^7.1", + "symfony/uid": "^6.4|^7.1", + "symfony/string": "^6.4|^7.1", + "symfony/messenger": "^6.4|^7.1", + "symfony/runtime": "^6.4|^7.1", + "symfony/doctrine-messenger": "^6.4|^7.1", "easycorp/easyadmin-bundle": "^4.8" }, "require-dev": { - "vincentlanglet/twig-cs-fixer": "1.4.0" + "doctrine/doctrine-fixtures-bundle": "^3.4", + "friendsofphp/php-cs-fixer": "*", + "phpstan/extension-installer": "*", + "phpstan/phpstan": "*", + "phpstan/phpstan-doctrine": "*", + "phpstan/phpstan-symfony": "*", + "phpunit/phpunit": "<10.0", + "rector/rector": "*", + "roave/security-advisories": "dev-latest", + "symfony/browser-kit": "^6.4|^7.1", + "symfony/css-selector": "^6.4|^7.1", + "symfony/debug-bundle": "^6.4|^7.1", + "symfony/maker-bundle": "^1.31", + "symfony/web-profiler-bundle": "^6.4|^7.1" }, "config": { - "optimize-autoloader": true, - "preferred-install": { - "*": "dist" - }, - "sort-packages": true, "allow-plugins": { - "composer/package-versions-deprecated": true, + "phpstan/extension-installer": true, "symfony/flex": true, - "symfony/runtime": true, - "phpstan/extension-installer": true - } - }, - "autoload": { - "psr-4": { - "CleverAge\\ProcessUiBundle\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "CleverAge\\ProcessUiBundle\\Tests\\": "tests/" - } - }, - "scripts": { - "auto-scripts": { - "cache:clear": "symfony-cmd", - "assets:install %PUBLIC_DIR%": "symfony-cmd" + "symfony/runtime": true }, - "post-install-cmd": [ - "@auto-scripts" - ], - "post-update-cmd": [ - "@auto-scripts" - ] + "sort-packages": true } } diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php index 9cfabc3..583f88f 100644 --- a/src/Migrations/Version20231006111525.php +++ b/src/Migrations/Version20231006111525.php @@ -4,6 +4,9 @@ namespace CleverAge\ProcessUiBundle\Migrations; +use Doctrine\DBAL\Platforms\MariaDBPlatform; +use Doctrine\DBAL\Platforms\MySQLPlatform; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; @@ -11,38 +14,14 @@ final class Version20231006111525 extends AbstractMigration { public function getDescription(): string { - return ''; + return 'Create tables log_record, process_execution and process_user'; } public function up(Schema $schema): void { - $platform = $this->connection->getDatabasePlatform()->getName(); - if ('sqlite' === $platform) { - if (!$schema->hasTable('log_record')) { - $this->addSql('CREATE TABLE log_record (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, process_execution_id INTEGER DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INTEGER NOT NULL, message VARCHAR(512) NOT NULL, context CLOB NOT NULL --(DC2Type:json) - , created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) - , CONSTRAINT FK_8ECECC333DAC0075 FOREIGN KEY (process_execution_id) REFERENCES process_execution (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)'); - $this->addSql('CREATE INDEX IDX_8ECECC333DAC0075 ON log_record (process_execution_id)'); - $this->addSql('CREATE INDEX idx_log_record_level ON log_record (level)'); - $this->addSql('CREATE INDEX idx_log_record_created_at ON log_record (created_at)'); - } - if (!$schema->hasTable('process_execution')) { - $this->addSql('CREATE TABLE process_execution (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, code VARCHAR(255) NOT NULL, log_filename VARCHAR(255) NOT NULL, start_date DATETIME NOT NULL --(DC2Type:datetime_immutable) - , end_date DATETIME DEFAULT NULL --(DC2Type:datetime_immutable) - , status VARCHAR(255) NOT NULL, report CLOB NOT NULL --(DC2Type:json) - )'); - $this->addSql('CREATE INDEX idx_process_execution_code ON process_execution (code)'); - $this->addSql('CREATE INDEX idx_process_execution_start_date ON process_execution (start_date)'); - } - if (!$schema->hasTable('process_user')) { - $this->addSql('CREATE TABLE process_user (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, email VARCHAR(255) NOT NULL, firstname VARCHAR(255) DEFAULT NULL, lastname VARCHAR(255) DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:json) - , password VARCHAR(255) DEFAULT NULL)'); - $this->addSql('CREATE UNIQUE INDEX UNIQ_627A047CE7927C74 ON process_user (email)'); - $this->addSql('CREATE INDEX idx_process_user_email ON process_user (email)'); - } - } + $platform = $this->connection->getDatabasePlatform(); - if ('mysql' === $platform) { + if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE TABLE log_record (id INT AUTO_INCREMENT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL COMMENT \'(DC2Type:json)\', created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_8ECECC333DAC0075 (process_execution_id), INDEX idx_log_record_level (level), INDEX idx_log_record_created_at (created_at), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); } @@ -55,7 +34,7 @@ public function up(Schema $schema): void } } - if ('postgresql' === $platform) { + if ($platform instanceof PostgreSQLPlatform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE SEQUENCE log_record_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); $this->addSql('CREATE TABLE log_record (id INT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php index 1ddabe2..8793abb 100644 --- a/src/Migrations/Version20240729151928.php +++ b/src/Migrations/Version20240729151928.php @@ -18,7 +18,7 @@ final class Version20240729151928 extends AbstractMigration { public function getDescription(): string { - return ''; + return 'Create table process_schedule'; } public function up(Schema $schema): void @@ -27,10 +27,6 @@ public function up(Schema $schema): void if ($platform instanceof PostgreSQLPlatform) { $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL, PRIMARY KEY(id))'); } - if ($platform instanceof SqlitePlatform) { - $this->addSql('CREATE TABLE process_schedule (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input CLOB DEFAULT NULL, context CLOB NOT NULL --(DC2Type:json) -);'); - } if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL COMMENT \'(DC2Type:json)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;'); diff --git a/src/Migrations/Version20240730090403.php b/src/Migrations/Version20240730090403.php index be4aeee..6524be0 100644 --- a/src/Migrations/Version20240730090403.php +++ b/src/Migrations/Version20240730090403.php @@ -14,7 +14,7 @@ final class Version20240730090403 extends AbstractMigration { public function getDescription(): string { - return ''; + return 'Add process_user.token'; } public function up(Schema $schema): void diff --git a/src/Migrations/Version20241007134542.php b/src/Migrations/Version20241007134542.php index 259c62f..226efe3 100644 --- a/src/Migrations/Version20241007134542.php +++ b/src/Migrations/Version20241007134542.php @@ -14,7 +14,7 @@ final class Version20241007134542 extends AbstractMigration { public function getDescription(): string { - return 'Add timezone field to user.'; + return 'Add process_user.timezone'; } public function up(Schema $schema): void diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php index 5785598..cd03460 100644 --- a/src/Migrations/Version20241007152613.php +++ b/src/Migrations/Version20241007152613.php @@ -14,7 +14,7 @@ final class Version20241007152613 extends AbstractMigration { public function getDescription(): string { - return 'Add context to process execution'; + return 'Add process_execution.context'; } public function up(Schema $schema): void diff --git a/src/Migrations/Version20241009075733.php b/src/Migrations/Version20241009075733.php index 1281ae3..fe4396d 100644 --- a/src/Migrations/Version20241009075733.php +++ b/src/Migrations/Version20241009075733.php @@ -11,7 +11,7 @@ final class Version20241009075733 extends AbstractMigration { public function getDescription(): string { - return 'Add locale to user'; + return 'Add process_user.locale'; } public function up(Schema $schema): void diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index d2159c1..20b9c39 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -14,7 +14,7 @@ class DoctrineProcessHandler extends AbstractProcessingHandler { - /** @psalm-var ArrayCollection */ + /** @var ArrayCollection */ private ArrayCollection $records; private ?ProcessExecutionManager $processExecutionManager; private ?EntityManagerInterface $em = null; From 4bdacb241a7882a3a9e4828edaeb99e0b4b1546e Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 16:10:22 +0100 Subject: [PATCH 061/115] composer require symfony/scheduler && remove ext-pcntl --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index a5d2894..2a7ee55 100644 --- a/composer.json +++ b/composer.json @@ -39,20 +39,20 @@ "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", - "ext-pcntl": "*", "cleverage/process-bundle": "dev-prepare-release", "doctrine/common": "^3.0", "doctrine/dbal": "^2.9 || ^3.0", "doctrine/doctrine-bundle": "^2.5", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.9 || ^3.0", + "easycorp/easyadmin-bundle": "^4.8", + "symfony/doctrine-messenger": "^6.4|^7.1", "symfony/dotenv": "^6.4|^7.1", - "symfony/uid": "^6.4|^7.1", - "symfony/string": "^6.4|^7.1", "symfony/messenger": "^6.4|^7.1", "symfony/runtime": "^6.4|^7.1", - "symfony/doctrine-messenger": "^6.4|^7.1", - "easycorp/easyadmin-bundle": "^4.8" + "symfony/scheduler": "^6.4|^7.1", + "symfony/string": "^6.4|^7.1", + "symfony/uid": "^6.4|^7.1" }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^3.4", From a3303c22fba6f3860bc4d8e8bef413d7418da15d Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 16:10:34 +0100 Subject: [PATCH 062/115] Apply quality rules --- src/Admin/Field/EnumField.php | 9 ++++ src/Admin/Field/LogLevelField.php | 9 ++++ src/Admin/Filter/LogProcessFilter.php | 18 +++++-- src/Command/UserCreateCommand.php | 2 +- .../Admin/LogRecordCrudController.php | 13 ++++- src/Controller/Admin/Process/LaunchAction.php | 21 ++++++--- src/Controller/Admin/Process/ListAction.php | 12 ++++- .../Admin/Process/UploadAndExecuteAction.php | 18 +++++-- .../Admin/ProcessDashboardController.php | 16 +++++-- .../Admin/ProcessExecutionCrudController.php | 13 ++++- .../Admin/ProcessScheduleCrudController.php | 47 +++++++++---------- .../Admin/Security/LoginController.php | 12 ++++- .../Admin/Security/LogoutController.php | 12 ++++- src/Controller/Admin/UserCrudController.php | 37 ++++++++------- src/Controller/ProcessExecuteController.php | 13 ++++- .../CleverAgeProcessUiExtension.php | 24 +++++----- src/Entity/Enum/ProcessExecutionStatus.php | 9 ++++ src/Entity/LogRecord.php | 30 +++++++----- src/Entity/ProcessExecution.php | 18 +++---- src/Entity/ProcessSchedule.php | 15 ++++-- src/Entity/User.php | 32 ++++++------- .../ProcessEventSubscriber.php | 20 ++++---- src/Form/Type/LaunchType.php | 22 +++++---- src/Form/Type/ProcessContextType.php | 9 ++++ src/Form/Type/ProcessUploadFileType.php | 9 ++++ src/Http/Model/HttpProcessExecution.php | 11 ++++- .../HttpProcessExecuteValueResolver.php | 11 ++++- .../ProcessConfigurationValueResolver.php | 9 ++++ src/Manager/ProcessConfigurationsManager.php | 13 +++-- src/Manager/ProcessExecutionManager.php | 13 ++++- src/Message/CronProcessMessage.php | 9 ++++ src/Message/CronProcessMessageHandler.php | 15 ++++-- src/Message/ProcessExecuteHandler.php | 9 ++++ src/Message/ProcessExecuteMessage.php | 9 ++++ src/Migrations/Version20231006111525.php | 11 ++++- src/Migrations/Version20240729151928.php | 12 ++++- src/Migrations/Version20240730090403.php | 9 ++++ src/Migrations/Version20241007134542.php | 9 ++++ src/Migrations/Version20241007152613.php | 9 ++++ src/Migrations/Version20241009075733.php | 9 ++++ .../Handler/DoctrineProcessHandler.php | 12 ++++- src/Monolog/Handler/ProcessHandler.php | 25 ++++++---- src/Repository/ProcessExecutionRepository.php | 2 +- src/Repository/ProcessScheduleRepository.php | 9 ++++ src/Scheduler/CronScheduler.php | 15 ++++-- .../HttpProcessExecutionAuthenticator.php | 13 ++++- src/Twig/Extension/LogLevelExtension.php | 9 ++++ src/Twig/Extension/MD5Extension.php | 9 ++++ .../Extension/ProcessExecutionExtension.php | 9 ++++ src/Twig/Runtime/LogLevelExtensionRuntime.php | 15 ++++-- src/Twig/Runtime/MD5ExtensionRuntime.php | 9 ++++ .../ProcessExecutionExtensionRuntime.php | 13 ++++- src/Validator/CronExpression.php | 11 ++++- src/Validator/CronExpressionValidator.php | 14 +++++- src/Validator/EveryExpression.php | 11 ++++- src/Validator/EveryExpressionValidator.php | 16 ++++++- src/Validator/IsValidProcessCode.php | 13 ++++- src/Validator/IsValidProcessCodeValidator.php | 11 ++++- 58 files changed, 624 insertions(+), 190 deletions(-) diff --git a/src/Admin/Field/EnumField.php b/src/Admin/Field/EnumField.php index 6c9ab87..7d5a406 100644 --- a/src/Admin/Field/EnumField.php +++ b/src/Admin/Field/EnumField.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Admin\Field; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; diff --git a/src/Admin/Field/LogLevelField.php b/src/Admin/Field/LogLevelField.php index 67250c8..f0d4c68 100644 --- a/src/Admin/Field/LogLevelField.php +++ b/src/Admin/Field/LogLevelField.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Admin\Field; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php index bbb3099..ed884a0 100644 --- a/src/Admin/Filter/LogProcessFilter.php +++ b/src/Admin/Filter/LogProcessFilter.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Admin\Filter; use Doctrine\ORM\QueryBuilder; @@ -18,17 +27,16 @@ class LogProcessFilter implements FilterInterface use FilterTrait; public static function new( - $label, + mixed $label, array $choices, - null|string|int $executionId = null, - ): self - { + string|int|null $executionId = null, + ): self { if (is_numeric($executionId)) { $choices = [$executionId => $executionId]; } return (new self()) - ->setFilterFqcn(__CLASS__) + ->setFilterFqcn(self::class) ->setProperty('process') ->setLabel($label) ->setFormType(ChoiceFilterType::class) diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index dbab7c6..17a8480 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -38,7 +38,7 @@ class UserCreateCommand extends Command public function __construct( private readonly ValidatorInterface $validator, private readonly UserPasswordHasherInterface $passwordEncoder, - private readonly EntityManagerInterface $em + private readonly EntityManagerInterface $em, ) { parent::__construct(); } diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 4170313..57d2831 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -28,7 +37,7 @@ class LogRecordCrudController extends AbstractCrudController { public function __construct( private readonly ProcessConfigurationsManager $processConfigurationsManager, - private readonly RequestStack $request + private readonly RequestStack $request, ) { } @@ -74,7 +83,7 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { - $id = $this->request->getMainRequest()->query->all('filters')['process']['value'] ?? null; + $id = $this->request->getMainRequest()?->query->all('filters')['process']['value'] ?? null; $processList = $this->processConfigurationsManager->getPublicProcesses(); $processList = array_map(fn (ProcessConfiguration $cfg) => $cfg->getCode(), $processList); diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 5d5b98c..69a1830 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -20,11 +29,10 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\Messenger\MessageBusInterface; -use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; -#[Route( +#[\Symfony\Component\Routing\Attribute\Route( '/process/launch', name: 'process_launch', requirements: ['process' => '\w+'], @@ -41,17 +49,17 @@ public function __invoke( ProcessConfigurationsManager $configurationsManager, AdminContext $context, ): Response { - $uiOptions = $configurationsManager->getUiOptions($requestStack->getMainRequest()->get('process')); + $uiOptions = $configurationsManager->getUiOptions($requestStack->getMainRequest()?->get('process') ?? ''); $form = $this->createForm( LaunchType::class, null, [ - 'constraints' => $uiOptions['constraints'], + 'constraints' => $uiOptions['constraints'] ?? [], 'process_code' => $requestStack->getMainRequest()?->get('process'), ] ); if (false === $form->isSubmitted()) { - $default = $uiOptions['default']; + $default = $uiOptions['default'] ?? []; if (false === $form->get('input')->getConfig()->getType()->getInnerType() instanceof TextType && isset($default['input']) ) { @@ -61,10 +69,9 @@ public function __invoke( } $form->handleRequest($requestStack->getMainRequest()); if ($form->isSubmitted() && $form->isValid()) { - /** @var mixed|UploadedFile $file */ $input = $form->get('input')->getData(); if ($input instanceof UploadedFile) { - $filename = sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $input->getClientOriginalExtension()); + $filename = \sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $input->getClientOriginalExtension()); (new Filesystem())->dumpFile($filename, $input->getContent()); $input = $filename; } diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php index 1af4a0f..98a0d2c 100644 --- a/src/Controller/Admin/Process/ListAction.php +++ b/src/Controller/Admin/Process/ListAction.php @@ -2,15 +2,23 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -#[Route('/process/list', name: 'process_list')] +#[\Symfony\Component\Routing\Attribute\Route('/process/list', name: 'process_list')] #[IsGranted('ROLE_USER')] class ListAction extends AbstractController { diff --git a/src/Controller/Admin/Process/UploadAndExecuteAction.php b/src/Controller/Admin/Process/UploadAndExecuteAction.php index 8ad3ae0..87d39c1 100644 --- a/src/Controller/Admin/Process/UploadAndExecuteAction.php +++ b/src/Controller/Admin/Process/UploadAndExecuteAction.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -15,11 +24,10 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\Messenger\MessageBusInterface; -use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; -#[Route( +#[\Symfony\Component\Routing\Attribute\Route( '/process/upload-and-execute', name: 'process_upload_and_execute', requirements: ['process' => '\w+'], @@ -32,9 +40,9 @@ public function __invoke( RequestStack $requestStack, MessageBusInterface $messageBus, #[Autowire(param: 'upload_directory')] string $uploadDirectory, - #[ValueResolver('process')] ProcessConfiguration $processConfiguration + #[ValueResolver('process')] ProcessConfiguration $processConfiguration, ): Response { - if (null === $processConfiguration->getEntryPoint()) { + if (!$processConfiguration->getEntryPoint() instanceof \CleverAge\ProcessBundle\Configuration\TaskConfiguration) { throw new \RuntimeException('You must set an entry_point.'); } $form = $this->createForm( @@ -46,7 +54,7 @@ public function __invoke( if ($form->isSubmitted() && $form->isValid()) { /** @var UploadedFile $file */ $file = $form->getData(); - $savedFilepath = sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $file->getClientOriginalExtension()); + $savedFilepath = \sprintf('%s/%s.%s', $uploadDirectory, Uuid::v4(), $file->getClientOriginalExtension()); (new Filesystem())->dumpFile($savedFilepath, $file->getContent()); $messageBus->dispatch( new ProcessExecuteMessage( diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index d2fe033..5c380f8 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin; use CleverAge\ProcessUiBundle\Entity\LogRecord; @@ -14,7 +23,6 @@ use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Translation\LocaleSwitcher; @@ -23,11 +31,11 @@ class ProcessDashboardController extends AbstractDashboardController { public function __construct( private readonly LocaleSwitcher $localeSwitcher, - private readonly string $logoPath = '' + private readonly string $logoPath = '', ) { } - #[Route('/process', name: 'process')] + #[\Symfony\Component\Routing\Attribute\Route('/process', name: 'process')] public function index(): Response { $adminUrlGenerator = $this->container->get(AdminUrlGenerator::class); @@ -63,7 +71,7 @@ public function configureMenuItems(): iterable public function configureCrud(): Crud { - /** @var User $user */ + /** @var ?User $user */ $user = $this->getUser(); if (null !== $user?->getLocale()) { $this->localeSwitcher->setLocale($user->getLocale()); diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index c7eae3f..cb21820 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin; use CleverAge\ProcessUiBundle\Admin\Field\EnumField; @@ -96,7 +105,7 @@ public function showLogs(AdminContext $adminContext): RedirectResponse [ 'process' => [ 'comparison' => '=', - 'value' => $this->getContext()->getEntity()->getInstance()->getId(), + 'value' => $this->getContext()?->getEntity()->getInstance()->getId(), ], ] ) @@ -111,7 +120,7 @@ public function downloadLogFile( ): Response { /** @var ProcessExecution $processExecution */ $processExecution = $context->getEntity()->getInstance(); - $filepath = $directory.DIRECTORY_SEPARATOR.$processExecution->code.DIRECTORY_SEPARATOR + $filepath = $directory.\DIRECTORY_SEPARATOR.$processExecution->code.\DIRECTORY_SEPARATOR .$processExecution->logFilename; $basename = basename($filepath); $content = file_get_contents($filepath); diff --git a/src/Controller/Admin/ProcessScheduleCrudController.php b/src/Controller/Admin/ProcessScheduleCrudController.php index 9aff0e9..c7c6526 100644 --- a/src/Controller/Admin/ProcessScheduleCrudController.php +++ b/src/Controller/Admin/ProcessScheduleCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -43,22 +52,14 @@ public function configureCrud(Crud $crud): Crud public function configureActions(Actions $actions): Actions { return $actions - ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { - return $action->setIcon('fa fa-plus') - ->setLabel(false) - ->addCssClass(''); - })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { - return $action->setIcon('fa fa-edit') - ->setLabel(false) - ->addCssClass('text-warning'); - })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { - return $action->setIcon('fa fa-trash-o') - ->setLabel(false) - ->addCssClass(''); - })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { - return $action->setLabel('Delete') - ->addCssClass(''); - }); + ->update(Crud::PAGE_INDEX, Action::NEW, fn (Action $action) => $action->setIcon('fa fa-plus') + ->setLabel(false) + ->addCssClass(''))->update(Crud::PAGE_INDEX, Action::EDIT, fn (Action $action) => $action->setIcon('fa fa-edit') + ->setLabel(false) + ->addCssClass('text-warning'))->update(Crud::PAGE_INDEX, Action::DELETE, fn (Action $action) => $action->setIcon('fa fa-trash-o') + ->setLabel(false) + ->addCssClass(''))->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, fn (Action $action) => $action->setLabel('Delete') + ->addCssClass('')); } public static function getEntityFqcn(): string @@ -68,9 +69,7 @@ public static function getEntityFqcn(): string public function configureFields(string $pageName): iterable { - $choices = array_map(function (ProcessConfiguration $configuration) { - return [$configuration->getCode()]; - }, $this->processConfigurationsManager->getPublicProcesses()); + $choices = array_map(fn (ProcessConfiguration $configuration) => [$configuration->getCode()], $this->processConfigurationsManager->getPublicProcesses()); return [ FormField::addTab('General'), @@ -86,11 +85,11 @@ public function configureFields(string $pageName): iterable ->setVirtual(true) ->hideOnForm() ->hideOnDetail() - ->formatValue(function ($value, ProcessSchedule $entity) { - return ProcessScheduleType::CRON === $entity->getType() - ? CronExpressionTrigger::fromSpec($entity->getExpression())->getNextRunDate(new \DateTimeImmutable())->format('c') - : null; - }), + ->formatValue(fn ($value, ProcessSchedule $entity) => ProcessScheduleType::CRON === $entity->getType() + ? CronExpressionTrigger::fromSpec($entity->getExpression() ?? '') + ->getNextRunDate(new \DateTimeImmutable()) + ?->format('c') + : null), FormField::addTab('Input'), TextField::new('input'), FormField::addTab('Context'), diff --git a/src/Controller/Admin/Security/LoginController.php b/src/Controller/Admin/Security/LoginController.php index f39026c..01db200 100644 --- a/src/Controller/Admin/Security/LoginController.php +++ b/src/Controller/Admin/Security/LoginController.php @@ -2,15 +2,23 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin\Security; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; class LoginController extends AbstractController { - #[Route('/process/login', name: 'process_login')] + #[\Symfony\Component\Routing\Attribute\Route('/process/login', name: 'process_login')] public function __invoke(): Response { return $this->render( diff --git a/src/Controller/Admin/Security/LogoutController.php b/src/Controller/Admin/Security/LogoutController.php index e272d38..2d6b66c 100644 --- a/src/Controller/Admin/Security/LogoutController.php +++ b/src/Controller/Admin/Security/LogoutController.php @@ -2,16 +2,24 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin\Security; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Annotation\Route; class LogoutController extends AbstractController { - #[Route('/process/logout', name: 'process_logout')] + #[\Symfony\Component\Routing\Attribute\Route('/process/logout', name: 'process_logout')] public function __invoke(Security $security): Response { $security->logout(); diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 16b4fbf..45284b3 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller\Admin; use CleverAge\ProcessUiBundle\Entity\User; @@ -27,7 +36,7 @@ class UserCrudController extends AbstractCrudController { /** @param array $roles */ - public function __construct(private array $roles) + public function __construct(private readonly array $roles) { } @@ -79,22 +88,14 @@ public function configureFields(string $pageName): iterable public function configureActions(Actions $actions): Actions { return $actions - ->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) { - return $action->setIcon('fa fa-plus') - ->setLabel(false) - ->addCssClass(''); - })->update(Crud::PAGE_INDEX, Action::EDIT, function (Action $action) { - return $action->setIcon('fa fa-edit') - ->setLabel(false) - ->addCssClass('text-warning'); - })->update(Crud::PAGE_INDEX, Action::DELETE, function (Action $action) { - return $action->setIcon('fa fa-trash-o') - ->setLabel(false) - ->addCssClass(''); - })->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, function (Action $action) { - return $action->setLabel('Delete') - ->addCssClass(''); - })->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')); + ->update(Crud::PAGE_INDEX, Action::NEW, fn (Action $action) => $action->setIcon('fa fa-plus') + ->setLabel(false) + ->addCssClass(''))->update(Crud::PAGE_INDEX, Action::EDIT, fn (Action $action) => $action->setIcon('fa fa-edit') + ->setLabel(false) + ->addCssClass('text-warning'))->update(Crud::PAGE_INDEX, Action::DELETE, fn (Action $action) => $action->setIcon('fa fa-trash-o') + ->setLabel(false) + ->addCssClass(''))->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, fn (Action $action) => $action->setLabel('Delete') + ->addCssClass(''))->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')); } public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adminUrlGenerator): Response @@ -111,7 +112,7 @@ public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adm return $this->redirect( $adminUrlGenerator - ->setController(UserCrudController::class) + ->setController(self::class) ->setAction(Action::EDIT) ->setEntityId($user->getId()) ->generateUrl() diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php index a20eb17..a321660 100644 --- a/src/Controller/ProcessExecuteController.php +++ b/src/Controller/ProcessExecuteController.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Controller; use CleverAge\ProcessUiBundle\Http\Model\HttpProcessExecution; @@ -20,7 +29,7 @@ class ProcessExecuteController extends AbstractController public function __invoke( #[ValueResolver('http_process_execution')] HttpProcessExecution $httpProcessExecution, ValidatorInterface $validator, - MessageBusInterface $bus + MessageBusInterface $bus, ): JsonResponse { $violations = $validator->validate($httpProcessExecution); if ($violations->count() > 0) { @@ -32,7 +41,7 @@ public function __invoke( } $bus->dispatch( new ProcessExecuteMessage( - $httpProcessExecution->code, + $httpProcessExecution->code ?? '', $httpProcessExecution->input, $httpProcessExecution->context ) diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index 75db72b..173fbb6 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -48,23 +48,23 @@ public function load(array $configs, ContainerBuilder $container): void */ public function prepend(ContainerBuilder $container): void { - $env = $container->getParameter("kernel.environment"); + $env = $container->getParameter('kernel.environment'); $container->loadFromExtension( 'monolog', [ 'handlers' => [ 'pb_ui_file' => [ 'type' => 'service', - 'id' => ProcessHandler::class + 'id' => ProcessHandler::class, ], 'pb_ui_orm' => [ 'type' => 'service', - 'id' => DoctrineProcessHandler::class - ] - ] + 'id' => DoctrineProcessHandler::class, + ], + ], ] ); - if ("dev" === $env) { + if ('dev' === $env) { $container->loadFromExtension( 'monolog', [ @@ -73,15 +73,15 @@ public function prepend(ContainerBuilder $container): void 'type' => 'filter', 'min_level' => Level::Debug->name, 'handler' => 'pb_ui_file', - 'channels' => ['cleverage_process', 'cleverage_process_task'] + 'channels' => ['cleverage_process', 'cleverage_process_task'], ], 'pb_ui_orm_filter' => [ 'type' => 'filter', 'min_level' => Level::Debug->name, 'handler' => 'pb_ui_orm', - 'channels' => ["cleverage_process", "cleverage_process_task"] + 'channels' => ['cleverage_process', 'cleverage_process_task'], ], - ] + ], ] ); } else { @@ -93,15 +93,15 @@ public function prepend(ContainerBuilder $container): void 'type' => 'filter', 'min_level' => Level::Info->name, 'handler' => 'pb_ui_file', - 'channels' => ['cleverage_process', 'cleverage_process_task'] + 'channels' => ['cleverage_process', 'cleverage_process_task'], ], 'pb_ui_orm_filter' => [ 'type' => 'filter', 'min_level' => Level::Info->name, 'handler' => 'pb_ui_orm', - 'channels' => ["cleverage_process", "cleverage_process_task"] + 'channels' => ['cleverage_process', 'cleverage_process_task'], ], - ] + ], ] ); } diff --git a/src/Entity/Enum/ProcessExecutionStatus.php b/src/Entity/Enum/ProcessExecutionStatus.php index 1950783..5d66457 100644 --- a/src/Entity/Enum/ProcessExecutionStatus.php +++ b/src/Entity/Enum/ProcessExecutionStatus.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity\Enum; enum ProcessExecutionStatus: string diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php index e55fedc..3380467 100644 --- a/src/Entity/LogRecord.php +++ b/src/Entity/LogRecord.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use Doctrine\ORM\Mapping as ORM; @@ -17,24 +26,20 @@ class LogRecord #[ORM\Column] private ?int $id = null; - #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] - #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE')] - private readonly ProcessExecution $processExecution; - - #[ORM\Column(type: 'string', length: 64)] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 64)] public readonly string $channel; - #[ORM\Column(type: 'integer')] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)] public readonly int $level; - #[ORM\Column(type: 'string', length: 512)] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 512)] public readonly string $message; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)] /** @var array */ public readonly array $context; - #[ORM\Column(type: 'datetime_immutable')] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE)] public readonly \DateTimeImmutable $createdAt; public function getId(): ?int @@ -42,18 +47,19 @@ public function getId(): ?int return $this->id; } - public function __construct(\Monolog\LogRecord $record, ProcessExecution $processExecution) + public function __construct(\Monolog\LogRecord $record, #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] + #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + private readonly ProcessExecution $processExecution) { $this->channel = (string) (new UnicodeString($record->channel))->truncate(64); $this->level = $record->level->value; $this->message = (string) (new UnicodeString($record->message))->truncate(512); $this->context = $record->context; - $this->processExecution = $processExecution; $this->createdAt = \DateTimeImmutable::createFromMutable(new \DateTime()); } public function contextIsEmpty(): bool { - return !empty($this->context); + return [] !== $this->context; } } diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index c4314e5..5a5ffe0 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -21,7 +21,7 @@ #[ORM\Entity] #[ORM\Index(columns: ['code'], name: 'idx_process_execution_code')] #[ORM\Index(columns: ['start_date'], name: 'idx_process_execution_start_date')] -class ProcessExecution +class ProcessExecution implements \Stringable { #[ORM\Id] #[ORM\GeneratedValue] @@ -31,9 +31,6 @@ class ProcessExecution #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $code; - #[ORM\Column(type: Types::STRING, length: 255)] - public readonly string $logFilename; - #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public readonly \DateTimeImmutable $startDate; @@ -41,7 +38,7 @@ class ProcessExecution public ?\DateTimeImmutable $endDate = null; #[ORM\Column(type: Types::STRING, enumType: ProcessExecutionStatus::class)] - public ProcessExecutionStatus $status; + public ProcessExecutionStatus $status = ProcessExecutionStatus::Started; #[ORM\Column(type: Types::JSON)] private array $report = []; @@ -54,12 +51,11 @@ public function getId(): ?int return $this->id; } - public function __construct(string $code, string $logFilename, ?array $context = []) + public function __construct(string $code, #[ORM\Column(type: Types::STRING, length: 255)] + public readonly string $logFilename, ?array $context = []) { $this->code = (string) (new UnicodeString($code))->truncate(255); - $this->logFilename = $logFilename; $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); - $this->status = ProcessExecutionStatus::Started; $this->context = $context ?? []; } @@ -75,7 +71,7 @@ public function end(): void public function __toString(): string { - return sprintf('%s (%s)', $this->id, $this->code); + return \sprintf('%s (%s)', $this->id, $this->code); } public function addReport(string $key, mixed $value): void @@ -94,7 +90,7 @@ public function getReport(?string $key = null, mixed $default = null): mixed public function duration(string $format = '%H hour(s) %I min(s) %S s'): ?string { - if (null === $this->endDate) { + if (!$this->endDate instanceof \DateTimeImmutable) { return null; } $diff = $this->endDate->diff($this->startDate); @@ -107,7 +103,7 @@ public function getCode(): string return $this->code; } - public function getContext(): array + public function getContext(): ?array { return $this->context; } diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 1bdb677..5e1cd1b 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Entity; use CleverAge\ProcessUiBundle\Repository\ProcessScheduleRepository; @@ -40,10 +49,10 @@ class ProcessSchedule )] private ?string $expression = null; - #[ORM\Column(type: 'text', nullable: true)] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)] private ?string $input = null; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)] private string|array $context = []; public function getId(): ?int @@ -65,7 +74,7 @@ public function setProcess(string $process): static public function getContext(): array { - return is_array($this->context) ? $this->context : json_decode($this->context); + return \is_array($this->context) ? $this->context : json_decode($this->context); } public function setContext(array $context): void diff --git a/src/Entity/User.php b/src/Entity/User.php index b78d367..88982a7 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -25,31 +25,31 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] - private ?int $id; + private ?int $id = null; - #[ORM\Column(type: 'string', length: 255, unique: true)] - private ?string $email; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, unique: true)] + private ?string $email = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $firstname; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $firstname = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $lastname; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $lastname = null; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)] private array $roles = []; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $password; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $password = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $timezone; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $timezone = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $locale; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $locale = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private ?string $token; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + private ?string $token = null; public function getId(): ?int { diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index b11bb6c..539c656 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -27,19 +27,19 @@ public function __construct( private ProcessHandler $processHandler, private DoctrineProcessHandler $doctrineProcessHandler, - private ProcessExecutionManager $processExecutionManager + private ProcessExecutionManager $processExecutionManager, ) { } public function onProcessStart(ProcessEvent $event): void { if (false === $this->processHandler->hasFilename()) { - $this->processHandler->setFilename(sprintf('%s/%s.log', $event->getProcessCode(), Uuid::v4())); + $this->processHandler->setFilename(\sprintf('%s/%s.log', $event->getProcessCode(), Uuid::v4())); } - if (null === $this->processExecutionManager->getCurrentProcessExecution()) { + if (!$this->processExecutionManager->getCurrentProcessExecution() instanceof ProcessExecution) { $processExecution = new ProcessExecution( $event->getProcessCode(), - basename($this->processHandler->getFilename()), + basename((string) $this->processHandler->getFilename()), $event->getProcessContext() ); $this->processExecutionManager->setCurrentProcessExecution($processExecution)->save(); @@ -48,9 +48,9 @@ public function onProcessStart(ProcessEvent $event): void public function success(ProcessEvent $event): void { - if ($event->getProcessCode() === $this->processExecutionManager?->getCurrentProcessExecution()?->getCode()) { - $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Finish); - $this->processExecutionManager->getCurrentProcessExecution()?->end(); + if ($event->getProcessCode() === $this->processExecutionManager->getCurrentProcessExecution()?->getCode()) { + $this->processExecutionManager->getCurrentProcessExecution()->setStatus(ProcessExecutionStatus::Finish); + $this->processExecutionManager->getCurrentProcessExecution()->end(); $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); $this->processHandler->close(); } @@ -58,9 +58,9 @@ public function success(ProcessEvent $event): void public function fail(ProcessEvent $event): void { - if ($event->getProcessCode() === $this->processExecutionManager?->getCurrentProcessExecution()?->getCode()) { - $this->processExecutionManager->getCurrentProcessExecution()?->setStatus(ProcessExecutionStatus::Failed); - $this->processExecutionManager->getCurrentProcessExecution()?->end(); + if ($event->getProcessCode() === $this->processExecutionManager->getCurrentProcessExecution()?->getCode()) { + $this->processExecutionManager->getCurrentProcessExecution()->setStatus(ProcessExecutionStatus::Failed); + $this->processExecutionManager->getCurrentProcessExecution()->end(); $this->processExecutionManager->save()->unsetProcessExecution($event->getProcessCode()); $this->processHandler->close(); } diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 60027d1..1cfa6fd 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -2,8 +2,18 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Form\Type; +use CleverAge\ProcessBundle\Configuration\TaskConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use Symfony\Component\Form\AbstractType; @@ -30,9 +40,9 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $uiOptions = $this->configurationsManager->getUiOptions($code); $builder->add( 'input', - 'file' === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, + 'file' === ($uiOptions['entrypoint_type'] ?? null) ? FileType::class : TextType::class, [ - 'required' => !(null === $configuration->getEntryPoint()), + 'required' => $configuration->getEntryPoint() instanceof TaskConfiguration, ] ); $builder->add( @@ -46,12 +56,8 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ] ); $builder->get('context')->addModelTransformer(new CallbackTransformer( - function ($data) { - return null === $data ? [] : $data; - }, - function ($data) { - return array_column($data ?? [], 'value', 'key'); - }, + fn ($data) => $data ?? [], + fn ($data) => array_column($data ?? [], 'value', 'key'), )); } diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php index daa48d1..6a7103b 100644 --- a/src/Form/Type/ProcessContextType.php +++ b/src/Form/Type/ProcessContextType.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Form\Type; use Symfony\Component\Form\AbstractType; diff --git a/src/Form/Type/ProcessUploadFileType.php b/src/Form/Type/ProcessUploadFileType.php index cf476c7..b22026f 100644 --- a/src/Form/Type/ProcessUploadFileType.php +++ b/src/Form/Type/ProcessUploadFileType.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Form\Type; use Symfony\Component\Form\AbstractType; diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index 7f66563..c671dba 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Http\Model; use CleverAge\ProcessUiBundle\Validator\IsValidProcessCode; @@ -14,7 +23,7 @@ public function __construct( #[Sequentially(constraints: [new NotNull(message: 'Process code is required.'), new IsValidProcessCode()])] public ?string $code = null, public ?string $input = null, - public array $context = [] + public array $context = [], ) { } } diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 6f73301..58bcbd0 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Http\ValueResolver; use CleverAge\ProcessUiBundle\Http\Model\HttpProcessExecution; @@ -24,7 +33,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable { $input = $request->get('input', $request->files->get('input')); if ($input instanceof UploadedFile) { - $uploadFileName = $this->storageDir.DIRECTORY_SEPARATOR.date('YmdHis').'_'.uniqid().'_'.$input->getClientOriginalName(); + $uploadFileName = $this->storageDir.\DIRECTORY_SEPARATOR.date('YmdHis').'_'.uniqid().'_'.$input->getClientOriginalName(); (new Filesystem())->dumpFile($uploadFileName, $input->getContent()); $input = $uploadFileName; } diff --git a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php index a8c2a89..9c99ebc 100644 --- a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php +++ b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Http\ValueResolver; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 489f188..5ce8601 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Manager; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; @@ -66,9 +75,7 @@ private function resolveUiOptions(array $options): array 'run ui option is deprecated. Use public option instead to hide a process from UI' ); $uiResolver->setAllowedValues('entrypoint_type', ['text', 'file']); - $uiResolver->setNormalizer('constraints', function (Options $options, array $values): array { - return (new ConstraintLoader())->buildConstraints($values); - }); + $uiResolver->setNormalizer('constraints', fn (Options $options, array $values): array => (new ConstraintLoader())->buildConstraints($values)); }); return $resolver->resolve($options); diff --git a/src/Manager/ProcessExecutionManager.php b/src/Manager/ProcessExecutionManager.php index cc4ab7c..f342af1 100644 --- a/src/Manager/ProcessExecutionManager.php +++ b/src/Manager/ProcessExecutionManager.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Manager; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; @@ -17,7 +26,7 @@ public function __construct(private readonly ProcessExecutionRepository $process public function setCurrentProcessExecution(ProcessExecution $processExecution): self { - if (null === $this->currentProcessExecution) { + if (!$this->currentProcessExecution instanceof ProcessExecution) { $this->currentProcessExecution = $processExecution; } @@ -40,7 +49,7 @@ public function unsetProcessExecution(string $processCode): self public function save(): self { - if (null !== $this->currentProcessExecution) { + if ($this->currentProcessExecution instanceof ProcessExecution) { $this->processExecutionRepository->save($this->currentProcessExecution); } diff --git a/src/Message/CronProcessMessage.php b/src/Message/CronProcessMessage.php index 2a86db1..b5c9d61 100644 --- a/src/Message/CronProcessMessage.php +++ b/src/Message/CronProcessMessage.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; diff --git a/src/Message/CronProcessMessageHandler.php b/src/Message/CronProcessMessageHandler.php index 868803e..ed55f5a 100644 --- a/src/Message/CronProcessMessageHandler.php +++ b/src/Message/CronProcessMessageHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; use Symfony\Component\Messenger\Attribute\AsMessageHandler; @@ -17,11 +26,9 @@ public function __construct(private MessageBusInterface $bus) public function __invoke(CronProcessMessage $message): void { $schedule = $message->processSchedule; - $context = array_merge(...array_map(function($ctx) { - return [$ctx['key'] => $ctx['value']]; - }, $schedule->getContext())); + $context = array_merge(...array_map(fn ($ctx) => [$ctx['key'] => $ctx['value']], $schedule->getContext())); $this->bus->dispatch( - new ProcessExecuteMessage($schedule->getProcess(), $schedule->getInput(), $context) + new ProcessExecuteMessage($schedule->getProcess() ?? '', $schedule->getInput(), $context) ); } } diff --git a/src/Message/ProcessExecuteHandler.php b/src/Message/ProcessExecuteHandler.php index 48e1b8a..f786378 100644 --- a/src/Message/ProcessExecuteHandler.php +++ b/src/Message/ProcessExecuteHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; use CleverAge\ProcessBundle\Manager\ProcessManager; diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php index a64e633..5ffdfb3 100644 --- a/src/Message/ProcessExecuteMessage.php +++ b/src/Message/ProcessExecuteMessage.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Message; readonly class ProcessExecuteMessage diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php index 583f88f..03d4d55 100644 --- a/src/Migrations/Version20231006111525.php +++ b/src/Migrations/Version20231006111525.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Platforms\MariaDBPlatform; @@ -21,7 +30,7 @@ public function up(Schema $schema): void { $platform = $this->connection->getDatabasePlatform(); - if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { + if ($platform instanceof MariaDBPlatform || $platform instanceof MySQLPlatform) { if (!$schema->hasTable('log_record')) { $this->addSql('CREATE TABLE log_record (id INT AUTO_INCREMENT NOT NULL, process_execution_id INT DEFAULT NULL, channel VARCHAR(64) NOT NULL, level INT NOT NULL, message VARCHAR(512) NOT NULL, context JSON NOT NULL COMMENT \'(DC2Type:json)\', created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_8ECECC333DAC0075 (process_execution_id), INDEX idx_log_record_level (level), INDEX idx_log_record_created_at (created_at), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); } diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php index 8793abb..dfdc762 100644 --- a/src/Migrations/Version20240729151928.php +++ b/src/Migrations/Version20240729151928.php @@ -2,12 +2,20 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Platforms\MariaDBPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; @@ -28,7 +36,7 @@ public function up(Schema $schema): void $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL, PRIMARY KEY(id))'); } - if ($platform instanceof MariaDBPlatform or $platform instanceof MySQLPlatform) { + if ($platform instanceof MariaDBPlatform || $platform instanceof MySQLPlatform) { $this->addSql('CREATE TABLE process_schedule (id INT AUTO_INCREMENT NOT NULL, process VARCHAR(255) NOT NULL, type VARCHAR(6) NOT NULL, expression VARCHAR(255) NOT NULL, input VARCHAR(255), context JSON NOT NULL COMMENT \'(DC2Type:json)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;'); } } diff --git a/src/Migrations/Version20240730090403.php b/src/Migrations/Version20240730090403.php index 6524be0..2f6ca6e 100644 --- a/src/Migrations/Version20240730090403.php +++ b/src/Migrations/Version20240730090403.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; diff --git a/src/Migrations/Version20241007134542.php b/src/Migrations/Version20241007134542.php index 226efe3..403c538 100644 --- a/src/Migrations/Version20241007134542.php +++ b/src/Migrations/Version20241007134542.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php index cd03460..8f989d7 100644 --- a/src/Migrations/Version20241007152613.php +++ b/src/Migrations/Version20241007152613.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; diff --git a/src/Migrations/Version20241009075733.php b/src/Migrations/Version20241009075733.php index fe4396d..6a027e2 100644 --- a/src/Migrations/Version20241009075733.php +++ b/src/Migrations/Version20241009075733.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Migrations; use Doctrine\DBAL\Schema\Schema; diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index 20b9c39..7b99b93 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -2,8 +2,18 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Monolog\Handler; +use CleverAge\ProcessUiBundle\Entity\ProcessExecution; use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; @@ -46,7 +56,7 @@ public function __destruct() public function flush(): void { foreach ($this->records as $record) { - if ($currentProcessExecution = $this->processExecutionManager->getCurrentProcessExecution()) { + if (($currentProcessExecution = $this->processExecutionManager?->getCurrentProcessExecution()) instanceof ProcessExecution) { $entity = new \CleverAge\ProcessUiBundle\Entity\LogRecord($record, $currentProcessExecution); $this->em?->persist($entity); } diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php index 97115ea..5d4dd0c 100644 --- a/src/Monolog/Handler/ProcessHandler.php +++ b/src/Monolog/Handler/ProcessHandler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Monolog\Handler; use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; @@ -12,16 +21,13 @@ class ProcessHandler extends StreamHandler { - private readonly string $directory; - private Level $reportIncrementLevel; + private Level $reportIncrementLevel = Level::Error; public function __construct( - #[Autowire(param: 'kernel.logs_dir')] string $directory, - private ProcessExecutionManager $processExecutionManager + #[Autowire(param: 'kernel.logs_dir')] private readonly string $directory, + private readonly ProcessExecutionManager $processExecutionManager, ) { - $this->directory = $directory; - $this->reportIncrementLevel = Level::Error; - parent::__construct($directory); + parent::__construct($this->directory); } public function hasFilename(): bool @@ -31,7 +37,7 @@ public function hasFilename(): bool public function setFilename(string $filename): void { - $this->url = sprintf('%s/%s', $this->directory, $filename); + $this->url = \sprintf('%s/%s', $this->directory, $filename); } public function close(): void @@ -53,6 +59,9 @@ public function write(LogRecord $record): void } } + /** + * @param 'ALERT'|'Alert'|'alert'|'CRITICAL'|'Critical'|'critical'|'DEBUG'|'Debug'|'debug'|'EMERGENCY'|'Emergency'|'emergency'|'ERROR'|'Error'|'error'|'INFO'|'Info'|'info'|'NOTICE'|'Notice'|'notice'|'WARNING'|'Warning'|'warning' $level + */ public function setReportIncrementLevel(string $level): void { $this->reportIncrementLevel = Level::fromName($level); diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index 4e58abc..ef2bc80 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -18,7 +18,7 @@ use Doctrine\ORM\EntityRepository; /** - * @extends ServiceEntityRepository + * @extends EntityRepository * * @method ProcessExecution|null find($id, $lockMode = null, $lockVersion = null) * @method ProcessExecution|null findOneBy(array $criteria, array $orderBy = null) diff --git a/src/Repository/ProcessScheduleRepository.php b/src/Repository/ProcessScheduleRepository.php index b7b3452..2a40866 100644 --- a/src/Repository/ProcessScheduleRepository.php +++ b/src/Repository/ProcessScheduleRepository.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Repository; use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index e200dce..6f0de44 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Scheduler; use CleverAge\ProcessUiBundle\Entity\ProcessScheduleType; @@ -22,7 +31,7 @@ public function __construct( private ProcessScheduleRepository $repository, private ValidatorInterface $validator, - private LoggerInterface $logger + private LoggerInterface $logger, ) { } @@ -44,14 +53,14 @@ public function getSchedule(): Schedule if (ProcessScheduleType::CRON === $processSchedule->getType()) { $schedule->add( RecurringMessage::cron( - $processSchedule->getExpression(), + $processSchedule->getExpression() ?? '', new CronProcessMessage($processSchedule) ) ); } elseif (ProcessScheduleType::EVERY === $processSchedule->getType()) { $schedule->add( RecurringMessage::every( - $processSchedule->getExpression(), + $processSchedule->getExpression() ?? '', new CronProcessMessage($processSchedule) ) ); diff --git a/src/Security/HttpProcessExecutionAuthenticator.php b/src/Security/HttpProcessExecutionAuthenticator.php index a37b1e9..2b28680 100644 --- a/src/Security/HttpProcessExecutionAuthenticator.php +++ b/src/Security/HttpProcessExecutionAuthenticator.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Security; use CleverAge\ProcessUiBundle\Entity\User; @@ -34,7 +43,7 @@ public function authenticate(Request $request): Passport throw new AuthenticationException('Missing auth token.'); } $token = $request->headers->get('Authorization'); - $token = str_replace('Bearer ', '', null === $token ? [''] : $token); + $token = str_replace('Bearer ', '', $token ?? ''); $user = $this->entityManager->getRepository(User::class)->findOneBy( ['token' => (new Pbkdf2PasswordHasher())->hash($token)] ); @@ -42,7 +51,7 @@ public function authenticate(Request $request): Passport throw new AuthenticationException('Invalid token.'); } - return new SelfValidatingPassport(new UserBadge($user->getEmail())); + return new SelfValidatingPassport(new UserBadge($user->getEmail() ?? '')); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response diff --git a/src/Twig/Extension/LogLevelExtension.php b/src/Twig/Extension/LogLevelExtension.php index 2c93258..32339dc 100644 --- a/src/Twig/Extension/LogLevelExtension.php +++ b/src/Twig/Extension/LogLevelExtension.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Extension; use CleverAge\ProcessUiBundle\Twig\Runtime\LogLevelExtensionRuntime; diff --git a/src/Twig/Extension/MD5Extension.php b/src/Twig/Extension/MD5Extension.php index 29722de..3538855 100644 --- a/src/Twig/Extension/MD5Extension.php +++ b/src/Twig/Extension/MD5Extension.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Extension; use CleverAge\ProcessUiBundle\Twig\Runtime\MD5ExtensionRuntime; diff --git a/src/Twig/Extension/ProcessExecutionExtension.php b/src/Twig/Extension/ProcessExecutionExtension.php index fc237e9..893c3c9 100644 --- a/src/Twig/Extension/ProcessExecutionExtension.php +++ b/src/Twig/Extension/ProcessExecutionExtension.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Extension; use CleverAge\ProcessUiBundle\Twig\Runtime\ProcessExecutionExtensionRuntime; diff --git a/src/Twig/Runtime/LogLevelExtensionRuntime.php b/src/Twig/Runtime/LogLevelExtensionRuntime.php index aef2855..8730df6 100644 --- a/src/Twig/Runtime/LogLevelExtensionRuntime.php +++ b/src/Twig/Runtime/LogLevelExtensionRuntime.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Runtime; use Monolog\Level; @@ -16,18 +25,18 @@ public function getLabel(int $value): string public function getCssClass(string|int $value): string { - return is_int($value) ? + return \is_int($value) ? match ($value) { Level::Warning->value => 'warning', Level::Error->value, Level::Emergency->value, Level::Critical->value, Level::Alert->value => 'danger', Level::Debug->value, Level::Info->value => 'success', - default => '' + default => '', } : match ($value) { Level::Warning->name => 'warning', Level::Error->name, Level::Emergency->name, Level::Critical->name, Level::Alert->name => 'danger', Level::Debug->name, Level::Info->name => 'success', - default => '' + default => '', }; } } diff --git a/src/Twig/Runtime/MD5ExtensionRuntime.php b/src/Twig/Runtime/MD5ExtensionRuntime.php index 40bd3f1..bd8263e 100644 --- a/src/Twig/Runtime/MD5ExtensionRuntime.php +++ b/src/Twig/Runtime/MD5ExtensionRuntime.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 0f90ef5..fff7056 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Twig\Runtime; use CleverAge\ProcessUiBundle\Entity\ProcessExecution; @@ -24,11 +33,11 @@ public function getLastExecutionDate(string $code): ?ProcessExecution public function getProcessSource(string $code): ?string { - return $this->processConfigurationsManager->getUiOptions($code)['source']; + return $this->processConfigurationsManager->getUiOptions($code)['source'] ?? null; } public function getProcessTarget(string $code): ?string { - return $this->processConfigurationsManager->getUiOptions($code)['target']; + return $this->processConfigurationsManager->getUiOptions($code)['target'] ?? null; } } diff --git a/src/Validator/CronExpression.php b/src/Validator/CronExpression.php index 9d1a363..9c5e07e 100644 --- a/src/Validator/CronExpression.php +++ b/src/Validator/CronExpression.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use Symfony\Component\Validator\Constraint; @@ -9,5 +18,5 @@ #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] final class CronExpression extends Constraint { - public $message = 'The value "{{ value }}" is not a valid cron expression.'; + public string $message = 'The value "{{ value }}" is not a valid cron expression.'; } diff --git a/src/Validator/CronExpressionValidator.php b/src/Validator/CronExpressionValidator.php index 02231ee..78af969 100644 --- a/src/Validator/CronExpressionValidator.php +++ b/src/Validator/CronExpressionValidator.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use Symfony\Component\Scheduler\Trigger\CronExpressionTrigger; @@ -10,7 +19,10 @@ final class CronExpressionValidator extends ConstraintValidator { - public function validate($value, Constraint $constraint): void + /** + * @param CronExpression $constraint + */ + public function validate(mixed $value, Constraint $constraint): void { try { CronExpressionTrigger::fromSpec($value); diff --git a/src/Validator/EveryExpression.php b/src/Validator/EveryExpression.php index 2288311..1423628 100644 --- a/src/Validator/EveryExpression.php +++ b/src/Validator/EveryExpression.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use Symfony\Component\Validator\Constraint; @@ -9,5 +18,5 @@ #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] final class EveryExpression extends Constraint { - public $message = 'The value "{{ value }}" is not every valid expression.'; + public string $message = 'The value "{{ value }}" is not every valid expression.'; } diff --git a/src/Validator/EveryExpressionValidator.php b/src/Validator/EveryExpressionValidator.php index 53fd39d..8bbd8b6 100644 --- a/src/Validator/EveryExpressionValidator.php +++ b/src/Validator/EveryExpressionValidator.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use Symfony\Component\Validator\Constraint; @@ -9,11 +18,14 @@ final class EveryExpressionValidator extends ConstraintValidator { - public function validate($value, Constraint $constraint): void + /** + * @param EveryExpression $constraint + */ + public function validate(mixed $value, Constraint $constraint): void { /* @var EveryExpression $constraint */ - if (false !== strtotime($value)) { + if (false !== strtotime((string) $value)) { return; } diff --git a/src/Validator/IsValidProcessCode.php b/src/Validator/IsValidProcessCode.php index b957e86..f33c133 100644 --- a/src/Validator/IsValidProcessCode.php +++ b/src/Validator/IsValidProcessCode.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use Symfony\Component\Validator\Constraint; @@ -9,6 +18,6 @@ #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] final class IsValidProcessCode extends Constraint { - public $messageIsNotPublic = 'The process "{{ value }}" is not public.'; - public $messageNotExists = 'The process "{{ value }}" does not exist.'; + public string $messageIsNotPublic = 'The process "{{ value }}" is not public.'; + public string $messageNotExists = 'The process "{{ value }}" does not exist.'; } diff --git a/src/Validator/IsValidProcessCodeValidator.php b/src/Validator/IsValidProcessCodeValidator.php index 6bff49d..b47a706 100644 --- a/src/Validator/IsValidProcessCodeValidator.php +++ b/src/Validator/IsValidProcessCodeValidator.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of the CleverAge/UiProcessBundle package. + * + * Copyright (c) Clever-Age + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace CleverAge\ProcessUiBundle\Validator; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; @@ -17,7 +26,7 @@ public function __construct(private readonly ProcessConfigurationRegistry $regis /** * @param IsValidProcessCode $constraint */ - public function validate($value, Constraint $constraint): void + public function validate(mixed $value, Constraint $constraint): void { if (!$this->registry->hasProcessConfiguration($value)) { $this->context->buildViolation($constraint->messageNotExists) From 419b3d81eb415246f3f4b931a7417e443842d0df Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 17:49:52 +0100 Subject: [PATCH 063/115] Fix manager & controller services definition --- config/services/controller.yaml | 8 ++++++-- config/services/manager.yaml | 13 ++++++++----- src/Controller/Admin/Process/LaunchAction.php | 9 +++++---- src/Controller/Admin/Process/ListAction.php | 3 ++- .../Admin/Process/UploadAndExecuteAction.php | 9 +++++---- src/Controller/Admin/ProcessDashboardController.php | 3 ++- src/Controller/Admin/Security/LoginController.php | 3 ++- src/Controller/Admin/Security/LogoutController.php | 3 ++- 8 files changed, 32 insertions(+), 19 deletions(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 90405a3..fa3a534 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -4,7 +4,11 @@ services: autowire: true autoconfigure: true bind: - $processLogDir: '%process_logs_dir%' - $indexLogs: '%clever_age_process_ui.index_logs.enabled%' + $processConfigurationsManager: '@cleverage_ui_process.manager.process_configuration' + $localeSwitcher: '@translation.locale_switcher' + $request: '@request_stack' + $messageBus: '@messenger.default_bus' + $uploadDirectory: '%upload_directory%' + $context: '@EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext' tags: - { name: 'controller.service_arguments' } diff --git a/config/services/manager.yaml b/config/services/manager.yaml index 973a110..45edb15 100644 --- a/config/services/manager.yaml +++ b/config/services/manager.yaml @@ -1,9 +1,12 @@ services: - cleverage_ui_process.manager.configuration: - class: CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager + cleverage_ui_process.manager.process_execution: + class: CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager public: false arguments: - - '@cleverage_process.registry.process_configuration' + - '@cleverage_ui_process.repository.process_execution' - CleverAge\ProcessUiBundle\Manager\ProcessUiConfigurationManager: - alias: 'cleverage_ui_process.manager.configuration' + cleverage_ui_process.manager.process_configuration: + class: CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager + public: false + arguments: + - '@cleverage_process.registry.process_configuration' diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 69a1830..26bf25b 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -29,10 +29,11 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; -#[\Symfony\Component\Routing\Attribute\Route( +#[Route( '/process/launch', name: 'process_launch', requirements: ['process' => '\w+'], @@ -44,12 +45,12 @@ class LaunchAction extends AbstractController public function __invoke( RequestStack $requestStack, MessageBusInterface $messageBus, - #[Autowire(param: 'upload_directory')] string $uploadDirectory, + string $uploadDirectory, #[ValueResolver('process')] ProcessConfiguration $processConfiguration, - ProcessConfigurationsManager $configurationsManager, + ProcessConfigurationsManager $processConfigurationsManager, AdminContext $context, ): Response { - $uiOptions = $configurationsManager->getUiOptions($requestStack->getMainRequest()?->get('process') ?? ''); + $uiOptions = $processConfigurationsManager->getUiOptions($requestStack->getMainRequest()?->get('process') ?? ''); $form = $this->createForm( LaunchType::class, null, diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php index 98a0d2c..e6fd4b6 100644 --- a/src/Controller/Admin/Process/ListAction.php +++ b/src/Controller/Admin/Process/ListAction.php @@ -16,9 +16,10 @@ use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -#[\Symfony\Component\Routing\Attribute\Route('/process/list', name: 'process_list')] +#[Route('/process/list', name: 'process_list')] #[IsGranted('ROLE_USER')] class ListAction extends AbstractController { diff --git a/src/Controller/Admin/Process/UploadAndExecuteAction.php b/src/Controller/Admin/Process/UploadAndExecuteAction.php index 87d39c1..614f587 100644 --- a/src/Controller/Admin/Process/UploadAndExecuteAction.php +++ b/src/Controller/Admin/Process/UploadAndExecuteAction.php @@ -14,20 +14,21 @@ namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; +use CleverAge\ProcessBundle\Configuration\TaskConfiguration; use CleverAge\ProcessUiBundle\Form\Type\ProcessUploadFileType; use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; -#[\Symfony\Component\Routing\Attribute\Route( +#[Route( '/process/upload-and-execute', name: 'process_upload_and_execute', requirements: ['process' => '\w+'], @@ -39,10 +40,10 @@ class UploadAndExecuteAction extends AbstractController public function __invoke( RequestStack $requestStack, MessageBusInterface $messageBus, - #[Autowire(param: 'upload_directory')] string $uploadDirectory, + string $uploadDirectory, #[ValueResolver('process')] ProcessConfiguration $processConfiguration, ): Response { - if (!$processConfiguration->getEntryPoint() instanceof \CleverAge\ProcessBundle\Configuration\TaskConfiguration) { + if (!$processConfiguration->getEntryPoint() instanceof TaskConfiguration) { throw new \RuntimeException('You must set an entry_point.'); } $form = $this->createForm( diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 5c380f8..22ee1c0 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -23,6 +23,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Translation\LocaleSwitcher; @@ -35,7 +36,7 @@ public function __construct( ) { } - #[\Symfony\Component\Routing\Attribute\Route('/process', name: 'process')] + #[Route('/process', name: 'process')] public function index(): Response { $adminUrlGenerator = $this->container->get(AdminUrlGenerator::class); diff --git a/src/Controller/Admin/Security/LoginController.php b/src/Controller/Admin/Security/LoginController.php index 01db200..ed49f18 100644 --- a/src/Controller/Admin/Security/LoginController.php +++ b/src/Controller/Admin/Security/LoginController.php @@ -15,10 +15,11 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; class LoginController extends AbstractController { - #[\Symfony\Component\Routing\Attribute\Route('/process/login', name: 'process_login')] + #[Route('/process/login', name: 'process_login')] public function __invoke(): Response { return $this->render( diff --git a/src/Controller/Admin/Security/LogoutController.php b/src/Controller/Admin/Security/LogoutController.php index 2d6b66c..a49cba1 100644 --- a/src/Controller/Admin/Security/LogoutController.php +++ b/src/Controller/Admin/Security/LogoutController.php @@ -16,10 +16,11 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Attribute\Route; class LogoutController extends AbstractController { - #[\Symfony\Component\Routing\Attribute\Route('/process/logout', name: 'process_logout')] + #[Route('/process/logout', name: 'process_logout')] public function __invoke(Security $security): Response { $security->logout(); From d39754c504b5c5eaae4d224c52ebf4874f367e6e Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 19 Nov 2024 17:51:06 +0100 Subject: [PATCH 064/115] Fix command services definition --- config/services/command.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/config/services/command.yaml b/config/services/command.yaml index 73f5b02..ef5a20d 100644 --- a/config/services/command.yaml +++ b/config/services/command.yaml @@ -1,13 +1,4 @@ services: - cleverage_ui_process.command.purge_process_execution: - class: CleverAge\ProcessUiBundle\Command\PurgeProcessExecution - public: false - tags: - - { name: console.command } - arguments: - - '@cleverage_ui_process.repository.process_execution' - - '%process_logs_dir%' - cleverage_ui_process.command.user_create: class: CleverAge\ProcessUiBundle\Command\UserCreateCommand public: false From 4cedf5eb5a3d31b08bb5f8952bb15476dbadc872 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 10:47:40 +0100 Subject: [PATCH 065/115] Fix event_subscriber & monolog_handler services definition --- config/services/event_subscriber.yaml | 18 +++--------------- config/services/monolog_handler.yaml | 14 +++++++++++--- src/Monolog/Handler/DoctrineProcessHandler.php | 3 --- src/Monolog/Handler/ProcessHandler.php | 3 +-- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml index 8aed4df..8b27d91 100644 --- a/config/services/event_subscriber.yaml +++ b/config/services/event_subscriber.yaml @@ -5,18 +5,6 @@ services: tags: - { name: 'kernel.event_subscriber' } arguments: - - '@doctrine.orm.entity_manager' - - '@cleverage_ui_process.repository.process' - - '@cleverage_ui_process.monolog_handler.process_log' - - '@messenger.default_bus' - - '@cleverage_ui_process.manager.configuration' - - '%process_logs_dir%' - - '%clever_age_process_ui.index_logs.enabled%' - - cleverage_ui_process.event_subscriber.crud.process: - class: CleverAge\ProcessUiBundle\EventSubscriber\Crud\ProcessCrudListener - public: false - tags: - - { name: 'kernel.event_subscriber' } - arguments: - - '@cleverage_ui_process.repository.process' + - '@cleverage_ui_process.monolog_handler.process' + - '@cleverage_ui_process.monolog_handler.doctrine_process' + - '@cleverage_ui_process.manager.process_execution' diff --git a/config/services/monolog_handler.yaml b/config/services/monolog_handler.yaml index cacc088..294f525 100644 --- a/config/services/monolog_handler.yaml +++ b/config/services/monolog_handler.yaml @@ -1,7 +1,15 @@ services: - cleverage_ui_process.monolog_handler.process_log: - class: CleverAge\ProcessUiBundle\Monolog\Handler\ProcessLogHandler + cleverage_ui_process.monolog_handler.doctrine_process: + class: CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler + public: false + calls: + - [ setEntityManager, [ '@doctrine.orm.entity_manager' ] ] + - [ setProcessExecutionManager, [ '@cleverage_ui_process.manager.process_execution' ] ] + + cleverage_ui_process.monolog_handler.process: + class: CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler public: false arguments: - - '%process_logs_dir%' + - '%kernel.logs_dir%' + - '@cleverage_ui_process.manager.process_execution' diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index 7b99b93..3115be4 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -20,7 +20,6 @@ use Monolog\Handler\AbstractProcessingHandler; use Monolog\Level; use Monolog\LogRecord; -use Symfony\Contracts\Service\Attribute\Required; class DoctrineProcessHandler extends AbstractProcessingHandler { @@ -35,13 +34,11 @@ public function __construct(int|string|Level $level = Level::Debug, bool $bubble $this->records = new ArrayCollection(); } - #[Required] public function setEntityManager(EntityManagerInterface $em): void { $this->em = $em; } - #[Required] public function setProcessExecutionManager(ProcessExecutionManager $processExecutionManager): void { $this->processExecutionManager = $processExecutionManager; diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php index 5d4dd0c..2ff325b 100644 --- a/src/Monolog/Handler/ProcessHandler.php +++ b/src/Monolog/Handler/ProcessHandler.php @@ -17,14 +17,13 @@ use Monolog\Handler\StreamHandler; use Monolog\Level; use Monolog\LogRecord; -use Symfony\Component\DependencyInjection\Attribute\Autowire; class ProcessHandler extends StreamHandler { private Level $reportIncrementLevel = Level::Error; public function __construct( - #[Autowire(param: 'kernel.logs_dir')] private readonly string $directory, + private readonly string $directory, private readonly ProcessExecutionManager $processExecutionManager, ) { parent::__construct($this->directory); From 9f9958e9dd8c62364942985a677c1c74bf93f14b Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 10:56:30 +0100 Subject: [PATCH 066/115] Add http_value_resolver services definition --- config/services/http_value_resolver.yaml | 12 ++++++++++++ .../HttpProcessExecuteValueResolver.php | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 config/services/http_value_resolver.yaml diff --git a/config/services/http_value_resolver.yaml b/config/services/http_value_resolver.yaml new file mode 100644 index 0000000..8e0c0ce --- /dev/null +++ b/config/services/http_value_resolver.yaml @@ -0,0 +1,12 @@ +services: + cleverage_ui_process.http_value_resolver.http_process_execute: + class: CleverAge\ProcessUiBundle\Http\ValueResolver\HttpProcessExecuteValueResolver + public: false + arguments: + - '%upload_directory%' + + cleverage_ui_process.http_value_resolver.process_configuration: + class: CleverAge\ProcessUiBundle\Http\ValueResolver\ProcessConfigurationValueResolver + public: false + arguments: + - '@cleverage_process.registry.process_configuration' diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 58bcbd0..71f3941 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -14,7 +14,6 @@ namespace CleverAge\ProcessUiBundle\Http\ValueResolver; use CleverAge\ProcessUiBundle\Http\Model\HttpProcessExecution; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; @@ -25,7 +24,7 @@ #[AsTargetedValueResolver('http_process_execution')] readonly class HttpProcessExecuteValueResolver implements ValueResolverInterface { - public function __construct(#[Autowire(param: 'upload_directory')] private string $storageDir) + public function __construct(private string $storageDir) { } From 96e706dc50b4a046b59ce03de2c37315021696f3 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 11:03:11 +0100 Subject: [PATCH 067/115] Fix message & repository services definition --- config/services/message.yaml | 13 +++++++------ config/services/repository.yaml | 12 ++---------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/config/services/message.yaml b/config/services/message.yaml index af59384..eaa3873 100644 --- a/config/services/message.yaml +++ b/config/services/message.yaml @@ -1,13 +1,14 @@ services: - cleverage_ui_process.message.log_indexer_handler: - class: CleverAge\ProcessUiBundle\Message\LogIndexerHandler + cleverage_ui_process.message.cron_process_message_handler: + class: CleverAge\ProcessUiBundle\Message\CronProcessMessageHandler public: false arguments: - - '@doctrine' + - '@messenger.default_bus' - cleverage_ui_process.message.process_run_handler: - class: CleverAge\ProcessUiBundle\Message\ProcessRunHandler + cleverage_ui_process.message.process_execute_handler: + class: CleverAge\ProcessUiBundle\Message\ProcessExecuteHandler public: false arguments: - - '@cleverage_process.command.execute_process' + - '@cleverage_process.manager.process' + - '@cleverage_ui_process.monolog_handler.process' diff --git a/config/services/repository.yaml b/config/services/repository.yaml index 0456ccc..13ec0ca 100644 --- a/config/services/repository.yaml +++ b/config/services/repository.yaml @@ -5,16 +5,8 @@ services: arguments: - '@doctrine.orm.entity_manager' - cleverage_ui_process.repository.process: - class: CleverAge\ProcessUiBundle\Repository\ProcessRepository - public: false - arguments: - - '@doctrine.orm.entity_manager' - - '@cleverage_ui_process.manager.configuration' - - '@cleverage_process.registry.process_configuration' - - cleverage_ui_process.repository.user: - class: CleverAge\ProcessUiBundle\Repository\UserRepository + cleverage_ui_process.repository.process_schedule: + class: CleverAge\ProcessUiBundle\Repository\ProcessScheduleRepository public: false arguments: - '@doctrine.orm.entity_manager' From 4142a57df948e2a581eb58ef9de60c0efc1a920d Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 11:18:07 +0100 Subject: [PATCH 068/115] Fix security services definition --- config/services/security.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/services/security.yaml b/config/services/security.yaml index ba5a36d..fa54359 100644 --- a/config/services/security.yaml +++ b/config/services/security.yaml @@ -1,7 +1,7 @@ services: - cleverage_ui_process.security.login_form_auth_authenticator: - class: CleverAge\ProcessUiBundle\Security\LoginFormAuthAuthenticator + cleverage_ui_process.security.http_process_execution_authenticator: + class: CleverAge\ProcessUiBundle\Security\HttpProcessExecutionAuthenticator public: false arguments: - - '@router' + - '@doctrine.orm.entity_manager' From f0e52202cc89752751da4b8315ceb96844b0a1a3 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 11:18:29 +0100 Subject: [PATCH 069/115] Add scheduler, twig & validator services definition --- config/services/scheduler.yaml | 8 ++++++++ config/services/twig.yaml | 25 +++++++++++++++++++++++++ config/services/validator.yaml | 21 +++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 config/services/scheduler.yaml create mode 100644 config/services/twig.yaml create mode 100644 config/services/validator.yaml diff --git a/config/services/scheduler.yaml b/config/services/scheduler.yaml new file mode 100644 index 0000000..794570a --- /dev/null +++ b/config/services/scheduler.yaml @@ -0,0 +1,8 @@ +services: + cleverage_ui_process.scheduler.cron: + class: CleverAge\ProcessUiBundle\Scheduler\CronScheduler + public: false + arguments: + - '@cleverage_ui_process.repository.process_schedule' + - '@validator' + - '@logger' diff --git a/config/services/twig.yaml b/config/services/twig.yaml new file mode 100644 index 0000000..7c031bf --- /dev/null +++ b/config/services/twig.yaml @@ -0,0 +1,25 @@ +services: + cleverage_ui_process.twig.log_level_extension: + class: CleverAge\ProcessUiBundle\Twig\Extension\LogLevelExtension + public: false + tags: + - { name: 'twig.extension' } + + cleverage_ui_process.twig.md5_extension: + class: CleverAge\ProcessUiBundle\Twig\Extension\MD5Extension + public: false + tags: + - { name: 'twig.extension' } + + cleverage_ui_process.twig.process_execution_extension: + class: CleverAge\ProcessUiBundle\Twig\Extension\ProcessExecutionExtension + public: false + tags: + - { name: 'twig.extension' } + + cleverage_ui_process.twig.process_execution_extension_runtime: + class: CleverAge\ProcessUiBundle\Twig\Runtime\ProcessExecutionExtensionRuntime + public: false + arguments: + - '@cleverage_ui_process.repository.process_execution' + - '@cleverage_ui_process.manager.process_configuration' diff --git a/config/services/validator.yaml b/config/services/validator.yaml new file mode 100644 index 0000000..e876335 --- /dev/null +++ b/config/services/validator.yaml @@ -0,0 +1,21 @@ +services: + cleverage_ui_process.validator.cron_expression_validator: + class: CleverAge\ProcessUiBundle\Validator\CronExpressionValidator + public: false + tags: + - { name: 'validator.constraint_validator' } + + cleverage_ui_process.validator.every_expression_validator: + class: CleverAge\ProcessUiBundle\Validator\EveryExpressionValidator + public: false + tags: + - { name: 'validator.constraint_validator' } + + cleverage_ui_process.validator.is_valid_process_code: + class: CleverAge\ProcessUiBundle\Validator\IsValidProcessCodeValidator + public: false + tags: + - { name: 'validator.constraint_validator' } + arguments: + - '@cleverage_process.registry.process_configuration' + From 496759b641259806e592085613c5504c57bf2114 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 11:30:00 +0100 Subject: [PATCH 070/115] Fix DependencyInjection using service name instead of class FQCN & remove last autowire annotation --- config/services/controller.yaml | 1 + src/Controller/Admin/Process/LaunchAction.php | 1 - .../Admin/ProcessExecutionCrudController.php | 5 ++--- .../CleverAgeProcessUiExtension.php | 8 +++----- src/Monolog/Handler/DoctrineProcessHandler.php | 2 +- src/Monolog/Handler/ProcessHandler.php | 16 ++++++++-------- 6 files changed, 15 insertions(+), 18 deletions(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index fa3a534..c9a8d77 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -10,5 +10,6 @@ services: $messageBus: '@messenger.default_bus' $uploadDirectory: '%upload_directory%' $context: '@EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext' + $logDirectory: '%kernel.logs_dir%' tags: - { name: 'controller.service_arguments' } diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 26bf25b..d68af22 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -21,7 +21,6 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Asset; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\File\UploadedFile; diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index cb21820..b5a9666 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -25,7 +25,6 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -116,11 +115,11 @@ public function showLogs(AdminContext $adminContext): RedirectResponse public function downloadLogFile( AdminContext $context, - #[Autowire(param: 'kernel.logs_dir')] string $directory, + string $logDirectory, ): Response { /** @var ProcessExecution $processExecution */ $processExecution = $context->getEntity()->getInstance(); - $filepath = $directory.\DIRECTORY_SEPARATOR.$processExecution->code.\DIRECTORY_SEPARATOR + $filepath = $logDirectory.\DIRECTORY_SEPARATOR.$processExecution->code.\DIRECTORY_SEPARATOR .$processExecution->logFilename; $basename = basename($filepath); $content = file_get_contents($filepath); diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeProcessUiExtension.php index 173fbb6..d532189 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeProcessUiExtension.php @@ -17,8 +17,6 @@ use CleverAge\ProcessUiBundle\Controller\Admin\UserCrudController; use CleverAge\ProcessUiBundle\Entity\User; use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; -use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; use Monolog\Level; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -37,7 +35,7 @@ public function load(array $configs, ContainerBuilder $container): void $config = $this->processConfiguration($configuration, $configs); $container->getDefinition(UserCrudController::class) ->setArgument('$roles', array_combine($config['security']['roles'], $config['security']['roles'])); - $container->getDefinition(ProcessHandler::class) + $container->getDefinition('cleverage_ui_process.monolog_handler.process') ->addMethodCall('setReportIncrementLevel', [$config['logs']['report_increment_level']]); $container->getDefinition(ProcessDashboardController::class) ->setArgument('$logoPath', $config['design']['logo_path']); @@ -55,11 +53,11 @@ public function prepend(ContainerBuilder $container): void 'handlers' => [ 'pb_ui_file' => [ 'type' => 'service', - 'id' => ProcessHandler::class, + 'id' => 'cleverage_ui_process.monolog_handler.process', ], 'pb_ui_orm' => [ 'type' => 'service', - 'id' => DoctrineProcessHandler::class, + 'id' => 'cleverage_ui_process.monolog_handler.doctrine_process', ], ], ] diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index 3115be4..1595694 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -25,7 +25,7 @@ class DoctrineProcessHandler extends AbstractProcessingHandler { /** @var ArrayCollection */ private ArrayCollection $records; - private ?ProcessExecutionManager $processExecutionManager; + private ?ProcessExecutionManager $processExecutionManager = null; private ?EntityManagerInterface $em = null; public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php index 2ff325b..be51136 100644 --- a/src/Monolog/Handler/ProcessHandler.php +++ b/src/Monolog/Handler/ProcessHandler.php @@ -29,6 +29,14 @@ public function __construct( parent::__construct($this->directory); } + /** + * @param 'ALERT'|'Alert'|'alert'|'CRITICAL'|'Critical'|'critical'|'DEBUG'|'Debug'|'debug'|'EMERGENCY'|'Emergency'|'emergency'|'ERROR'|'Error'|'error'|'INFO'|'Info'|'info'|'NOTICE'|'Notice'|'notice'|'WARNING'|'Warning'|'warning' $level + */ + public function setReportIncrementLevel(string $level): void + { + $this->reportIncrementLevel = Level::fromName($level); + } + public function hasFilename(): bool { return $this->directory !== $this->url; @@ -57,12 +65,4 @@ public function write(LogRecord $record): void $this->processExecutionManager->increment($record->level->name); } } - - /** - * @param 'ALERT'|'Alert'|'alert'|'CRITICAL'|'Critical'|'critical'|'DEBUG'|'Debug'|'debug'|'EMERGENCY'|'Emergency'|'emergency'|'ERROR'|'Error'|'error'|'INFO'|'Info'|'info'|'NOTICE'|'Notice'|'notice'|'WARNING'|'Warning'|'warning' $level - */ - public function setReportIncrementLevel(string $level): void - { - $this->reportIncrementLevel = Level::fromName($level); - } } From 3fc81eea9de0035b03e2be593ab1df845130aa5b Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 11:56:50 +0100 Subject: [PATCH 071/115] Fix controller $context definition using AdminContextFactory --- config/services/controller.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index c9a8d77..38b6790 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -9,7 +9,7 @@ services: $request: '@request_stack' $messageBus: '@messenger.default_bus' $uploadDirectory: '%upload_directory%' - $context: '@EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext' + $context: '@EasyCorp\Bundle\EasyAdminBundle\Factory\AdminContextFactory' $logDirectory: '%kernel.logs_dir%' tags: - { name: 'controller.service_arguments' } From 8a9eaecfb1153425c55f8a298eb548e7918d1d88 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 12:00:18 +0100 Subject: [PATCH 072/115] Fix documentation --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 1cf258f..6a9311c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,8 +22,9 @@ CleverAge\UiProcessBundle\CleverAgeUiProcessBundle::class => ['all' => true], ## Import routes ```yaml -processui: - resource: '@CleverAgeProcessUiBundle/src/Controller' type: attribute +ui-process-bundle: + resource: '@CleverAgeProcessUiBundle/src/Controller' + type: attribute ``` * Run doctrine migration * Create an user using cleverage:ui-process:user-create console. From a33b94d644156dd004bd5f0264eb793f7002530a Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 12:32:25 +0100 Subject: [PATCH 073/115] #9 composer require vincentlanglet/twig-cs-fixer and add it to quality rules (Makefile & github quality actions) --- .github/workflows/quality.yml | 17 +++++++++++++++++ .gitignore | 4 ++++ Makefile | 5 ++++- composer.json | 3 ++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 9f1580f..c926661 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -60,3 +60,20 @@ jobs: uses: ramsey/composer-install@v3 - name: Rector run: vendor/bin/rector --no-progress-bar --dry-run + + twig-cs-fixer: + name: Twig-CS-Fixer + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Install PHP with extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + tools: composer:v2 + - name: Install Composer dependencies (locked) + uses: ramsey/composer-install@v3 + - name: Twig-CS-Fixer + run: vendor/bin/twig-cs-fixer lint --report=github diff --git a/.gitignore b/.gitignore index b13d896..40db549 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ coverage-report npm-debug.log yarn-error.log ###< symfony/webpack-encore-bundle ### + +###> vincentlanglet/twig-cs-fixer ### +/.twig-cs-fixer.cache +###< vincentlanglet/twig-cs-fixer ### diff --git a/Makefile b/Makefile index 0a58e32..4970ded 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ bash: #[Docker] Connect to php container with current host user logs: #[Docker] Show logs $(DOCKER_COMPOSE) logs -f -quality: phpstan php-cs-fixer rector #[Quality] Run all quality checks +quality: phpstan php-cs-fixer rector twig-cs-fixer #[Quality] Run all quality checks phpstan: #[Quality] Run PHPStan $(DOCKER_RUN_PHP) "vendor/bin/phpstan --no-progress --memory-limit=1G analyse" @@ -48,6 +48,9 @@ php-cs-fixer: #[Quality] Run PHP-CS-Fixer rector: #[Quality] Run Rector $(DOCKER_RUN_PHP) "vendor/bin/rector" +twig-cs-fixer: #[Quality] Run Rector + $(DOCKER_RUN_PHP) "vendor/bin/twig-cs-fixer fix --verbose" + tests: phpunit #[Tests] Run all tests phpunit: #[Tests] Run PHPUnit diff --git a/composer.json b/composer.json index 2a7ee55..eb9a161 100644 --- a/composer.json +++ b/composer.json @@ -68,7 +68,8 @@ "symfony/css-selector": "^6.4|^7.1", "symfony/debug-bundle": "^6.4|^7.1", "symfony/maker-bundle": "^1.31", - "symfony/web-profiler-bundle": "^6.4|^7.1" + "symfony/web-profiler-bundle": "^6.4|^7.1", + "vincentlanglet/twig-cs-fixer": "^3.3" }, "config": { "allow-plugins": { From 5d39fee282985cc513cdf1c2081666e60b68660c Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 14:04:10 +0100 Subject: [PATCH 074/115] #9 Apply quality rules --- templates/admin/process/list.html.twig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index ac6d384..97de49b 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -32,7 +32,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - + From 7e1eeddd4d0acb9316f6a0c17cb66240ad85b008 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 14:19:32 +0100 Subject: [PATCH 075/115] #3 Rename process-ui-bundle to ui-process-bundle, cleverage:process-ui:xxx to cleverage:ui-process:xxx and clever_age_process_ui to cleverage_ui_process --- docs/index.md | 10 +++++----- src/Command/UserCreateCommand.php | 2 +- src/DependencyInjection/Configuration.php | 4 ++-- src/Manager/ProcessConfigurationsManager.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6a9311c..38633c7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,7 +13,7 @@ Open a command console, enter your project directory and install it using compos composer require cleverage/ui-process-bundle ``` -Remember to add the following line to config/bundles.php (not required if Symfony Flex is used) +Remember to add the following line to `config/bundles.php` (not required if Symfony Flex is used) ```php CleverAge\UiProcessBundle\CleverAgeUiProcessBundle::class => ['all' => true], @@ -27,7 +27,7 @@ ui-process-bundle: type: attribute ``` * Run doctrine migration -* Create an user using cleverage:ui-process:user-create console. +* Create a user using `cleverage:ui-process:user-create` console. Now you can access Process UI via http://your-domain.com/process @@ -37,19 +37,19 @@ Now you can access Process UI via http://your-domain.com/process You can launch a process via http post request First you need to generate a token via UI User edit form. The ProcessUi generate for you a auth token (keep it in secured area, it will display once). -It' all, now you can launch a process via http post request +That's all, now you can launch a process via http post request ***Curl sample*** ```bash make bash -curl --location 'http://localhost/http/process/execute?code=demo.die' \ +curl --location 'http://apache2/http/process/execute?code=demo.die' \ --header 'Authorization: Bearer 3da8409b5f5b640fb0c43d68e8ac8d23' \ --form 'input=@"/file.csv"' \ --form 'context[context_1]="FOO"' \ --form 'context[context_2]="BAR"' ``` * Query string code parameter must be a valid process code -* Header Autorization: Bearer is the previously generated token +* Header Authorization: Bearer is the previously generated token * input could be string or file representation * context you can pass multiple context values diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index 17a8480..558ca2c 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -30,7 +30,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface; #[AsCommand( - name: 'cleverage:process-ui:user-create', + name: 'cleverage:ui-process:user-create', description: 'Command to create a new admin into database for process ui.' )] class UserCreateCommand extends Command diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 7b9ed08..9b76bf9 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -22,7 +22,7 @@ class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { - $tb = new TreeBuilder('clever_age_process_ui'); + $tb = new TreeBuilder('cleverage_ui_process'); /** @var ArrayNodeDefinition $rootNode */ $rootNode = $tb->getRootNode(); $rootNode @@ -45,7 +45,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->arrayNode('design') ->addDefaultsIfNotSet() ->children() - ->scalarNode('logo_path')->defaultValue('bundles/cleverageprocessui/logo.jpg')->end() + ->scalarNode('logo_path')->defaultValue('bundles/cleverageuiprocess/logo.jpg')->end() ->end(); return $tb; diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 5ce8601..74f8393 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -70,7 +70,7 @@ private function resolveUiOptions(array $options): array ); $uiResolver->setDeprecated( 'run', - 'cleverage/process-ui-bundle', + 'cleverage/ui-process-bundle', '2', 'run ui option is deprecated. Use public option instead to hide a process from UI' ); From ac7806bc13e756aaa2b34d0d2c6457b1bbd2f5fa Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 14:28:53 +0100 Subject: [PATCH 076/115] #3 Rename ProcessUi*** to UiProcess*** & Update CHANGELOG --- CHANGELOG.md | 5 +++-- composer.json | 4 ++-- config/services/command.yaml | 2 +- config/services/controller.yaml | 2 +- config/services/event_subscriber.yaml | 2 +- config/services/http_value_resolver.yaml | 4 ++-- config/services/manager.yaml | 4 ++-- config/services/message.yaml | 4 ++-- config/services/monolog_handler.yaml | 4 ++-- config/services/repository.yaml | 4 ++-- config/services/scheduler.yaml | 2 +- config/services/security.yaml | 2 +- config/services/twig.yaml | 8 ++++---- config/services/validator.yaml | 6 +++--- docs/index.md | 6 +++--- src/Admin/Field/EnumField.php | 4 ++-- src/Admin/Field/LogLevelField.php | 4 ++-- src/Admin/Filter/LogProcessFilter.php | 2 +- ...ssUiBundle.php => CleverAgeUiProcessBundle.php} | 4 ++-- src/Command/UserCreateCommand.php | 6 +++--- src/Controller/Admin/LogRecordCrudController.php | 12 ++++++------ src/Controller/Admin/Process/LaunchAction.php | 12 ++++++------ src/Controller/Admin/Process/ListAction.php | 6 +++--- .../Admin/Process/UploadAndExecuteAction.php | 8 ++++---- .../Admin/ProcessDashboardController.php | 10 +++++----- .../Admin/ProcessExecutionCrudController.php | 14 +++++++------- .../Admin/ProcessScheduleCrudController.php | 12 ++++++------ src/Controller/Admin/Security/LoginController.php | 4 ++-- src/Controller/Admin/Security/LogoutController.php | 2 +- src/Controller/Admin/UserCrudController.php | 4 ++-- src/Controller/ProcessExecuteController.php | 6 +++--- ...tension.php => CleverAgeUiProcessExtension.php} | 14 +++++++------- src/DependencyInjection/Configuration.php | 2 +- src/Entity/Enum/ProcessExecutionStatus.php | 2 +- src/Entity/LogRecord.php | 2 +- src/Entity/ProcessExecution.php | 4 ++-- src/Entity/ProcessSchedule.php | 10 +++++----- src/Entity/User.php | 2 +- src/EventSubscriber/ProcessEventSubscriber.php | 12 ++++++------ src/Form/Type/LaunchType.php | 4 ++-- src/Form/Type/ProcessContextType.php | 2 +- src/Form/Type/ProcessUploadFileType.php | 2 +- src/Http/Model/HttpProcessExecution.php | 4 ++-- .../HttpProcessExecuteValueResolver.php | 4 ++-- .../ProcessConfigurationValueResolver.php | 2 +- src/Manager/ProcessConfigurationsManager.php | 2 +- src/Manager/ProcessExecutionManager.php | 6 +++--- src/Message/CronProcessMessage.php | 4 ++-- src/Message/CronProcessMessageHandler.php | 2 +- src/Message/ProcessExecuteHandler.php | 4 ++-- src/Message/ProcessExecuteMessage.php | 2 +- src/Migrations/Version20231006111525.php | 2 +- src/Migrations/Version20240729151928.php | 2 +- src/Migrations/Version20240730090403.php | 2 +- src/Migrations/Version20241007134542.php | 2 +- src/Migrations/Version20241007152613.php | 2 +- src/Migrations/Version20241009075733.php | 2 +- src/Monolog/Handler/DoctrineProcessHandler.php | 8 ++++---- src/Monolog/Handler/ProcessHandler.php | 4 ++-- src/Repository/ProcessExecutionRepository.php | 4 ++-- src/Repository/ProcessScheduleRepository.php | 4 ++-- src/Scheduler/CronScheduler.php | 8 ++++---- src/Security/HttpProcessExecutionAuthenticator.php | 4 ++-- src/Twig/Extension/LogLevelExtension.php | 4 ++-- src/Twig/Extension/MD5Extension.php | 4 ++-- src/Twig/Extension/ProcessExecutionExtension.php | 4 ++-- src/Twig/Runtime/LogLevelExtensionRuntime.php | 2 +- src/Twig/Runtime/MD5ExtensionRuntime.php | 2 +- .../Runtime/ProcessExecutionExtensionRuntime.php | 8 ++++---- src/Validator/CronExpression.php | 2 +- src/Validator/CronExpressionValidator.php | 2 +- src/Validator/EveryExpression.php | 2 +- src/Validator/EveryExpressionValidator.php | 2 +- src/Validator/IsValidProcessCode.php | 2 +- src/Validator/IsValidProcessCodeValidator.php | 2 +- templates/admin/process/list.html.twig | 2 +- 76 files changed, 169 insertions(+), 168 deletions(-) rename src/{CleverAgeProcessUiBundle.php => CleverAgeUiProcessBundle.php} (82%) rename src/DependencyInjection/{CleverAgeProcessUiExtension.php => CleverAgeUiProcessExtension.php} (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bcaf59..52cbc66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,12 @@ v2.0 * [#4](https://github.com/cleverage/ui-process-bundle/issues/4) Update composer : "doctrine/*" using same versions of doctrine-process-bundle. Remove "sensio/framework-extra-bundle" & "symfony/flex". Update require-dev using "process-bundle" standard. Reinstall "symfony/debug-pack". - "symfony/*" from ^5.4 to ^6.4|^7.1 => Update changes on code. "league/flysystem-bundle" from ^2.2 to ^3.0" (same as flysystem-process-bundle). - "twig/extra-bundle" and "twig/intl-extra" to ^3.8 + "symfony/*" from ^5.4 to ^6.4|^7.1 => Update changes on code. * [#2](https://github.com/cleverage/ui-process-bundle/issues/2) Routes must be prefixed with the bundle alias => `cleverage_ui_process` * [#2](https://github.com/cleverage/ui-process-bundle/issues/2) Update services according to Symfony best practices. Services should not use autowiring or autoconfiguration. Instead, all services should be defined explicitly. Services must be prefixed with the bundle alias instead of using fully qualified class names => `cleverage_ui_process` +* [#3](https://github.com/cleverage/ui-process-bundle/issues/3) Rename process-ui-bundle to ui-process-bundle, + cleverage:process-ui:xxx to cleverage:ui-process:xxx, clever_age_process_ui to cleverage_ui_process and ProcessUi*** to UiProcess*** ### Changes diff --git a/composer.json b/composer.json index eb9a161..0e6ee7a 100644 --- a/composer.json +++ b/composer.json @@ -27,12 +27,12 @@ ], "autoload": { "psr-4": { - "CleverAge\\ProcessUiBundle\\": "src/" + "CleverAge\\UiProcessBundle\\": "src/" } }, "autoload-dev": { "psr-4": { - "CleverAge\\ProcessUiBundle\\Tests\\": "tests/" + "CleverAge\\UiProcessBundle\\Tests\\": "tests/" } }, "require": { diff --git a/config/services/command.yaml b/config/services/command.yaml index ef5a20d..e8f5c9f 100644 --- a/config/services/command.yaml +++ b/config/services/command.yaml @@ -1,6 +1,6 @@ services: cleverage_ui_process.command.user_create: - class: CleverAge\ProcessUiBundle\Command\UserCreateCommand + class: CleverAge\UiProcessBundle\Command\UserCreateCommand public: false tags: - { name: console.command } diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 38b6790..2aae5d8 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -1,5 +1,5 @@ services: - CleverAge\ProcessUiBundle\Controller\: + CleverAge\UiProcessBundle\Controller\: resource: '../../src/Controller/' autowire: true autoconfigure: true diff --git a/config/services/event_subscriber.yaml b/config/services/event_subscriber.yaml index 8b27d91..1a35949 100644 --- a/config/services/event_subscriber.yaml +++ b/config/services/event_subscriber.yaml @@ -1,6 +1,6 @@ services: cleverage_ui_process.event_subscriber.process: - class: CleverAge\ProcessUiBundle\EventSubscriber\ProcessEventSubscriber + class: CleverAge\UiProcessBundle\EventSubscriber\ProcessEventSubscriber public: false tags: - { name: 'kernel.event_subscriber' } diff --git a/config/services/http_value_resolver.yaml b/config/services/http_value_resolver.yaml index 8e0c0ce..5a18ae2 100644 --- a/config/services/http_value_resolver.yaml +++ b/config/services/http_value_resolver.yaml @@ -1,12 +1,12 @@ services: cleverage_ui_process.http_value_resolver.http_process_execute: - class: CleverAge\ProcessUiBundle\Http\ValueResolver\HttpProcessExecuteValueResolver + class: CleverAge\UiProcessBundle\Http\ValueResolver\HttpProcessExecuteValueResolver public: false arguments: - '%upload_directory%' cleverage_ui_process.http_value_resolver.process_configuration: - class: CleverAge\ProcessUiBundle\Http\ValueResolver\ProcessConfigurationValueResolver + class: CleverAge\UiProcessBundle\Http\ValueResolver\ProcessConfigurationValueResolver public: false arguments: - '@cleverage_process.registry.process_configuration' diff --git a/config/services/manager.yaml b/config/services/manager.yaml index 45edb15..4521e68 100644 --- a/config/services/manager.yaml +++ b/config/services/manager.yaml @@ -1,12 +1,12 @@ services: cleverage_ui_process.manager.process_execution: - class: CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager + class: CleverAge\UiProcessBundle\Manager\ProcessExecutionManager public: false arguments: - '@cleverage_ui_process.repository.process_execution' cleverage_ui_process.manager.process_configuration: - class: CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager + class: CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager public: false arguments: - '@cleverage_process.registry.process_configuration' diff --git a/config/services/message.yaml b/config/services/message.yaml index eaa3873..7df35bd 100644 --- a/config/services/message.yaml +++ b/config/services/message.yaml @@ -1,12 +1,12 @@ services: cleverage_ui_process.message.cron_process_message_handler: - class: CleverAge\ProcessUiBundle\Message\CronProcessMessageHandler + class: CleverAge\UiProcessBundle\Message\CronProcessMessageHandler public: false arguments: - '@messenger.default_bus' cleverage_ui_process.message.process_execute_handler: - class: CleverAge\ProcessUiBundle\Message\ProcessExecuteHandler + class: CleverAge\UiProcessBundle\Message\ProcessExecuteHandler public: false arguments: - '@cleverage_process.manager.process' diff --git a/config/services/monolog_handler.yaml b/config/services/monolog_handler.yaml index 294f525..1dc3978 100644 --- a/config/services/monolog_handler.yaml +++ b/config/services/monolog_handler.yaml @@ -1,13 +1,13 @@ services: cleverage_ui_process.monolog_handler.doctrine_process: - class: CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler + class: CleverAge\UiProcessBundle\Monolog\Handler\DoctrineProcessHandler public: false calls: - [ setEntityManager, [ '@doctrine.orm.entity_manager' ] ] - [ setProcessExecutionManager, [ '@cleverage_ui_process.manager.process_execution' ] ] cleverage_ui_process.monolog_handler.process: - class: CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler + class: CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler public: false arguments: - '%kernel.logs_dir%' diff --git a/config/services/repository.yaml b/config/services/repository.yaml index 13ec0ca..a39784c 100644 --- a/config/services/repository.yaml +++ b/config/services/repository.yaml @@ -1,12 +1,12 @@ services: cleverage_ui_process.repository.process_execution: - class: CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository + class: CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository public: false arguments: - '@doctrine.orm.entity_manager' cleverage_ui_process.repository.process_schedule: - class: CleverAge\ProcessUiBundle\Repository\ProcessScheduleRepository + class: CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository public: false arguments: - '@doctrine.orm.entity_manager' diff --git a/config/services/scheduler.yaml b/config/services/scheduler.yaml index 794570a..7590703 100644 --- a/config/services/scheduler.yaml +++ b/config/services/scheduler.yaml @@ -1,6 +1,6 @@ services: cleverage_ui_process.scheduler.cron: - class: CleverAge\ProcessUiBundle\Scheduler\CronScheduler + class: CleverAge\UiProcessBundle\Scheduler\CronScheduler public: false arguments: - '@cleverage_ui_process.repository.process_schedule' diff --git a/config/services/security.yaml b/config/services/security.yaml index fa54359..2eda664 100644 --- a/config/services/security.yaml +++ b/config/services/security.yaml @@ -1,6 +1,6 @@ services: cleverage_ui_process.security.http_process_execution_authenticator: - class: CleverAge\ProcessUiBundle\Security\HttpProcessExecutionAuthenticator + class: CleverAge\UiProcessBundle\Security\HttpProcessExecutionAuthenticator public: false arguments: - '@doctrine.orm.entity_manager' diff --git a/config/services/twig.yaml b/config/services/twig.yaml index 7c031bf..8a5cd0f 100644 --- a/config/services/twig.yaml +++ b/config/services/twig.yaml @@ -1,24 +1,24 @@ services: cleverage_ui_process.twig.log_level_extension: - class: CleverAge\ProcessUiBundle\Twig\Extension\LogLevelExtension + class: CleverAge\UiProcessBundle\Twig\Extension\LogLevelExtension public: false tags: - { name: 'twig.extension' } cleverage_ui_process.twig.md5_extension: - class: CleverAge\ProcessUiBundle\Twig\Extension\MD5Extension + class: CleverAge\UiProcessBundle\Twig\Extension\MD5Extension public: false tags: - { name: 'twig.extension' } cleverage_ui_process.twig.process_execution_extension: - class: CleverAge\ProcessUiBundle\Twig\Extension\ProcessExecutionExtension + class: CleverAge\UiProcessBundle\Twig\Extension\ProcessExecutionExtension public: false tags: - { name: 'twig.extension' } cleverage_ui_process.twig.process_execution_extension_runtime: - class: CleverAge\ProcessUiBundle\Twig\Runtime\ProcessExecutionExtensionRuntime + class: CleverAge\UiProcessBundle\Twig\Runtime\ProcessExecutionExtensionRuntime public: false arguments: - '@cleverage_ui_process.repository.process_execution' diff --git a/config/services/validator.yaml b/config/services/validator.yaml index e876335..c4da724 100644 --- a/config/services/validator.yaml +++ b/config/services/validator.yaml @@ -1,18 +1,18 @@ services: cleverage_ui_process.validator.cron_expression_validator: - class: CleverAge\ProcessUiBundle\Validator\CronExpressionValidator + class: CleverAge\UiProcessBundle\Validator\CronExpressionValidator public: false tags: - { name: 'validator.constraint_validator' } cleverage_ui_process.validator.every_expression_validator: - class: CleverAge\ProcessUiBundle\Validator\EveryExpressionValidator + class: CleverAge\UiProcessBundle\Validator\EveryExpressionValidator public: false tags: - { name: 'validator.constraint_validator' } cleverage_ui_process.validator.is_valid_process_code: - class: CleverAge\ProcessUiBundle\Validator\IsValidProcessCodeValidator + class: CleverAge\UiProcessBundle\Validator\IsValidProcessCodeValidator public: false tags: - { name: 'validator.constraint_validator' } diff --git a/docs/index.md b/docs/index.md index 38633c7..0966b94 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,19 +23,19 @@ CleverAge\UiProcessBundle\CleverAgeUiProcessBundle::class => ['all' => true], ```yaml ui-process-bundle: - resource: '@CleverAgeProcessUiBundle/src/Controller' + resource: '@CleverAgeUiProcessBundle/src/Controller' type: attribute ``` * Run doctrine migration * Create a user using `cleverage:ui-process:user-create` console. -Now you can access Process UI via http://your-domain.com/process +Now you can access UI Process via http://your-domain.com/process ## Features ### Launch process via http request You can launch a process via http post request -First you need to generate a token via UI User edit form. The ProcessUi generate for you a auth token (keep it in secured area, it will display once). +First you need to generate a token via UI User edit form. The UiProcess generate for you a auth token (keep it in secured area, it will display once). That's all, now you can launch a process via http post request diff --git a/src/Admin/Field/EnumField.php b/src/Admin/Field/EnumField.php index 7d5a406..fd936f2 100644 --- a/src/Admin/Field/EnumField.php +++ b/src/Admin/Field/EnumField.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Admin\Field; +namespace CleverAge\UiProcessBundle\Admin\Field; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait; @@ -25,6 +25,6 @@ public static function new(string $propertyName, ?string $label = null): self return (new self()) ->setProperty($propertyName) ->setLabel($label) - ->setTemplatePath('@CleverAgeProcessUi/admin/field/enum.html.twig'); + ->setTemplatePath('@CleverAgeUiProcess/admin/field/enum.html.twig'); } } diff --git a/src/Admin/Field/LogLevelField.php b/src/Admin/Field/LogLevelField.php index f0d4c68..6f6fcfb 100644 --- a/src/Admin/Field/LogLevelField.php +++ b/src/Admin/Field/LogLevelField.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Admin\Field; +namespace CleverAge\UiProcessBundle\Admin\Field; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait; @@ -25,6 +25,6 @@ public static function new(string $propertyName, ?string $label = null): self return (new self()) ->setProperty($propertyName) ->setLabel($label) - ->setTemplatePath('@CleverAgeProcessUi/admin/field/log_level.html.twig'); + ->setTemplatePath('@CleverAgeUiProcess/admin/field/log_level.html.twig'); } } diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php index ed884a0..c11c74e 100644 --- a/src/Admin/Filter/LogProcessFilter.php +++ b/src/Admin/Filter/LogProcessFilter.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Admin\Filter; +namespace CleverAge\UiProcessBundle\Admin\Filter; use Doctrine\ORM\QueryBuilder; use EasyCorp\Bundle\EasyAdminBundle\Contracts\Filter\FilterInterface; diff --git a/src/CleverAgeProcessUiBundle.php b/src/CleverAgeUiProcessBundle.php similarity index 82% rename from src/CleverAgeProcessUiBundle.php rename to src/CleverAgeUiProcessBundle.php index 698933b..8acf1d7 100644 --- a/src/CleverAgeProcessUiBundle.php +++ b/src/CleverAgeUiProcessBundle.php @@ -11,11 +11,11 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle; +namespace CleverAge\UiProcessBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; -class CleverAgeProcessUiBundle extends Bundle +class CleverAgeUiProcessBundle extends Bundle { public function getPath(): string { diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index 558ca2c..806cc0c 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Command; +namespace CleverAge\UiProcessBundle\Command; -use CleverAge\ProcessUiBundle\Entity\User; +use CleverAge\UiProcessBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; @@ -31,7 +31,7 @@ #[AsCommand( name: 'cleverage:ui-process:user-create', - description: 'Command to create a new admin into database for process ui.' + description: 'Command to create a new admin into database for ui process.' )] class UserCreateCommand extends Command { diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 57d2831..918ee18 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -11,13 +11,13 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin; +namespace CleverAge\UiProcessBundle\Controller\Admin; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; -use CleverAge\ProcessUiBundle\Admin\Field\LogLevelField; -use CleverAge\ProcessUiBundle\Admin\Filter\LogProcessFilter; -use CleverAge\ProcessUiBundle\Entity\LogRecord; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Admin\Field\LogLevelField; +use CleverAge\UiProcessBundle\Admin\Filter\LogProcessFilter; +use CleverAge\UiProcessBundle\Entity\LogRecord; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -53,7 +53,7 @@ public function configureFields(string $pageName): iterable TextField::new('message')->setMaxLength(512), DateTimeField::new('createdAt')->setFormat('Y/M/dd H:mm:ss'), ArrayField::new('context') - ->setTemplatePath('@CleverAgeProcessUi/admin/field/array.html.twig') + ->setTemplatePath('@CleverAgeUiProcess/admin/field/array.html.twig') ->onlyOnDetail(), BooleanField::new('contextIsEmpty', 'Has context info ?') ->onlyOnIndex() diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index d68af22..faa8ee5 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -11,13 +11,13 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; +namespace CleverAge\UiProcessBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; -use CleverAge\ProcessUiBundle\Entity\User; -use CleverAge\ProcessUiBundle\Form\Type\LaunchType; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; -use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; +use CleverAge\UiProcessBundle\Entity\User; +use CleverAge\UiProcessBundle\Form\Type\LaunchType; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage; use EasyCorp\Bundle\EasyAdminBundle\Config\Asset; use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -95,7 +95,7 @@ public function __invoke( $context->getAssets()->addJsAsset(Asset::fromEasyAdminAssetPackage('field-collection.js')->getAsDto()); return $this->render( - '@CleverAgeProcessUi/admin/process/launch.html.twig', + '@CleverAgeUiProcess/admin/process/launch.html.twig', [ 'form' => $form->createView(), ] diff --git a/src/Controller/Admin/Process/ListAction.php b/src/Controller/Admin/Process/ListAction.php index e6fd4b6..4bd60e9 100644 --- a/src/Controller/Admin/Process/ListAction.php +++ b/src/Controller/Admin/Process/ListAction.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; +namespace CleverAge\UiProcessBundle\Controller\Admin\Process; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -26,7 +26,7 @@ class ListAction extends AbstractController public function __invoke(ProcessConfigurationsManager $processConfigurationsManager): Response { return $this->render( - '@CleverAgeProcessUi/admin/process/list.html.twig', + '@CleverAgeUiProcess/admin/process/list.html.twig', [ 'processes' => $processConfigurationsManager->getPublicProcesses(), ] diff --git a/src/Controller/Admin/Process/UploadAndExecuteAction.php b/src/Controller/Admin/Process/UploadAndExecuteAction.php index 614f587..8392263 100644 --- a/src/Controller/Admin/Process/UploadAndExecuteAction.php +++ b/src/Controller/Admin/Process/UploadAndExecuteAction.php @@ -11,12 +11,12 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin\Process; +namespace CleverAge\UiProcessBundle\Controller\Admin\Process; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessBundle\Configuration\TaskConfiguration; -use CleverAge\ProcessUiBundle\Form\Type\ProcessUploadFileType; -use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; +use CleverAge\UiProcessBundle\Form\Type\ProcessUploadFileType; +use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; @@ -72,7 +72,7 @@ public function __invoke( } return $this->render( - '@CleverAgeProcessUi/admin/process/upload_and_execute.html.twig', + '@CleverAgeUiProcess/admin/process/upload_and_execute.html.twig', [ 'form' => $form->createView(), ] diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 22ee1c0..6a60e97 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -11,12 +11,12 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin; +namespace CleverAge\UiProcessBundle\Controller\Admin; -use CleverAge\ProcessUiBundle\Entity\LogRecord; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; -use CleverAge\ProcessUiBundle\Entity\User; +use CleverAge\UiProcessBundle\Entity\LogRecord; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Entity\ProcessSchedule; +use CleverAge\UiProcessBundle\Entity\User; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard; use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem; diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index b5a9666..7033d2b 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin; +namespace CleverAge\UiProcessBundle\Controller\Admin; -use CleverAge\ProcessUiBundle\Admin\Field\EnumField; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Admin\Field\EnumField; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -45,13 +45,13 @@ public function configureFields(string $pageName): iterable EnumField::new('status'), DateTimeField::new('startDate')->setFormat('Y/M/dd H:mm:ss'), DateTimeField::new('endDate')->setFormat('Y/M/dd H:mm:ss'), - TextField::new('source')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_source.html.twig'), - TextField::new('target')->setTemplatePath('@CleverAgeProcessUi/admin/field/process_target.html.twig'), + TextField::new('source')->setTemplatePath('@CleverAgeUiProcess/admin/field/process_source.html.twig'), + TextField::new('target')->setTemplatePath('@CleverAgeUiProcess/admin/field/process_target.html.twig'), TextField::new('duration')->formatValue(function ($value, ProcessExecution $entity) { return $entity->duration(); // returned format can be changed here }), - ArrayField::new('report')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), - ArrayField::new('context')->setTemplatePath('@CleverAgeProcessUi/admin/field/report.html.twig'), + ArrayField::new('report')->setTemplatePath('@CleverAgeUiProcess/admin/field/report.html.twig'), + ArrayField::new('context')->setTemplatePath('@CleverAgeUiProcess/admin/field/report.html.twig'), ]; } diff --git a/src/Controller/Admin/ProcessScheduleCrudController.php b/src/Controller/Admin/ProcessScheduleCrudController.php index c7c6526..035ae2c 100644 --- a/src/Controller/Admin/ProcessScheduleCrudController.php +++ b/src/Controller/Admin/ProcessScheduleCrudController.php @@ -11,14 +11,14 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin; +namespace CleverAge\UiProcessBundle\Controller\Admin; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; -use CleverAge\ProcessUiBundle\Admin\Field\EnumField; -use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; -use CleverAge\ProcessUiBundle\Entity\ProcessScheduleType; -use CleverAge\ProcessUiBundle\Form\Type\ProcessContextType; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Admin\Field\EnumField; +use CleverAge\UiProcessBundle\Entity\ProcessSchedule; +use CleverAge\UiProcessBundle\Entity\ProcessScheduleType; +use CleverAge\UiProcessBundle\Form\Type\ProcessContextType; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; diff --git a/src/Controller/Admin/Security/LoginController.php b/src/Controller/Admin/Security/LoginController.php index ed49f18..c55b1e0 100644 --- a/src/Controller/Admin/Security/LoginController.php +++ b/src/Controller/Admin/Security/LoginController.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin\Security; +namespace CleverAge\UiProcessBundle\Controller\Admin\Security; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -23,7 +23,7 @@ class LoginController extends AbstractController public function __invoke(): Response { return $this->render( - '@CleverAgeProcessUi/admin/login.html.twig', + '@CleverAgeUiProcess/admin/login.html.twig', [ 'page_title' => 'Login', 'target_path' => '/process', diff --git a/src/Controller/Admin/Security/LogoutController.php b/src/Controller/Admin/Security/LogoutController.php index a49cba1..9ddd963 100644 --- a/src/Controller/Admin/Security/LogoutController.php +++ b/src/Controller/Admin/Security/LogoutController.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin\Security; +namespace CleverAge\UiProcessBundle\Controller\Admin\Security; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\SecurityBundle\Security; diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 45284b3..d084fdd 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller\Admin; +namespace CleverAge\UiProcessBundle\Controller\Admin; -use CleverAge\ProcessUiBundle\Entity\User; +use CleverAge\UiProcessBundle\Entity\User; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php index a321660..e14260c 100644 --- a/src/Controller/ProcessExecuteController.php +++ b/src/Controller/ProcessExecuteController.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Controller; +namespace CleverAge\UiProcessBundle\Controller; -use CleverAge\ProcessUiBundle\Http\Model\HttpProcessExecution; -use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; +use CleverAge\UiProcessBundle\Http\Model\HttpProcessExecution; +use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\Attribute\ValueResolver; diff --git a/src/DependencyInjection/CleverAgeProcessUiExtension.php b/src/DependencyInjection/CleverAgeUiProcessExtension.php similarity index 93% rename from src/DependencyInjection/CleverAgeProcessUiExtension.php rename to src/DependencyInjection/CleverAgeUiProcessExtension.php index d532189..9e7654e 100644 --- a/src/DependencyInjection/CleverAgeProcessUiExtension.php +++ b/src/DependencyInjection/CleverAgeUiProcessExtension.php @@ -11,12 +11,12 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\DependencyInjection; +namespace CleverAge\UiProcessBundle\DependencyInjection; -use CleverAge\ProcessUiBundle\Controller\Admin\ProcessDashboardController; -use CleverAge\ProcessUiBundle\Controller\Admin\UserCrudController; -use CleverAge\ProcessUiBundle\Entity\User; -use CleverAge\ProcessUiBundle\Message\ProcessExecuteMessage; +use CleverAge\UiProcessBundle\Controller\Admin\ProcessDashboardController; +use CleverAge\UiProcessBundle\Controller\Admin\UserCrudController; +use CleverAge\UiProcessBundle\Entity\User; +use CleverAge\UiProcessBundle\Message\ProcessExecuteMessage; use Monolog\Level; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -25,7 +25,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\Finder\Finder; -final class CleverAgeProcessUiExtension extends Extension implements PrependExtensionInterface +final class CleverAgeUiProcessExtension extends Extension implements PrependExtensionInterface { public function load(array $configs, ContainerBuilder $container): void { @@ -106,7 +106,7 @@ public function prepend(ContainerBuilder $container): void $container->loadFromExtension( 'doctrine_migrations', [ - 'migrations_paths' => ['CleverAge\ProcessUiBundle\Migrations' => \dirname(__DIR__).'/Migrations'], + 'migrations_paths' => ['CleverAge\UiProcessBundle\Migrations' => \dirname(__DIR__).'/Migrations'], ] ); $container->loadFromExtension( diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 9b76bf9..dad5eb4 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\DependencyInjection; +namespace CleverAge\UiProcessBundle\DependencyInjection; use Monolog\Level; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; diff --git a/src/Entity/Enum/ProcessExecutionStatus.php b/src/Entity/Enum/ProcessExecutionStatus.php index 5d66457..5589885 100644 --- a/src/Entity/Enum/ProcessExecutionStatus.php +++ b/src/Entity/Enum/ProcessExecutionStatus.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Entity\Enum; +namespace CleverAge\UiProcessBundle\Entity\Enum; enum ProcessExecutionStatus: string { diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php index 3380467..24c4a63 100644 --- a/src/Entity/LogRecord.php +++ b/src/Entity/LogRecord.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Entity; +namespace CleverAge\UiProcessBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\String\UnicodeString; diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 5a5ffe0..dbea4bd 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Entity; +namespace CleverAge\UiProcessBundle\Entity; -use CleverAge\ProcessUiBundle\Entity\Enum\ProcessExecutionStatus; +use CleverAge\UiProcessBundle\Entity\Enum\ProcessExecutionStatus; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\String\UnicodeString; diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 5e1cd1b..24957c0 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -11,12 +11,12 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Entity; +namespace CleverAge\UiProcessBundle\Entity; -use CleverAge\ProcessUiBundle\Repository\ProcessScheduleRepository; -use CleverAge\ProcessUiBundle\Validator\CronExpression; -use CleverAge\ProcessUiBundle\Validator\EveryExpression; -use CleverAge\ProcessUiBundle\Validator\IsValidProcessCode; +use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository; +use CleverAge\UiProcessBundle\Validator\CronExpression; +use CleverAge\UiProcessBundle\Validator\EveryExpression; +use CleverAge\UiProcessBundle\Validator\IsValidProcessCode; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; diff --git a/src/Entity/User.php b/src/Entity/User.php index 88982a7..62d0f20 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Entity; +namespace CleverAge\UiProcessBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; diff --git a/src/EventSubscriber/ProcessEventSubscriber.php b/src/EventSubscriber/ProcessEventSubscriber.php index 539c656..ed90faa 100644 --- a/src/EventSubscriber/ProcessEventSubscriber.php +++ b/src/EventSubscriber/ProcessEventSubscriber.php @@ -11,14 +11,14 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\EventSubscriber; +namespace CleverAge\UiProcessBundle\EventSubscriber; use CleverAge\ProcessBundle\Event\ProcessEvent; -use CleverAge\ProcessUiBundle\Entity\Enum\ProcessExecutionStatus; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; -use CleverAge\ProcessUiBundle\Monolog\Handler\DoctrineProcessHandler; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; +use CleverAge\UiProcessBundle\Entity\Enum\ProcessExecutionStatus; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Manager\ProcessExecutionManager; +use CleverAge\UiProcessBundle\Monolog\Handler\DoctrineProcessHandler; +use CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Uid\Uuid; diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 1cfa6fd..5ca2489 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -11,11 +11,11 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Form\Type; +namespace CleverAge\UiProcessBundle\Form\Type; use CleverAge\ProcessBundle\Configuration\TaskConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; use Symfony\Component\Form\Extension\Core\Type\CollectionType; diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php index 6a7103b..e8e2c2d 100644 --- a/src/Form/Type/ProcessContextType.php +++ b/src/Form/Type/ProcessContextType.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Form\Type; +namespace CleverAge\UiProcessBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/src/Form/Type/ProcessUploadFileType.php b/src/Form/Type/ProcessUploadFileType.php index b22026f..88b77c1 100644 --- a/src/Form/Type/ProcessUploadFileType.php +++ b/src/Form/Type/ProcessUploadFileType.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Form\Type; +namespace CleverAge\UiProcessBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FileType; diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index c671dba..d6fbeea 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Http\Model; +namespace CleverAge\UiProcessBundle\Http\Model; -use CleverAge\ProcessUiBundle\Validator\IsValidProcessCode; +use CleverAge\UiProcessBundle\Validator\IsValidProcessCode; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Sequentially; diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 71f3941..13d5584 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Http\ValueResolver; +namespace CleverAge\UiProcessBundle\Http\ValueResolver; -use CleverAge\ProcessUiBundle\Http\Model\HttpProcessExecution; +use CleverAge\UiProcessBundle\Http\Model\HttpProcessExecution; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; diff --git a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php index 9c99ebc..3290d9b 100644 --- a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php +++ b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Http\ValueResolver; +namespace CleverAge\UiProcessBundle\Http\ValueResolver; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use Symfony\Component\HttpFoundation\Request; diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 74f8393..82dc3db 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Manager; +namespace CleverAge\UiProcessBundle\Manager; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; diff --git a/src/Manager/ProcessExecutionManager.php b/src/Manager/ProcessExecutionManager.php index f342af1..84a6041 100644 --- a/src/Manager/ProcessExecutionManager.php +++ b/src/Manager/ProcessExecutionManager.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Manager; +namespace CleverAge\UiProcessBundle\Manager; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; class ProcessExecutionManager { diff --git a/src/Message/CronProcessMessage.php b/src/Message/CronProcessMessage.php index b5c9d61..8e94c09 100644 --- a/src/Message/CronProcessMessage.php +++ b/src/Message/CronProcessMessage.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Message; +namespace CleverAge\UiProcessBundle\Message; -use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; +use CleverAge\UiProcessBundle\Entity\ProcessSchedule; final readonly class CronProcessMessage { diff --git a/src/Message/CronProcessMessageHandler.php b/src/Message/CronProcessMessageHandler.php index ed55f5a..a517ece 100644 --- a/src/Message/CronProcessMessageHandler.php +++ b/src/Message/CronProcessMessageHandler.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Message; +namespace CleverAge\UiProcessBundle\Message; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; diff --git a/src/Message/ProcessExecuteHandler.php b/src/Message/ProcessExecuteHandler.php index f786378..dec4a05 100644 --- a/src/Message/ProcessExecuteHandler.php +++ b/src/Message/ProcessExecuteHandler.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Message; +namespace CleverAge\UiProcessBundle\Message; use CleverAge\ProcessBundle\Manager\ProcessManager; -use CleverAge\ProcessUiBundle\Monolog\Handler\ProcessHandler; +use CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler; use Symfony\Component\Messenger\Attribute\AsMessageHandler; #[AsMessageHandler] diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php index 5ffdfb3..397f0ae 100644 --- a/src/Message/ProcessExecuteMessage.php +++ b/src/Message/ProcessExecuteMessage.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Message; +namespace CleverAge\UiProcessBundle\Message; readonly class ProcessExecuteMessage { diff --git a/src/Migrations/Version20231006111525.php b/src/Migrations/Version20231006111525.php index 03d4d55..5d8619f 100644 --- a/src/Migrations/Version20231006111525.php +++ b/src/Migrations/Version20231006111525.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Platforms\MariaDBPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; diff --git a/src/Migrations/Version20240729151928.php b/src/Migrations/Version20240729151928.php index dfdc762..d1635b8 100644 --- a/src/Migrations/Version20240729151928.php +++ b/src/Migrations/Version20240729151928.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Platforms\MariaDBPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; diff --git a/src/Migrations/Version20240730090403.php b/src/Migrations/Version20240730090403.php index 2f6ca6e..101395a 100644 --- a/src/Migrations/Version20240730090403.php +++ b/src/Migrations/Version20240730090403.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Migrations/Version20241007134542.php b/src/Migrations/Version20241007134542.php index 403c538..1599e1b 100644 --- a/src/Migrations/Version20241007134542.php +++ b/src/Migrations/Version20241007134542.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Migrations/Version20241007152613.php b/src/Migrations/Version20241007152613.php index 8f989d7..5b8cf45 100644 --- a/src/Migrations/Version20241007152613.php +++ b/src/Migrations/Version20241007152613.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Migrations/Version20241009075733.php b/src/Migrations/Version20241009075733.php index 6a027e2..b66faee 100644 --- a/src/Migrations/Version20241009075733.php +++ b/src/Migrations/Version20241009075733.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Migrations; +namespace CleverAge\UiProcessBundle\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; diff --git a/src/Monolog/Handler/DoctrineProcessHandler.php b/src/Monolog/Handler/DoctrineProcessHandler.php index 1595694..07c4a0a 100644 --- a/src/Monolog/Handler/DoctrineProcessHandler.php +++ b/src/Monolog/Handler/DoctrineProcessHandler.php @@ -11,10 +11,10 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Monolog\Handler; +namespace CleverAge\UiProcessBundle\Monolog\Handler; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Manager\ProcessExecutionManager; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; use Monolog\Handler\AbstractProcessingHandler; @@ -54,7 +54,7 @@ public function flush(): void { foreach ($this->records as $record) { if (($currentProcessExecution = $this->processExecutionManager?->getCurrentProcessExecution()) instanceof ProcessExecution) { - $entity = new \CleverAge\ProcessUiBundle\Entity\LogRecord($record, $currentProcessExecution); + $entity = new \CleverAge\UiProcessBundle\Entity\LogRecord($record, $currentProcessExecution); $this->em?->persist($entity); } } diff --git a/src/Monolog/Handler/ProcessHandler.php b/src/Monolog/Handler/ProcessHandler.php index be51136..6b58789 100644 --- a/src/Monolog/Handler/ProcessHandler.php +++ b/src/Monolog/Handler/ProcessHandler.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Monolog\Handler; +namespace CleverAge\UiProcessBundle\Monolog\Handler; -use CleverAge\ProcessUiBundle\Manager\ProcessExecutionManager; +use CleverAge\UiProcessBundle\Manager\ProcessExecutionManager; use Monolog\Handler\StreamHandler; use Monolog\Level; use Monolog\LogRecord; diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index ef2bc80..6034717 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Repository; +namespace CleverAge\UiProcessBundle\Repository; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; diff --git a/src/Repository/ProcessScheduleRepository.php b/src/Repository/ProcessScheduleRepository.php index 2a40866..c89db93 100644 --- a/src/Repository/ProcessScheduleRepository.php +++ b/src/Repository/ProcessScheduleRepository.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Repository; +namespace CleverAge\UiProcessBundle\Repository; -use CleverAge\ProcessUiBundle\Entity\ProcessSchedule; +use CleverAge\UiProcessBundle\Entity\ProcessSchedule; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index 6f0de44..f1d588b 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -11,11 +11,11 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Scheduler; +namespace CleverAge\UiProcessBundle\Scheduler; -use CleverAge\ProcessUiBundle\Entity\ProcessScheduleType; -use CleverAge\ProcessUiBundle\Message\CronProcessMessage; -use CleverAge\ProcessUiBundle\Repository\ProcessScheduleRepository; +use CleverAge\UiProcessBundle\Entity\ProcessScheduleType; +use CleverAge\UiProcessBundle\Message\CronProcessMessage; +use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository; use Monolog\Attribute\WithMonologChannel; use Psr\Log\LoggerInterface; use Symfony\Component\Scheduler\Attribute\AsSchedule; diff --git a/src/Security/HttpProcessExecutionAuthenticator.php b/src/Security/HttpProcessExecutionAuthenticator.php index 2b28680..85734f9 100644 --- a/src/Security/HttpProcessExecutionAuthenticator.php +++ b/src/Security/HttpProcessExecutionAuthenticator.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Security; +namespace CleverAge\UiProcessBundle\Security; -use CleverAge\ProcessUiBundle\Entity\User; +use CleverAge\UiProcessBundle\Entity\User; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; diff --git a/src/Twig/Extension/LogLevelExtension.php b/src/Twig/Extension/LogLevelExtension.php index 32339dc..b8f9725 100644 --- a/src/Twig/Extension/LogLevelExtension.php +++ b/src/Twig/Extension/LogLevelExtension.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Extension; +namespace CleverAge\UiProcessBundle\Twig\Extension; -use CleverAge\ProcessUiBundle\Twig\Runtime\LogLevelExtensionRuntime; +use CleverAge\UiProcessBundle\Twig\Runtime\LogLevelExtensionRuntime; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; diff --git a/src/Twig/Extension/MD5Extension.php b/src/Twig/Extension/MD5Extension.php index 3538855..aba1918 100644 --- a/src/Twig/Extension/MD5Extension.php +++ b/src/Twig/Extension/MD5Extension.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Extension; +namespace CleverAge\UiProcessBundle\Twig\Extension; -use CleverAge\ProcessUiBundle\Twig\Runtime\MD5ExtensionRuntime; +use CleverAge\UiProcessBundle\Twig\Runtime\MD5ExtensionRuntime; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; diff --git a/src/Twig/Extension/ProcessExecutionExtension.php b/src/Twig/Extension/ProcessExecutionExtension.php index 893c3c9..40bb870 100644 --- a/src/Twig/Extension/ProcessExecutionExtension.php +++ b/src/Twig/Extension/ProcessExecutionExtension.php @@ -11,9 +11,9 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Extension; +namespace CleverAge\UiProcessBundle\Twig\Extension; -use CleverAge\ProcessUiBundle\Twig\Runtime\ProcessExecutionExtensionRuntime; +use CleverAge\UiProcessBundle\Twig\Runtime\ProcessExecutionExtensionRuntime; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; diff --git a/src/Twig/Runtime/LogLevelExtensionRuntime.php b/src/Twig/Runtime/LogLevelExtensionRuntime.php index 8730df6..690ce82 100644 --- a/src/Twig/Runtime/LogLevelExtensionRuntime.php +++ b/src/Twig/Runtime/LogLevelExtensionRuntime.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Runtime; +namespace CleverAge\UiProcessBundle\Twig\Runtime; use Monolog\Level; use Twig\Extension\RuntimeExtensionInterface; diff --git a/src/Twig/Runtime/MD5ExtensionRuntime.php b/src/Twig/Runtime/MD5ExtensionRuntime.php index bd8263e..8ec0da9 100644 --- a/src/Twig/Runtime/MD5ExtensionRuntime.php +++ b/src/Twig/Runtime/MD5ExtensionRuntime.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Runtime; +namespace CleverAge\UiProcessBundle\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index fff7056..592f1e4 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -11,11 +11,11 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Twig\Runtime; +namespace CleverAge\UiProcessBundle\Twig\Runtime; -use CleverAge\ProcessUiBundle\Entity\ProcessExecution; -use CleverAge\ProcessUiBundle\Manager\ProcessConfigurationsManager; -use CleverAge\ProcessUiBundle\Repository\ProcessExecutionRepository; +use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; +use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; use Twig\Extension\RuntimeExtensionInterface; readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface diff --git a/src/Validator/CronExpression.php b/src/Validator/CronExpression.php index 9c5e07e..d7e2866 100644 --- a/src/Validator/CronExpression.php +++ b/src/Validator/CronExpression.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use Symfony\Component\Validator\Constraint; diff --git a/src/Validator/CronExpressionValidator.php b/src/Validator/CronExpressionValidator.php index 78af969..efb866c 100644 --- a/src/Validator/CronExpressionValidator.php +++ b/src/Validator/CronExpressionValidator.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use Symfony\Component\Scheduler\Trigger\CronExpressionTrigger; use Symfony\Component\Validator\Constraint; diff --git a/src/Validator/EveryExpression.php b/src/Validator/EveryExpression.php index 1423628..302fdb5 100644 --- a/src/Validator/EveryExpression.php +++ b/src/Validator/EveryExpression.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use Symfony\Component\Validator\Constraint; diff --git a/src/Validator/EveryExpressionValidator.php b/src/Validator/EveryExpressionValidator.php index 8bbd8b6..dbc4143 100644 --- a/src/Validator/EveryExpressionValidator.php +++ b/src/Validator/EveryExpressionValidator.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; diff --git a/src/Validator/IsValidProcessCode.php b/src/Validator/IsValidProcessCode.php index f33c133..cba6cda 100644 --- a/src/Validator/IsValidProcessCode.php +++ b/src/Validator/IsValidProcessCode.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use Symfony\Component\Validator\Constraint; diff --git a/src/Validator/IsValidProcessCodeValidator.php b/src/Validator/IsValidProcessCodeValidator.php index b47a706..dc100d3 100644 --- a/src/Validator/IsValidProcessCodeValidator.php +++ b/src/Validator/IsValidProcessCodeValidator.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace CleverAge\ProcessUiBundle\Validator; +namespace CleverAge\UiProcessBundle\Validator; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use Symfony\Component\Validator\Constraint; diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 97de49b..ca09098 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -44,7 +44,7 @@ 'process', { crudAction: 'index', - crudControllerFqcn: 'CleverAge\\ProcessUiBundle\\Controller\\Admin\\ProcessExecutionCrudController', + crudControllerFqcn: 'CleverAge\\UiProcessBundle\\Controller\\Admin\\ProcessExecutionCrudController', filters: { code: { comparison: '=', From 8dc901b3689f0ee621a60a6f43ba4f905ea963e1 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 14:57:45 +0100 Subject: [PATCH 077/115] #3 Fix configuration naming to clever_age_ui_process: --- src/DependencyInjection/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index dad5eb4..4dd50a6 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -22,7 +22,7 @@ class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { - $tb = new TreeBuilder('cleverage_ui_process'); + $tb = new TreeBuilder('clever_age_ui_process'); /** @var ArrayNodeDefinition $rootNode */ $rootNode = $tb->getRootNode(); $rootNode From d51aec566ecb028a4b56e557509b69e7be535250 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 15:20:49 +0100 Subject: [PATCH 078/115] Add missing twig.runtime tag on ProcessExecutionExtensionRuntime --- config/services/twig.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/services/twig.yaml b/config/services/twig.yaml index 8a5cd0f..4324ee8 100644 --- a/config/services/twig.yaml +++ b/config/services/twig.yaml @@ -20,6 +20,8 @@ services: cleverage_ui_process.twig.process_execution_extension_runtime: class: CleverAge\UiProcessBundle\Twig\Runtime\ProcessExecutionExtensionRuntime public: false + tags: + - { name: 'twig.runtime' } arguments: - '@cleverage_ui_process.repository.process_execution' - '@cleverage_ui_process.manager.process_configuration' From 66e81e89111b65a382a77964e0dfa5769ee7233f Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 17:44:50 +0100 Subject: [PATCH 079/115] Fix $requestStack configuration on Controller & clean unused dependency on LaunchAction --- config/services/controller.yaml | 2 +- src/Controller/Admin/LogRecordCrudController.php | 2 +- src/Controller/Admin/Process/LaunchAction.php | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 2aae5d8..4d7f18f 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -6,7 +6,7 @@ services: bind: $processConfigurationsManager: '@cleverage_ui_process.manager.process_configuration' $localeSwitcher: '@translation.locale_switcher' - $request: '@request_stack' + $requestStack: '@request_stack' $messageBus: '@messenger.default_bus' $uploadDirectory: '%upload_directory%' $context: '@EasyCorp\Bundle\EasyAdminBundle\Factory\AdminContextFactory' diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 918ee18..2f889ed 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -37,7 +37,7 @@ class LogRecordCrudController extends AbstractCrudController { public function __construct( private readonly ProcessConfigurationsManager $processConfigurationsManager, - private readonly RequestStack $request, + private readonly RequestStack $requestStack, ) { } diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index faa8ee5..ef30674 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -45,7 +45,6 @@ public function __invoke( RequestStack $requestStack, MessageBusInterface $messageBus, string $uploadDirectory, - #[ValueResolver('process')] ProcessConfiguration $processConfiguration, ProcessConfigurationsManager $processConfigurationsManager, AdminContext $context, ): Response { From 8e410f8064168dc12e23ff8822fa4b16e0e1d661 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 17:45:19 +0100 Subject: [PATCH 080/115] Add missing services tags --- config/services/form_type.yaml | 9 +++++++++ config/services/message.yaml | 2 ++ config/services/twig.yaml | 12 ++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 config/services/form_type.yaml diff --git a/config/services/form_type.yaml b/config/services/form_type.yaml new file mode 100644 index 0000000..f47ec48 --- /dev/null +++ b/config/services/form_type.yaml @@ -0,0 +1,9 @@ +services: + cleverage_ui_process.form_type.launch: + class: CleverAge\UiProcessBundle\Form\Type\LaunchType + public: false + arguments: + - '@cleverage_process.registry.process_configuration' + - '@cleverage_ui_process.manager.process_configuration' + tags: + - { name: 'form.type' } diff --git a/config/services/message.yaml b/config/services/message.yaml index 7df35bd..8cb3330 100644 --- a/config/services/message.yaml +++ b/config/services/message.yaml @@ -4,6 +4,7 @@ services: public: false arguments: - '@messenger.default_bus' + tags: [messenger.message_handler] cleverage_ui_process.message.process_execute_handler: class: CleverAge\UiProcessBundle\Message\ProcessExecuteHandler @@ -11,4 +12,5 @@ services: arguments: - '@cleverage_process.manager.process' - '@cleverage_ui_process.monolog_handler.process' + tags: [messenger.message_handler] diff --git a/config/services/twig.yaml b/config/services/twig.yaml index 4324ee8..73ecf30 100644 --- a/config/services/twig.yaml +++ b/config/services/twig.yaml @@ -17,6 +17,18 @@ services: tags: - { name: 'twig.extension' } + cleverage_ui_process.twig.log_level_extension_runtime: + class: CleverAge\UiProcessBundle\Twig\Runtime\LogLevelExtensionRuntime + public: false + tags: + - { name: 'twig.runtime' } + + cleverage_ui_process.twig.md5_extension_runtime: + class: CleverAge\UiProcessBundle\Twig\Runtime\MD5ExtensionRuntime + public: false + tags: + - { name: 'twig.runtime' } + cleverage_ui_process.twig.process_execution_extension_runtime: class: CleverAge\UiProcessBundle\Twig\Runtime\ProcessExecutionExtensionRuntime public: false From 00ac02b88d5435d7aaab72e5e171cb800c3bfa70 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Wed, 20 Nov 2024 17:48:24 +0100 Subject: [PATCH 081/115] Fix previous renaming $request to $requestStack on LogRecordCrudController --- src/Controller/Admin/LogRecordCrudController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 2f889ed..7279dda 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -83,7 +83,7 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { - $id = $this->request->getMainRequest()?->query->all('filters')['process']['value'] ?? null; + $id = $this->requestStack->getMainRequest()?->query->all('filters')['process']['value'] ?? null; $processList = $this->processConfigurationsManager->getPublicProcesses(); $processList = array_map(fn (ProcessConfiguration $cfg) => $cfg->getCode(), $processList); From f5619d3e6e7861737f44d68556d89c022341bcde Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 21 Nov 2024 14:38:47 +0100 Subject: [PATCH 082/115] Fix CronScheduler definition using scheduler.schedule_provider and monolog.logger tags --- config/services/repository.yaml | 2 +- config/services/scheduler.yaml | 3 +++ src/Scheduler/CronScheduler.php | 4 ---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config/services/repository.yaml b/config/services/repository.yaml index a39784c..6e8a5bd 100644 --- a/config/services/repository.yaml +++ b/config/services/repository.yaml @@ -9,5 +9,5 @@ services: class: CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository public: false arguments: - - '@doctrine.orm.entity_manager' + - '@doctrine' diff --git a/config/services/scheduler.yaml b/config/services/scheduler.yaml index 7590703..ec15dd9 100644 --- a/config/services/scheduler.yaml +++ b/config/services/scheduler.yaml @@ -6,3 +6,6 @@ services: - '@cleverage_ui_process.repository.process_schedule' - '@validator' - '@logger' + tags: + - scheduler.schedule_provider: { name: 'cron' } + - { name: 'monolog.logger', channel: 'scheduler' } diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index f1d588b..ad343d3 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -16,16 +16,12 @@ use CleverAge\UiProcessBundle\Entity\ProcessScheduleType; use CleverAge\UiProcessBundle\Message\CronProcessMessage; use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository; -use Monolog\Attribute\WithMonologChannel; use Psr\Log\LoggerInterface; -use Symfony\Component\Scheduler\Attribute\AsSchedule; use Symfony\Component\Scheduler\RecurringMessage; use Symfony\Component\Scheduler\Schedule; use Symfony\Component\Scheduler\ScheduleProviderInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; -#[AsSchedule('cron')] -#[WithMonologChannel('scheduler')] readonly class CronScheduler implements ScheduleProviderInterface { public function __construct( From 242adaf92a5a97947f448735a514d7354b533b29 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 21 Nov 2024 16:07:39 +0100 Subject: [PATCH 083/115] Fix Transformer configuration & add missing aliases on monolog handlers --- config/services/monolog_handler.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/services/monolog_handler.yaml b/config/services/monolog_handler.yaml index 1dc3978..1bd99b8 100644 --- a/config/services/monolog_handler.yaml +++ b/config/services/monolog_handler.yaml @@ -5,6 +5,8 @@ services: calls: - [ setEntityManager, [ '@doctrine.orm.entity_manager' ] ] - [ setProcessExecutionManager, [ '@cleverage_ui_process.manager.process_execution' ] ] + CleverAge\UiProcessBundle\Monolog\Handler\DoctrineProcessHandler: + alias: cleverage_ui_process.monolog_handler.doctrine_process cleverage_ui_process.monolog_handler.process: class: CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler @@ -12,4 +14,5 @@ services: arguments: - '%kernel.logs_dir%' - '@cleverage_ui_process.manager.process_execution' - + CleverAge\UiProcessBundle\Monolog\Handler\ProcessHandler: + alias: cleverage_ui_process.monolog_handler.process From 1f80e86c8951d0080ea156b2ef940510ead122d5 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Thu, 21 Nov 2024 16:40:55 +0100 Subject: [PATCH 084/115] Fix ValueResolver that must use autoconfigure: true to allow AsTargetedValueResolver --- config/services/http_value_resolver.yaml | 2 ++ src/Controller/Admin/Process/LaunchAction.php | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/services/http_value_resolver.yaml b/config/services/http_value_resolver.yaml index 5a18ae2..21b40f2 100644 --- a/config/services/http_value_resolver.yaml +++ b/config/services/http_value_resolver.yaml @@ -1,12 +1,14 @@ services: cleverage_ui_process.http_value_resolver.http_process_execute: class: CleverAge\UiProcessBundle\Http\ValueResolver\HttpProcessExecuteValueResolver + autoconfigure: true public: false arguments: - '%upload_directory%' cleverage_ui_process.http_value_resolver.process_configuration: class: CleverAge\UiProcessBundle\Http\ValueResolver\ProcessConfigurationValueResolver + autoconfigure: true public: false arguments: - '@cleverage_process.registry.process_configuration' diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index ef30674..9c59c6f 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -13,7 +13,6 @@ namespace CleverAge\UiProcessBundle\Controller\Admin\Process; -use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\UiProcessBundle\Entity\User; use CleverAge\UiProcessBundle\Form\Type\LaunchType; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; @@ -26,7 +25,6 @@ use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Attribute\ValueResolver; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; From 19181389686ed9eb6aacc02bc57c9d906f8002c2 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Fri, 22 Nov 2024 12:00:22 +0100 Subject: [PATCH 085/115] #11 Restrict "showLogs" button when log_record exists. Restrict "downloadLogfile" button when log file exists --- CHANGELOG.md | 2 ++ config/services/controller.yaml | 1 + .../Admin/ProcessExecutionCrudController.php | 21 ++++++++++++++++--- src/Repository/ProcessExecutionRepository.php | 13 ++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52cbc66..bb04c2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ v2.0 * [#1](https://github.com/cleverage/ui-process-bundle/issues/1) Add Makefile & .docker for local standalone usage * [#1](https://github.com/cleverage/ui-process-bundle/issues/1) Add rector, phpstan & php-cs-fixer configurations & apply it. Remove phpcs configuration. +* [#11](https://github.com/cleverage/ui-process-bundle/issues/11) Restrict "Download log file" and "Show logs stored in database" buttons visibility + v1.0.6 ------ diff --git a/config/services/controller.yaml b/config/services/controller.yaml index 4d7f18f..4cec79e 100644 --- a/config/services/controller.yaml +++ b/config/services/controller.yaml @@ -11,5 +11,6 @@ services: $uploadDirectory: '%upload_directory%' $context: '@EasyCorp\Bundle\EasyAdminBundle\Factory\AdminContextFactory' $logDirectory: '%kernel.logs_dir%' + $processExecutionRepository: '@cleverage_ui_process.repository.process_execution' tags: - { name: 'controller.service_arguments' } diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index 7033d2b..f0bd2ca 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -15,6 +15,7 @@ use CleverAge\UiProcessBundle\Admin\Field\EnumField; use CleverAge\UiProcessBundle\Entity\ProcessExecution; +use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -33,6 +34,12 @@ #[IsGranted('ROLE_USER')] class ProcessExecutionCrudController extends AbstractCrudController { + public function __construct( + private readonly ProcessExecutionRepository $processExecutionRepository, + private readonly string $logDirectory, + ) { + } + public static function getEntityFqcn(): string { return ProcessExecution::class; @@ -77,6 +84,7 @@ public function configureActions(Actions $actions): Actions ] ) ->linkToCrudAction('showLogs') + ->displayIf(fn (ProcessExecution $entity) => $this->processExecutionRepository->hasLogs($entity)) )->add( Crud::PAGE_INDEX, Action::new('downloadLogfile', false, 'fas fa-download') @@ -88,6 +96,7 @@ public function configureActions(Actions $actions): Actions ] ) ->linkToCrudAction('downloadLogFile') + ->displayIf(fn (ProcessExecution $entity) => file_exists($this->getLogFilePath($entity))) ); } @@ -115,12 +124,10 @@ public function showLogs(AdminContext $adminContext): RedirectResponse public function downloadLogFile( AdminContext $context, - string $logDirectory, ): Response { /** @var ProcessExecution $processExecution */ $processExecution = $context->getEntity()->getInstance(); - $filepath = $logDirectory.\DIRECTORY_SEPARATOR.$processExecution->code.\DIRECTORY_SEPARATOR - .$processExecution->logFilename; + $filepath = $this->getLogFilePath($processExecution); $basename = basename($filepath); $content = file_get_contents($filepath); if (false === $content) { @@ -137,4 +144,12 @@ public function configureFilters(Filters $filters): Filters { return $filters->add('code')->add('startDate'); } + + private function getLogFilePath(ProcessExecution $processExecution): string + { + return $this->logDirectory. + \DIRECTORY_SEPARATOR.$processExecution->code. + \DIRECTORY_SEPARATOR.$processExecution->logFilename + ; + } } diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index 6034717..db0087d 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -13,6 +13,7 @@ namespace CleverAge\UiProcessBundle\Repository; +use CleverAge\UiProcessBundle\Entity\LogRecord; use CleverAge\UiProcessBundle\Entity\ProcessExecution; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; @@ -49,4 +50,16 @@ public function getLastProcessExecution(string $code): ?ProcessExecution ->getQuery() ->getOneOrNullResult(); } + + public function hasLogs(ProcessExecution $processExecution): bool + { + $qb = $this->createQueryBuilder('pe') + ->select('count(lr.id)') + ->join(LogRecord::class, 'lr', 'WITH', 'lr.processExecution = pe') + ->where('pe.id = :id') + ->setParameter('id', $processExecution->getId() + ); + + return (int) $qb->getQuery()->getSingleScalarResult() > 0; + } } From aa3e2f8a8a5a7419c42f8cdf96eb6cbd8accbe8a Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Mon, 9 Dec 2024 16:43:24 +0100 Subject: [PATCH 086/115] Add composer conflict on latest twig due to https://github.com/twigphp/Twig/pull/4475 --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index 0e6ee7a..5b7b9e0 100644 --- a/composer.json +++ b/composer.json @@ -71,6 +71,10 @@ "symfony/web-profiler-bundle": "^6.4|^7.1", "vincentlanglet/twig-cs-fixer": "^3.3" }, + "conflict": { + "symfony/twig-bridge": "7.2.0", + "twig/twig": "v3.15.0|v3.16.0" + }, "config": { "allow-plugins": { "phpstan/extension-installer": true, From 4e659f6353dd2264c48b2a4d5a22c24905103dcf Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 10 Dec 2024 10:42:07 +0100 Subject: [PATCH 087/115] Improve quality on Entities --- .../Admin/ProcessScheduleCrudController.php | 2 +- src/Entity/Enum/ProcessScheduleType.php | 20 +++++++ src/Entity/LogRecord.php | 25 +++++---- src/Entity/ProcessExecution.php | 21 ++++---- src/Entity/ProcessSchedule.php | 12 ++--- src/Entity/User.php | 52 ++++++------------- src/Scheduler/CronScheduler.php | 2 +- 7 files changed, 67 insertions(+), 67 deletions(-) create mode 100644 src/Entity/Enum/ProcessScheduleType.php diff --git a/src/Controller/Admin/ProcessScheduleCrudController.php b/src/Controller/Admin/ProcessScheduleCrudController.php index 035ae2c..df5b2f2 100644 --- a/src/Controller/Admin/ProcessScheduleCrudController.php +++ b/src/Controller/Admin/ProcessScheduleCrudController.php @@ -15,8 +15,8 @@ use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\UiProcessBundle\Admin\Field\EnumField; +use CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType; use CleverAge\UiProcessBundle\Entity\ProcessSchedule; -use CleverAge\UiProcessBundle\Entity\ProcessScheduleType; use CleverAge\UiProcessBundle\Form\Type\ProcessContextType; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; diff --git a/src/Entity/Enum/ProcessScheduleType.php b/src/Entity/Enum/ProcessScheduleType.php new file mode 100644 index 0000000..1c25450 --- /dev/null +++ b/src/Entity/Enum/ProcessScheduleType.php @@ -0,0 +1,20 @@ + */ + /** @var array $context */ + #[ORM\Column(type: Types::JSON)] public readonly array $context; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_IMMUTABLE)] + #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public readonly \DateTimeImmutable $createdAt; public function getId(): ?int @@ -47,10 +48,12 @@ public function getId(): ?int return $this->id; } - public function __construct(\Monolog\LogRecord $record, #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] + public function __construct( + \Monolog\LogRecord $record, + #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE')] - private readonly ProcessExecution $processExecution) - { + private readonly ProcessExecution $processExecution, + ) { $this->channel = (string) (new UnicodeString($record->channel))->truncate(64); $this->level = $record->level->value; $this->message = (string) (new UnicodeString($record->message))->truncate(512); diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index dbea4bd..2c51aa8 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -19,8 +19,8 @@ use Symfony\Component\String\UnicodeString; #[ORM\Entity] -#[ORM\Index(columns: ['code'], name: 'idx_process_execution_code')] -#[ORM\Index(columns: ['start_date'], name: 'idx_process_execution_start_date')] +#[ORM\Index(name: 'idx_process_execution_code', columns: ['code'])] +#[ORM\Index(name: 'idx_process_execution_start_date', columns: ['start_date'])] class ProcessExecution implements \Stringable { #[ORM\Id] @@ -51,14 +51,20 @@ public function getId(): ?int return $this->id; } - public function __construct(string $code, #[ORM\Column(type: Types::STRING, length: 255)] - public readonly string $logFilename, ?array $context = []) - { + public function __construct( + string $code, + #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename, ?array $context = [], + ) { $this->code = (string) (new UnicodeString($code))->truncate(255); $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); $this->context = $context ?? []; } + public function __toString(): string + { + return \sprintf('%s (%s)', $this->id, $this->code); + } + public function setStatus(ProcessExecutionStatus $status): void { $this->status = $status; @@ -69,11 +75,6 @@ public function end(): void $this->endDate = \DateTimeImmutable::createFromMutable(new \DateTime()); } - public function __toString(): string - { - return \sprintf('%s (%s)', $this->id, $this->code); - } - public function addReport(string $key, mixed $value): void { $this->report[$key] = $value; diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 24957c0..5eed3d6 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -13,19 +13,15 @@ namespace CleverAge\UiProcessBundle\Entity; +use CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType; use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository; use CleverAge\UiProcessBundle\Validator\CronExpression; use CleverAge\UiProcessBundle\Validator\EveryExpression; use CleverAge\UiProcessBundle\Validator\IsValidProcessCode; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; -enum ProcessScheduleType: string -{ - case CRON = 'cron'; - case EVERY = 'every'; -} - #[ORM\Entity(repositoryClass: ProcessScheduleRepository::class)] class ProcessSchedule { @@ -49,10 +45,10 @@ class ProcessSchedule )] private ?string $expression = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)] + #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $input = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)] + #[ORM\Column(type: Types::JSON)] private string|array $context = []; public function getId(): ?int diff --git a/src/Entity/User.php b/src/Entity/User.php index 62d0f20..b59be10 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -13,13 +13,14 @@ namespace CleverAge\UiProcessBundle\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; #[ORM\Entity] #[ORM\Table(name: 'process_user')] -#[ORM\Index(columns: ['email'], name: 'idx_process_user_email')] +#[ORM\Index(name: 'idx_process_user_email', columns: ['email'])] class User implements UserInterface, PasswordAuthenticatedUserInterface { #[ORM\Id] @@ -27,28 +28,28 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column] private ?int $id = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, unique: true)] + #[ORM\Column(type: Types::STRING, length: 255, unique: true)] private ?string $email = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $firstname = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $lastname = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)] + #[ORM\Column(type: Types::JSON)] private array $roles = []; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $password = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $timezone = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $locale = null; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)] + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $token = null; public function getId(): ?int @@ -92,14 +93,13 @@ public function setLastname(?string $lastname): self return $this; } - /** - * A visual identifier that represents this user. - * - * @see UserInterface - */ public function getUserIdentifier(): string { - return (string) $this->email; + if (null === $this->email || '' === $this->email || '0' === $this->email) { + throw new \LogicException('The User class must have an email.'); + } + + return $this->email; } public function getUsername(): string @@ -131,16 +131,13 @@ public function setLocale(?string $locale): self return $this; } - /** - * @see UserInterface - */ public function getRoles(): array { return array_merge(['ROLE_USER'], $this->roles); } /** - * @param array $roles + * @param array $roles */ public function setRoles(array $roles): self { @@ -149,9 +146,6 @@ public function setRoles(array $roles): self return $this; } - /** - * @see PasswordAuthenticatedUserInterface - */ public function getPassword(): ?string { return $this->password; @@ -176,20 +170,6 @@ public function setToken(?string $token): self return $this; } - /** - * Returning a salt is only needed, if you are not using a modern - * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml. - * - * @see UserInterface - */ - public function getSalt(): ?string - { - return null; - } - - /** - * @see UserInterface - */ public function eraseCredentials(): void { // If you store any temporary, sensitive data on the user, clear it here diff --git a/src/Scheduler/CronScheduler.php b/src/Scheduler/CronScheduler.php index ad343d3..b12fd20 100644 --- a/src/Scheduler/CronScheduler.php +++ b/src/Scheduler/CronScheduler.php @@ -13,7 +13,7 @@ namespace CleverAge\UiProcessBundle\Scheduler; -use CleverAge\UiProcessBundle\Entity\ProcessScheduleType; +use CleverAge\UiProcessBundle\Entity\Enum\ProcessScheduleType; use CleverAge\UiProcessBundle\Message\CronProcessMessage; use CleverAge\UiProcessBundle\Repository\ProcessScheduleRepository; use Psr\Log\LoggerInterface; From 0943b8aa96b7e147cf2d9ebbb753b3aa51477f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 12 Dec 2024 16:06:16 +0100 Subject: [PATCH 088/115] #14 Quality fix --- phpstan.neon | 7 +++++-- src/Entity/LogRecord.php | 2 +- src/Repository/ProcessExecutionRepository.php | 4 ++-- src/Repository/ProcessScheduleRepository.php | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 8f1e7db..fbfff5e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 8 + level: 6 paths: - src - tests @@ -14,7 +14,10 @@ parameters: - '#process\(\) has no return type specified#' - '#should return Iterator but returns Traversable#' - '#Negated boolean expression is always false#' - checkGenericClassInNonGenericObjectType: false + - + identifier: missingType.generics + - + identifier: doctrine.columnType reportUnmatchedIgnoredErrors: false inferPrivatePropertyTypeFromConstructor: true treatPhpDocTypesAsCertain: false diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php index b17e179..e6168ba 100644 --- a/src/Entity/LogRecord.php +++ b/src/Entity/LogRecord.php @@ -51,7 +51,7 @@ public function getId(): ?int public function __construct( \Monolog\LogRecord $record, #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] - #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE',nullable: false)] private readonly ProcessExecution $processExecution, ) { $this->channel = (string) (new UnicodeString($record->channel))->truncate(64); diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index db0087d..e5d09e0 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -22,9 +22,9 @@ * @extends EntityRepository * * @method ProcessExecution|null find($id, $lockMode = null, $lockVersion = null) - * @method ProcessExecution|null findOneBy(array $criteria, array $orderBy = null) + * @method ProcessExecution|null findOneBy(mixed[] $criteria, string[] $orderBy = null) * @method ProcessExecution[] findAll() - * @method ProcessExecution[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + * @method ProcessExecution[] findBy(mixed[] $criteria, string[] $orderBy = null, $limit = null, $offset = null) */ class ProcessExecutionRepository extends EntityRepository { diff --git a/src/Repository/ProcessScheduleRepository.php b/src/Repository/ProcessScheduleRepository.php index c89db93..6c8e3ea 100644 --- a/src/Repository/ProcessScheduleRepository.php +++ b/src/Repository/ProcessScheduleRepository.php @@ -21,9 +21,9 @@ * @extends ServiceEntityRepository * * @method ProcessSchedule|null find($id, $lockMode = null, $lockVersion = null) - * @method ProcessSchedule|null findOneBy(array $criteria, array $orderBy = null) + * @method ProcessSchedule|null findOneBy(mixed[] $criteria, string[] $orderBy = null) * @method ProcessSchedule[] findAll() - * @method ProcessSchedule[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + * @method ProcessSchedule[] findBy(mixed[] $criteria, string[] $orderBy = null, $limit = null, $offset = null) */ class ProcessScheduleRepository extends ServiceEntityRepository { From 92aa63cb3ba9790fccfe59f1c54683cd1f7427be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 12 Dec 2024 16:37:26 +0100 Subject: [PATCH 089/115] #14 Quality fix for LogRecord entity --- src/Entity/LogRecord.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php index e6168ba..2a9c25f 100644 --- a/src/Entity/LogRecord.php +++ b/src/Entity/LogRecord.php @@ -51,7 +51,7 @@ public function getId(): ?int public function __construct( \Monolog\LogRecord $record, #[ORM\ManyToOne(targetEntity: ProcessExecution::class, cascade: ['all'])] - #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE',nullable: false)] + #[ORM\JoinColumn(name: 'process_execution_id', referencedColumnName: 'id', onDelete: 'CASCADE', nullable: false)] private readonly ProcessExecution $processExecution, ) { $this->channel = (string) (new UnicodeString($record->channel))->truncate(64); From e8a4c26d4b9c1f97b638078b1e3032de239ea3b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 12 Dec 2024 15:17:19 +0100 Subject: [PATCH 090/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. --- config/services/twig.yaml | 20 +++++++++ src/Controller/Admin/Process/LaunchAction.php | 45 ++++++++++++++----- src/Manager/ProcessConfigurationsManager.php | 4 ++ src/Twig/Components/BootstrapModal.php | 20 +++++++++ src/Twig/Extension/ProcessExtension.php | 31 +++++++++++++ src/Twig/Runtime/ProcessExtensionRuntime.php | 27 +++++++++++ templates/admin/process/list.html.twig | 19 ++++++-- templates/components/BootstrapModal.html.twig | 37 +++++++++++++++ 8 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 src/Twig/Components/BootstrapModal.php create mode 100644 src/Twig/Extension/ProcessExtension.php create mode 100644 src/Twig/Runtime/ProcessExtensionRuntime.php create mode 100644 templates/components/BootstrapModal.html.twig diff --git a/config/services/twig.yaml b/config/services/twig.yaml index 73ecf30..4f54954 100644 --- a/config/services/twig.yaml +++ b/config/services/twig.yaml @@ -17,6 +17,12 @@ services: tags: - { name: 'twig.extension' } + cleverage_ui_process.twig.process_extension: + class: CleverAge\UiProcessBundle\Twig\Extension\ProcessExtension + public: false + tags: + - { name: 'twig.extension' } + cleverage_ui_process.twig.log_level_extension_runtime: class: CleverAge\UiProcessBundle\Twig\Runtime\LogLevelExtensionRuntime public: false @@ -37,3 +43,17 @@ services: arguments: - '@cleverage_ui_process.repository.process_execution' - '@cleverage_ui_process.manager.process_configuration' + + cleverage_ui_process.twig.process_extension_runtime: + class: CleverAge\UiProcessBundle\Twig\Runtime\ProcessExtensionRuntime + public: false + tags: + - { name: 'twig.runtime' } + arguments: + - '@cleverage_ui_process.manager.process_configuration' + + cleverage_ui_process.twig.component.bootstrap_modal: + class: CleverAge\UiProcessBundle\Twig\Components\BootstrapModal + shared: false + tags: + - { name: 'twig.component', key: 'ui:BootstrapModal', template: '@CleverAgeUiProcess/components/BootstrapModal.html.twig' } \ No newline at end of file diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 9c59c6f..149f92c 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -13,6 +13,7 @@ namespace CleverAge\UiProcessBundle\Controller\Admin\Process; +use CleverAge\ProcessBundle\Exception\MissingProcessException; use CleverAge\UiProcessBundle\Entity\User; use CleverAge\UiProcessBundle\Form\Type\LaunchType; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; @@ -39,20 +40,36 @@ #[IsGranted('ROLE_USER')] class LaunchAction extends AbstractController { + public function __construct(private readonly MessageBusInterface $messageBus) + { + } + public function __invoke( RequestStack $requestStack, - MessageBusInterface $messageBus, string $uploadDirectory, ProcessConfigurationsManager $processConfigurationsManager, AdminContext $context, ): Response { - $uiOptions = $processConfigurationsManager->getUiOptions($requestStack->getMainRequest()?->get('process') ?? ''); + $processCode = $requestStack->getMainRequest()?->get('process'); + if (null === $processCode) { + throw new MissingProcessException(); + } + $uiOptions = $processConfigurationsManager->getUiOptions($processCode); + if (false === $uiOptions['input_context_launcher_form']) { + $this->dispatch($processCode); + $this->addFlash( + 'success', + 'Process has been added to queue. It will start as soon as possible' + ); + + return $this->redirectToRoute('process', ['routeName' => 'process_list']); + } $form = $this->createForm( LaunchType::class, null, [ 'constraints' => $uiOptions['constraints'] ?? [], - 'process_code' => $requestStack->getMainRequest()?->get('process'), + 'process_code' => $processCode, ] ); if (false === $form->isSubmitted()) { @@ -72,16 +89,11 @@ public function __invoke( (new Filesystem())->dumpFile($filename, $input->getContent()); $input = $filename; } - - $message = new ProcessExecuteMessage( + $this->dispatch( $form->getConfig()->getOption('process_code'), $input, - array_merge( - ['execution_user' => $this->getUser()?->getEmail()], - $form->get('context')->getData() - ) + $form->get('context')->getData() ); - $messageBus->dispatch($message); $this->addFlash( 'success', 'Process has been added to queue. It will start as soon as possible' @@ -99,6 +111,19 @@ public function __invoke( ); } + protected function dispatch(string $processCode, mixed $input = null, array $context = []): void + { + $message = new ProcessExecuteMessage( + $processCode, + $input, + array_merge( + ['execution_user' => $this->getUser()?->getEmail()], + $context + ) + ); + $this->messageBus->dispatch($message); + } + protected function getUser(): ?User { /** @var User $user */ diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 82dc3db..0347f1a 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -57,6 +57,8 @@ private function resolveUiOptions(array $options): array 'source' => null, 'target' => null, 'entrypoint_type' => 'text', + 'input_context_launcher_form' => false, + 'run_confirmation_modal' => false, 'constraints' => [], 'run' => null, 'default' => function (OptionsResolver $defaultResolver) { @@ -76,6 +78,8 @@ private function resolveUiOptions(array $options): array ); $uiResolver->setAllowedValues('entrypoint_type', ['text', 'file']); $uiResolver->setNormalizer('constraints', fn (Options $options, array $values): array => (new ConstraintLoader())->buildConstraints($values)); + $uiResolver->setAllowedTypes('input_context_launcher_form', ['bool']); + $uiResolver->setAllowedTypes('run_confirmation_modal', ['bool']); }); return $resolver->resolve($options); diff --git a/src/Twig/Components/BootstrapModal.php b/src/Twig/Components/BootstrapModal.php new file mode 100644 index 0000000..1e8c362 --- /dev/null +++ b/src/Twig/Components/BootstrapModal.php @@ -0,0 +1,20 @@ +processConfigurationsManager->getUiOptions($code) ?? []; + } +} diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index ca09098..417567b 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -21,6 +21,7 @@ {# @var process \CleverAge\ProcessBundle\Configuration\ProcessConfiguration #} {% for process in processes %} {% set lastExecution = get_last_execution_date(process.code) %} + {% set uiOptions = resolve_ui_options(process.code) %} {% set statusClass = '' %} {% if lastExecution is not null %} {% set statusClass = lastExecution.status.value == 'failed' ? 'danger' : 'success' %} @@ -32,9 +33,15 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - - - + {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} + + + + {% else %} + + + + {% endif %} + {% endfor %} {% endblock %} diff --git a/templates/components/BootstrapModal.html.twig b/templates/components/BootstrapModal.html.twig new file mode 100644 index 0000000..c7976d0 --- /dev/null +++ b/templates/components/BootstrapModal.html.twig @@ -0,0 +1,37 @@ + \ No newline at end of file From 09174924f81cf80ebca5d410e047364362b55cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:01:52 +0100 Subject: [PATCH 091/115] #14 Quality. Phpstan remove - '#type has no value type specified in iterable type#' - '#has parameter .* with no value type specified in iterable type#' - '#has no value type specified in iterable type array#' - '#configureOptions\(\) has no return type specified.#' - '#configure\(\) has no return type specified#' - '#process\(\) has no return type specified#' - '#should return Iterator but returns Traversable#' - '#Negated boolean expression is always false#' --- phpstan.neon | 8 -------- src/Admin/Filter/LogProcessFilter.php | 3 +++ src/Entity/ProcessExecution.php | 18 ++++++++++++++++- src/Entity/ProcessSchedule.php | 9 +++++++++ src/Entity/User.php | 3 +++ src/Http/Model/HttpProcessExecution.php | 3 +++ .../HttpProcessExecuteValueResolver.php | 3 +++ .../ProcessConfigurationValueResolver.php | 4 ++++ src/Manager/ProcessConfigurationsManager.php | 20 +++++++++++++++++++ src/Message/ProcessExecuteMessage.php | 3 +++ 10 files changed, 65 insertions(+), 9 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index fbfff5e..8b167d3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,14 +6,6 @@ parameters: excludePaths: - src/DependencyInjection/Configuration.php ignoreErrors: - - '#type has no value type specified in iterable type#' - - '#has parameter .* with no value type specified in iterable type#' - - '#has no value type specified in iterable type array#' - - '#configureOptions\(\) has no return type specified.#' - - '#configure\(\) has no return type specified#' - - '#process\(\) has no return type specified#' - - '#should return Iterator but returns Traversable#' - - '#Negated boolean expression is always false#' - identifier: missingType.generics - diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php index c11c74e..15aac0e 100644 --- a/src/Admin/Filter/LogProcessFilter.php +++ b/src/Admin/Filter/LogProcessFilter.php @@ -26,6 +26,9 @@ class LogProcessFilter implements FilterInterface { use FilterTrait; + /** + * @param string[] $choices + */ public static function new( mixed $label, array $choices, diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 2c51aa8..a924eda 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -40,9 +40,15 @@ class ProcessExecution implements \Stringable #[ORM\Column(type: Types::STRING, enumType: ProcessExecutionStatus::class)] public ProcessExecutionStatus $status = ProcessExecutionStatus::Started; + /** + * @var array + */ #[ORM\Column(type: Types::JSON)] private array $report = []; + /** + * @var array + */ #[ORM\Column(type: Types::JSON, nullable: true)] private ?array $context = []; @@ -51,9 +57,13 @@ public function getId(): ?int return $this->id; } + /** + * @param array $context + */ public function __construct( string $code, - #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename, ?array $context = [], + #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename, + ?array $context = [], ) { $this->code = (string) (new UnicodeString($code))->truncate(255); $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); @@ -104,11 +114,17 @@ public function getCode(): string return $this->code; } + /** + * @return array + */ public function getContext(): ?array { return $this->context; } + /** + * @param array $context + */ public function setContext(array $context): void { $this->context = $context; diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 5eed3d6..0637a4a 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -48,6 +48,9 @@ class ProcessSchedule #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $input = null; + /** + * @var string|array + */ #[ORM\Column(type: Types::JSON)] private string|array $context = []; @@ -68,11 +71,17 @@ public function setProcess(string $process): static return $this; } + /** + * @return array + */ public function getContext(): array { return \is_array($this->context) ? $this->context : json_decode($this->context); } + /** + * @param array $context + */ public function setContext(array $context): void { $this->context = $context; diff --git a/src/Entity/User.php b/src/Entity/User.php index b59be10..a5f680c 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -37,6 +37,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $lastname = null; + /** + * @var string[] + */ #[ORM\Column(type: Types::JSON)] private array $roles = []; diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index d6fbeea..fc4272f 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -19,6 +19,9 @@ final readonly class HttpProcessExecution { + /** + * @param array $context + */ public function __construct( #[Sequentially(constraints: [new NotNull(message: 'Process code is required.'), new IsValidProcessCode()])] public ?string $code = null, diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 13d5584..5e2aafe 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -28,6 +28,9 @@ public function __construct(private string $storageDir) { } + /** + * @return iterable + */ public function resolve(Request $request, ArgumentMetadata $argument): iterable { $input = $request->get('input', $request->files->get('input')); diff --git a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php index 3290d9b..bf88b84 100644 --- a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php +++ b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php @@ -13,6 +13,7 @@ namespace CleverAge\UiProcessBundle\Http\ValueResolver; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsTargetedValueResolver; @@ -26,6 +27,9 @@ public function __construct(private ProcessConfigurationRegistry $registry) { } + /** + * @return iterable + */ public function resolve(Request $request, ArgumentMetadata $argument): iterable { return [$this->registry->getProcessConfiguration($request->get('process'))]; diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 82dc3db..d057468 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -18,7 +18,19 @@ use CleverAge\ProcessBundle\Validator\ConstraintLoader; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraint; +/** + * @template UiOptions of array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * @template UiOptionList of array {'ui': UiOptions} + */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -37,6 +49,9 @@ public function getPrivateProcesses(): array return array_filter($this->getConfigurations(), fn (ProcessConfiguration $cfg) => !$cfg->isPublic()); } + /** + * @return null|UiOptions + */ public function getUiOptions(string $processCode): ?array { if (false === $this->registry->hasProcessConfiguration($processCode)) { @@ -48,6 +63,11 @@ public function getUiOptions(string $processCode): ?array return $this->resolveUiOptions($configuration->getOptions())['ui']; } + /** + * @param array $options + * + * @return UiOptionList + */ private function resolveUiOptions(array $options): array { $resolver = new OptionsResolver(); diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php index 397f0ae..84fddb0 100644 --- a/src/Message/ProcessExecuteMessage.php +++ b/src/Message/ProcessExecuteMessage.php @@ -15,6 +15,9 @@ readonly class ProcessExecuteMessage { + /** + * @param mixed[] $context + */ public function __construct(public string $code, public mixed $input, public array $context = []) { } From dffccf24552183e3a22fd89b0b252a2356de5798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:38:13 +0100 Subject: [PATCH 092/115] #14 Quality. Phpstan remove missingType.generics --- phpstan.neon | 2 -- src/Form/Type/LaunchType.php | 1 + src/Form/Type/ProcessContextType.php | 1 + src/Form/Type/ProcessUploadFileType.php | 1 + src/Manager/ProcessConfigurationsManager.php | 31 +++++++++++-------- .../ProcessExecutionExtensionRuntime.php | 1 + 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 8b167d3..030748e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,8 +6,6 @@ parameters: excludePaths: - src/DependencyInjection/Configuration.php ignoreErrors: - - - identifier: missingType.generics - identifier: doctrine.columnType reportUnmatchedIgnoredErrors: false diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 5ca2489..9c2f964 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -25,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** @template-extends AbstractType> */ class LaunchType extends AbstractType { public function __construct( diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php index e8e2c2d..d95fd19 100644 --- a/src/Form/Type/ProcessContextType.php +++ b/src/Form/Type/ProcessContextType.php @@ -18,6 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\NotBlank; +/** @template-extends AbstractType */ class ProcessContextType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Type/ProcessUploadFileType.php b/src/Form/Type/ProcessUploadFileType.php index 88b77c1..57619ff 100644 --- a/src/Form/Type/ProcessUploadFileType.php +++ b/src/Form/Type/ProcessUploadFileType.php @@ -17,6 +17,7 @@ use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\OptionsResolver\OptionsResolver; +/** @template-extends AbstractType */ class ProcessUploadFileType extends AbstractType { public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index d057468..d3d9bd8 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -20,17 +20,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraint; -/** - * @template UiOptions of array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': 'text|file', - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * @template UiOptionList of array {'ui': UiOptions} - */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -50,7 +39,14 @@ public function getPrivateProcesses(): array } /** - * @return null|UiOptions + * @return null|array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } */ public function getUiOptions(string $processCode): ?array { @@ -66,7 +62,16 @@ public function getUiOptions(string $processCode): ?array /** * @param array $options * - * @return UiOptionList + * @return array{ + * 'ui': array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * } */ private function resolveUiOptions(array $options): array { diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 592f1e4..60f8630 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -16,6 +16,7 @@ use CleverAge\UiProcessBundle\Entity\ProcessExecution; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; +use Symfony\Component\Form\AbstractType; use Twig\Extension\RuntimeExtensionInterface; readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface From 92dd52b501970fb3bbdb53c112b1fae15a718391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:40:50 +0100 Subject: [PATCH 093/115] #14 Quality. Phpstan 7 --- phpstan.neon | 2 +- src/Manager/ProcessConfigurationsManager.php | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 030748e..9f60d1c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 6 + level: 7 paths: - src - tests diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index d3d9bd8..8c260f6 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -102,8 +102,21 @@ private function resolveUiOptions(array $options): array $uiResolver->setAllowedValues('entrypoint_type', ['text', 'file']); $uiResolver->setNormalizer('constraints', fn (Options $options, array $values): array => (new ConstraintLoader())->buildConstraints($values)); }); + /** + * @var array{ + * 'ui': array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * } $options + */ + $options = $resolver->resolve($options); - return $resolver->resolve($options); + return $options; } /** @return ProcessConfiguration[] */ From 0d0e7cf503fc3c3e082be0fd9b3ca49a1469b050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 14:32:47 +0100 Subject: [PATCH 094/115] #14 Quality. Phpstan 8 --- phpstan.neon | 10 +--------- src/Entity/ProcessSchedule.php | 6 +++--- src/Entity/User.php | 4 ++-- src/Form/Type/LaunchType.php | 16 +++++++++------- src/Manager/ProcessConfigurationsManager.php | 4 ++-- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 9f60d1c..1cd333b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,13 +1,5 @@ parameters: - level: 7 + level: 8 paths: - src - tests - excludePaths: - - src/DependencyInjection/Configuration.php - ignoreErrors: - - - identifier: doctrine.columnType - reportUnmatchedIgnoredErrors: false - inferPrivatePropertyTypeFromConstructor: true - treatPhpDocTypesAsCertain: false diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 0637a4a..4ffa00a 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -32,7 +32,7 @@ class ProcessSchedule #[ORM\Column(length: 255)] #[IsValidProcessCode] - private ?string $process = null; + private string $process; #[ORM\Column(length: 6)] private ProcessScheduleType $type; @@ -43,7 +43,7 @@ class ProcessSchedule #[Assert\When( expression: 'this.getType().value == "every"', constraints: [new EveryExpression()] )] - private ?string $expression = null; + private string $expression; #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $input = null; @@ -109,7 +109,7 @@ public function getExpression(): ?string return $this->expression; } - public function setExpression(?string $expression): self + public function setExpression(string $expression): self { $this->expression = $expression; diff --git a/src/Entity/User.php b/src/Entity/User.php index a5f680c..11532f7 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -29,7 +29,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface private ?int $id = null; #[ORM\Column(type: Types::STRING, length: 255, unique: true)] - private ?string $email = null; + private string $email; #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $firstname = null; @@ -98,7 +98,7 @@ public function setLastname(?string $lastname): self public function getUserIdentifier(): string { - if (null === $this->email || '' === $this->email || '0' === $this->email) { + if ('' === $this->email) { throw new \LogicException('The User class must have an email.'); } diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 9c2f964..3c876bc 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -39,13 +39,15 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $code = $options['process_code']; $configuration = $this->registry->getProcessConfiguration($code); $uiOptions = $this->configurationsManager->getUiOptions($code); - $builder->add( - 'input', - 'file' === ($uiOptions['entrypoint_type'] ?? null) ? FileType::class : TextType::class, - [ - 'required' => $configuration->getEntryPoint() instanceof TaskConfiguration, - ] - ); + if (isset($uiOptions['entrypoint_type'])) { + $builder->add( + 'input', + 'file' === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, + [ + 'required' => $configuration->getEntryPoint() instanceof TaskConfiguration, + ] + ); + } $builder->add( 'context', CollectionType::class, diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 8c260f6..f3cc54c 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -42,7 +42,7 @@ public function getPrivateProcesses(): array * @return null|array{ * 'source': ?string, * 'target': ?string, - * 'entrypoint_type': 'text|file', + * 'entrypoint_type': string, * 'constraints': Constraint[], * 'run': 'null|bool', * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} @@ -66,7 +66,7 @@ public function getUiOptions(string $processCode): ?array * 'ui': array{ * 'source': ?string, * 'target': ?string, - * 'entrypoint_type': 'text|file', + * 'entrypoint_type': string, * 'constraints': Constraint[], * 'run': 'null|bool', * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} From 5d29fef34d1494d65d1e93d8edd00c32ad4c6e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 14:55:29 +0100 Subject: [PATCH 095/115] #14 Quality. PhpCs --- src/Entity/ProcessSchedule.php | 2 +- src/Twig/Runtime/ProcessExecutionExtensionRuntime.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 4ffa00a..8eea928 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -80,7 +80,7 @@ public function getContext(): array } /** - * @param array $context + * @param array $context */ public function setContext(array $context): void { diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 60f8630..592f1e4 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -16,7 +16,6 @@ use CleverAge\UiProcessBundle\Entity\ProcessExecution; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; -use Symfony\Component\Form\AbstractType; use Twig\Extension\RuntimeExtensionInterface; readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface From 06b69a7c8b046aa51b68ab69afb498b4c7b30f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 14:18:42 +0100 Subject: [PATCH 096/115] #14 Quality. Phpstan use phpstan type to prevent duplicate definitions. --- src/Manager/ProcessConfigurationsManager.php | 41 +++++++------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index f3cc54c..4c4106d 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -20,6 +20,16 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraint; +/** + * @phpstan-type UiOptions array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': string, + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -39,14 +49,7 @@ public function getPrivateProcesses(): array } /** - * @return null|array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': string, - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } + * @return null|UiOptions */ public function getUiOptions(string $processCode): ?array { @@ -62,16 +65,7 @@ public function getUiOptions(string $processCode): ?array /** * @param array $options * - * @return array{ - * 'ui': array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': string, - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * } + * @return array{'ui': UiOptions} */ private function resolveUiOptions(array $options): array { @@ -103,16 +97,7 @@ private function resolveUiOptions(array $options): array $uiResolver->setNormalizer('constraints', fn (Options $options, array $values): array => (new ConstraintLoader())->buildConstraints($values)); }); /** - * @var array{ - * 'ui': array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': 'text|file', - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * } $options + * @var array{'ui': UiOptions} $options */ $options = $resolver->resolve($options); From f4bdfbbc309f065ab518f53d834fadfe7b5ba00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 14:21:44 +0100 Subject: [PATCH 097/115] #14 Quality. Phpstan use phpstan type to prevent duplicate definitions. --- src/Manager/ProcessConfigurationsManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 4c4106d..2db160e 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -49,7 +49,7 @@ public function getPrivateProcesses(): array } /** - * @return null|UiOptions + * @return UiOptions|null */ public function getUiOptions(string $processCode): ?array { From 85f31454b0b9896022f75a441705c47b9e860b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 14:46:16 +0100 Subject: [PATCH 098/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Update doc --- docs/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/index.md b/docs/index.md index 0966b94..e6d3950 100644 --- a/docs/index.md +++ b/docs/index.md @@ -33,6 +33,16 @@ Now you can access UI Process via http://your-domain.com/process ## Features +### Launch process via UI +From UI "Process List" menu entry you can run a process by clicking on "Rocket" action. +You can manage this behaviour by setting some ui options on process configuration ui option. + +| Options | Values | UI behaviour | +|----------------------------------|----------------|:---------:| +| input_context_launcher_form
    run_confirmation_modal | false
    false | Run process without any confirmation +| input_context_launcher_form
    run_confirmation_modal | true
    false | On click, open a form to set input and context execution +| input_context_launcher_form
    run_confirmation_modal | false
    true | On click, open confirmation model to confirm process execution + ### Launch process via http request You can launch a process via http post request First you need to generate a token via UI User edit form. The UiProcess generate for you a auth token (keep it in secured area, it will display once). From c9df4005b9414d15e6963fad4407450ac9dbb36a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 15:02:55 +0100 Subject: [PATCH 099/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Twig cs fixer --- templates/admin/process/list.html.twig | 2 +- templates/components/BootstrapModal.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 417567b..e655794 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} + {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} diff --git a/templates/components/BootstrapModal.html.twig b/templates/components/BootstrapModal.html.twig index c7976d0..9c226de 100644 --- a/templates/components/BootstrapModal.html.twig +++ b/templates/components/BootstrapModal.html.twig @@ -34,4 +34,4 @@ {% endblock %} - \ No newline at end of file + From 1ee039bd429252b2a4ea1e9d3c91cbae9c5bc62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:01:52 +0100 Subject: [PATCH 100/115] #14 Quality. Phpstan remove - '#type has no value type specified in iterable type#' - '#has parameter .* with no value type specified in iterable type#' - '#has no value type specified in iterable type array#' - '#configureOptions\(\) has no return type specified.#' - '#configure\(\) has no return type specified#' - '#process\(\) has no return type specified#' - '#should return Iterator but returns Traversable#' - '#Negated boolean expression is always false#' --- phpstan.neon | 8 -------- src/Admin/Filter/LogProcessFilter.php | 3 +++ src/Entity/ProcessExecution.php | 18 ++++++++++++++++- src/Entity/ProcessSchedule.php | 9 +++++++++ src/Entity/User.php | 3 +++ src/Http/Model/HttpProcessExecution.php | 3 +++ .../HttpProcessExecuteValueResolver.php | 3 +++ .../ProcessConfigurationValueResolver.php | 4 ++++ src/Manager/ProcessConfigurationsManager.php | 20 +++++++++++++++++++ src/Message/ProcessExecuteMessage.php | 3 +++ 10 files changed, 65 insertions(+), 9 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index fbfff5e..8b167d3 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,14 +6,6 @@ parameters: excludePaths: - src/DependencyInjection/Configuration.php ignoreErrors: - - '#type has no value type specified in iterable type#' - - '#has parameter .* with no value type specified in iterable type#' - - '#has no value type specified in iterable type array#' - - '#configureOptions\(\) has no return type specified.#' - - '#configure\(\) has no return type specified#' - - '#process\(\) has no return type specified#' - - '#should return Iterator but returns Traversable#' - - '#Negated boolean expression is always false#' - identifier: missingType.generics - diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php index c11c74e..15aac0e 100644 --- a/src/Admin/Filter/LogProcessFilter.php +++ b/src/Admin/Filter/LogProcessFilter.php @@ -26,6 +26,9 @@ class LogProcessFilter implements FilterInterface { use FilterTrait; + /** + * @param string[] $choices + */ public static function new( mixed $label, array $choices, diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index 2c51aa8..a924eda 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -40,9 +40,15 @@ class ProcessExecution implements \Stringable #[ORM\Column(type: Types::STRING, enumType: ProcessExecutionStatus::class)] public ProcessExecutionStatus $status = ProcessExecutionStatus::Started; + /** + * @var array + */ #[ORM\Column(type: Types::JSON)] private array $report = []; + /** + * @var array + */ #[ORM\Column(type: Types::JSON, nullable: true)] private ?array $context = []; @@ -51,9 +57,13 @@ public function getId(): ?int return $this->id; } + /** + * @param array $context + */ public function __construct( string $code, - #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename, ?array $context = [], + #[ORM\Column(type: Types::STRING, length: 255)] public readonly string $logFilename, + ?array $context = [], ) { $this->code = (string) (new UnicodeString($code))->truncate(255); $this->startDate = \DateTimeImmutable::createFromMutable(new \DateTime()); @@ -104,11 +114,17 @@ public function getCode(): string return $this->code; } + /** + * @return array + */ public function getContext(): ?array { return $this->context; } + /** + * @param array $context + */ public function setContext(array $context): void { $this->context = $context; diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 5eed3d6..0637a4a 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -48,6 +48,9 @@ class ProcessSchedule #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $input = null; + /** + * @var string|array + */ #[ORM\Column(type: Types::JSON)] private string|array $context = []; @@ -68,11 +71,17 @@ public function setProcess(string $process): static return $this; } + /** + * @return array + */ public function getContext(): array { return \is_array($this->context) ? $this->context : json_decode($this->context); } + /** + * @param array $context + */ public function setContext(array $context): void { $this->context = $context; diff --git a/src/Entity/User.php b/src/Entity/User.php index b59be10..a5f680c 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -37,6 +37,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $lastname = null; + /** + * @var string[] + */ #[ORM\Column(type: Types::JSON)] private array $roles = []; diff --git a/src/Http/Model/HttpProcessExecution.php b/src/Http/Model/HttpProcessExecution.php index d6fbeea..fc4272f 100644 --- a/src/Http/Model/HttpProcessExecution.php +++ b/src/Http/Model/HttpProcessExecution.php @@ -19,6 +19,9 @@ final readonly class HttpProcessExecution { + /** + * @param array $context + */ public function __construct( #[Sequentially(constraints: [new NotNull(message: 'Process code is required.'), new IsValidProcessCode()])] public ?string $code = null, diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 13d5584..5e2aafe 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -28,6 +28,9 @@ public function __construct(private string $storageDir) { } + /** + * @return iterable + */ public function resolve(Request $request, ArgumentMetadata $argument): iterable { $input = $request->get('input', $request->files->get('input')); diff --git a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php index 3290d9b..bf88b84 100644 --- a/src/Http/ValueResolver/ProcessConfigurationValueResolver.php +++ b/src/Http/ValueResolver/ProcessConfigurationValueResolver.php @@ -13,6 +13,7 @@ namespace CleverAge\UiProcessBundle\Http\ValueResolver; +use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsTargetedValueResolver; @@ -26,6 +27,9 @@ public function __construct(private ProcessConfigurationRegistry $registry) { } + /** + * @return iterable + */ public function resolve(Request $request, ArgumentMetadata $argument): iterable { return [$this->registry->getProcessConfiguration($request->get('process'))]; diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 0347f1a..b784e71 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -18,7 +18,19 @@ use CleverAge\ProcessBundle\Validator\ConstraintLoader; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraint; +/** + * @template UiOptions of array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * @template UiOptionList of array {'ui': UiOptions} + */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -37,6 +49,9 @@ public function getPrivateProcesses(): array return array_filter($this->getConfigurations(), fn (ProcessConfiguration $cfg) => !$cfg->isPublic()); } + /** + * @return null|UiOptions + */ public function getUiOptions(string $processCode): ?array { if (false === $this->registry->hasProcessConfiguration($processCode)) { @@ -48,6 +63,11 @@ public function getUiOptions(string $processCode): ?array return $this->resolveUiOptions($configuration->getOptions())['ui']; } + /** + * @param array $options + * + * @return UiOptionList + */ private function resolveUiOptions(array $options): array { $resolver = new OptionsResolver(); diff --git a/src/Message/ProcessExecuteMessage.php b/src/Message/ProcessExecuteMessage.php index 397f0ae..84fddb0 100644 --- a/src/Message/ProcessExecuteMessage.php +++ b/src/Message/ProcessExecuteMessage.php @@ -15,6 +15,9 @@ readonly class ProcessExecuteMessage { + /** + * @param mixed[] $context + */ public function __construct(public string $code, public mixed $input, public array $context = []) { } From ccce788c39fff30d6b9ad95a70bf5f989c00d6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:38:13 +0100 Subject: [PATCH 101/115] #14 Quality. Phpstan remove missingType.generics --- phpstan.neon | 2 -- src/Form/Type/LaunchType.php | 1 + src/Form/Type/ProcessContextType.php | 1 + src/Form/Type/ProcessUploadFileType.php | 1 + src/Manager/ProcessConfigurationsManager.php | 31 +++++++++++-------- .../ProcessExecutionExtensionRuntime.php | 1 + 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 8b167d3..030748e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,8 +6,6 @@ parameters: excludePaths: - src/DependencyInjection/Configuration.php ignoreErrors: - - - identifier: missingType.generics - identifier: doctrine.columnType reportUnmatchedIgnoredErrors: false diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 5ca2489..9c2f964 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -25,6 +25,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** @template-extends AbstractType> */ class LaunchType extends AbstractType { public function __construct( diff --git a/src/Form/Type/ProcessContextType.php b/src/Form/Type/ProcessContextType.php index e8e2c2d..d95fd19 100644 --- a/src/Form/Type/ProcessContextType.php +++ b/src/Form/Type/ProcessContextType.php @@ -18,6 +18,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\NotBlank; +/** @template-extends AbstractType */ class ProcessContextType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void diff --git a/src/Form/Type/ProcessUploadFileType.php b/src/Form/Type/ProcessUploadFileType.php index 88b77c1..57619ff 100644 --- a/src/Form/Type/ProcessUploadFileType.php +++ b/src/Form/Type/ProcessUploadFileType.php @@ -17,6 +17,7 @@ use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\OptionsResolver\OptionsResolver; +/** @template-extends AbstractType */ class ProcessUploadFileType extends AbstractType { public function configureOptions(OptionsResolver $resolver): void diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index b784e71..84393f2 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -20,17 +20,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraint; -/** - * @template UiOptions of array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': 'text|file', - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * @template UiOptionList of array {'ui': UiOptions} - */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -50,7 +39,14 @@ public function getPrivateProcesses(): array } /** - * @return null|UiOptions + * @return null|array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } */ public function getUiOptions(string $processCode): ?array { @@ -66,7 +62,16 @@ public function getUiOptions(string $processCode): ?array /** * @param array $options * - * @return UiOptionList + * @return array{ + * 'ui': array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * } */ private function resolveUiOptions(array $options): array { diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 592f1e4..60f8630 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -16,6 +16,7 @@ use CleverAge\UiProcessBundle\Entity\ProcessExecution; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; +use Symfony\Component\Form\AbstractType; use Twig\Extension\RuntimeExtensionInterface; readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface From 1173eee69b50db1710f6c16a0cee5f14e44a8b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 10:40:50 +0100 Subject: [PATCH 102/115] #14 Quality. Phpstan 7 --- phpstan.neon | 2 +- src/Manager/ProcessConfigurationsManager.php | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 030748e..9f60d1c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 6 + level: 7 paths: - src - tests diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 84393f2..83f831f 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -106,8 +106,21 @@ private function resolveUiOptions(array $options): array $uiResolver->setAllowedTypes('input_context_launcher_form', ['bool']); $uiResolver->setAllowedTypes('run_confirmation_modal', ['bool']); }); + /** + * @var array{ + * 'ui': array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': 'text|file', + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + * } $options + */ + $options = $resolver->resolve($options); - return $resolver->resolve($options); + return $options; } /** @return ProcessConfiguration[] */ From fecf2a2fc14dc089af8fffbae4a62d2d5b145ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 14:32:47 +0100 Subject: [PATCH 103/115] #14 Quality. Phpstan 8 --- phpstan.neon | 10 +--------- src/Entity/ProcessSchedule.php | 6 +++--- src/Entity/User.php | 4 ++-- src/Form/Type/LaunchType.php | 16 +++++++++------- src/Manager/ProcessConfigurationsManager.php | 4 ++-- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 9f60d1c..1cd333b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,13 +1,5 @@ parameters: - level: 7 + level: 8 paths: - src - tests - excludePaths: - - src/DependencyInjection/Configuration.php - ignoreErrors: - - - identifier: doctrine.columnType - reportUnmatchedIgnoredErrors: false - inferPrivatePropertyTypeFromConstructor: true - treatPhpDocTypesAsCertain: false diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 0637a4a..4ffa00a 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -32,7 +32,7 @@ class ProcessSchedule #[ORM\Column(length: 255)] #[IsValidProcessCode] - private ?string $process = null; + private string $process; #[ORM\Column(length: 6)] private ProcessScheduleType $type; @@ -43,7 +43,7 @@ class ProcessSchedule #[Assert\When( expression: 'this.getType().value == "every"', constraints: [new EveryExpression()] )] - private ?string $expression = null; + private string $expression; #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $input = null; @@ -109,7 +109,7 @@ public function getExpression(): ?string return $this->expression; } - public function setExpression(?string $expression): self + public function setExpression(string $expression): self { $this->expression = $expression; diff --git a/src/Entity/User.php b/src/Entity/User.php index a5f680c..11532f7 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -29,7 +29,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface private ?int $id = null; #[ORM\Column(type: Types::STRING, length: 255, unique: true)] - private ?string $email = null; + private string $email; #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $firstname = null; @@ -98,7 +98,7 @@ public function setLastname(?string $lastname): self public function getUserIdentifier(): string { - if (null === $this->email || '' === $this->email || '0' === $this->email) { + if ('' === $this->email) { throw new \LogicException('The User class must have an email.'); } diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 9c2f964..3c876bc 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -39,13 +39,15 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $code = $options['process_code']; $configuration = $this->registry->getProcessConfiguration($code); $uiOptions = $this->configurationsManager->getUiOptions($code); - $builder->add( - 'input', - 'file' === ($uiOptions['entrypoint_type'] ?? null) ? FileType::class : TextType::class, - [ - 'required' => $configuration->getEntryPoint() instanceof TaskConfiguration, - ] - ); + if (isset($uiOptions['entrypoint_type'])) { + $builder->add( + 'input', + 'file' === $uiOptions['entrypoint_type'] ? FileType::class : TextType::class, + [ + 'required' => $configuration->getEntryPoint() instanceof TaskConfiguration, + ] + ); + } $builder->add( 'context', CollectionType::class, diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 83f831f..485ef6a 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -42,7 +42,7 @@ public function getPrivateProcesses(): array * @return null|array{ * 'source': ?string, * 'target': ?string, - * 'entrypoint_type': 'text|file', + * 'entrypoint_type': string, * 'constraints': Constraint[], * 'run': 'null|bool', * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} @@ -66,7 +66,7 @@ public function getUiOptions(string $processCode): ?array * 'ui': array{ * 'source': ?string, * 'target': ?string, - * 'entrypoint_type': 'text|file', + * 'entrypoint_type': string, * 'constraints': Constraint[], * 'run': 'null|bool', * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} From 85cf872e295eac2953f0129d165d4891b93f59ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Fri, 13 Dec 2024 14:55:29 +0100 Subject: [PATCH 104/115] #14 Quality. PhpCs --- src/Entity/ProcessSchedule.php | 2 +- src/Twig/Runtime/ProcessExecutionExtensionRuntime.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index 4ffa00a..8eea928 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -80,7 +80,7 @@ public function getContext(): array } /** - * @param array $context + * @param array $context */ public function setContext(array $context): void { diff --git a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php index 60f8630..592f1e4 100644 --- a/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExecutionExtensionRuntime.php @@ -16,7 +16,6 @@ use CleverAge\UiProcessBundle\Entity\ProcessExecution; use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; -use Symfony\Component\Form\AbstractType; use Twig\Extension\RuntimeExtensionInterface; readonly class ProcessExecutionExtensionRuntime implements RuntimeExtensionInterface From e996d47c70559c9ee6c30d04d07cad73845e3cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 14:18:42 +0100 Subject: [PATCH 105/115] #14 Quality. Phpstan use phpstan type to prevent duplicate definitions. --- src/Manager/ProcessConfigurationsManager.php | 41 +++++++------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 485ef6a..aaf1a74 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -20,6 +20,16 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraint; +/** + * @phpstan-type UiOptions array{ + * 'source': ?string, + * 'target': ?string, + * 'entrypoint_type': string, + * 'constraints': Constraint[], + * 'run': 'null|bool', + * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} + * } + */ final readonly class ProcessConfigurationsManager { public function __construct(private ProcessConfigurationRegistry $registry) @@ -39,14 +49,7 @@ public function getPrivateProcesses(): array } /** - * @return null|array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': string, - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } + * @return null|UiOptions */ public function getUiOptions(string $processCode): ?array { @@ -62,16 +65,7 @@ public function getUiOptions(string $processCode): ?array /** * @param array $options * - * @return array{ - * 'ui': array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': string, - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * } + * @return array{'ui': UiOptions} */ private function resolveUiOptions(array $options): array { @@ -107,16 +101,7 @@ private function resolveUiOptions(array $options): array $uiResolver->setAllowedTypes('run_confirmation_modal', ['bool']); }); /** - * @var array{ - * 'ui': array{ - * 'source': ?string, - * 'target': ?string, - * 'entrypoint_type': 'text|file', - * 'constraints': Constraint[], - * 'run': 'null|bool', - * 'default': array{'input': mixed, 'context': array{array{'key': 'int|text', 'value':'int|text'}}} - * } - * } $options + * @var array{'ui': UiOptions} $options */ $options = $resolver->resolve($options); From 1911fbfe40f064263d8b6368f14591876194deab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 14:21:44 +0100 Subject: [PATCH 106/115] #14 Quality. Phpstan use phpstan type to prevent duplicate definitions. --- src/Manager/ProcessConfigurationsManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index aaf1a74..e3a9aae 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -49,7 +49,7 @@ public function getPrivateProcesses(): array } /** - * @return null|UiOptions + * @return UiOptions|null */ public function getUiOptions(string $processCode): ?array { From b1433dc148d326bc90a69547547b8c001629d7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Thu, 12 Dec 2024 15:17:19 +0100 Subject: [PATCH 107/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. --- templates/admin/process/list.html.twig | 2 +- templates/components/BootstrapModal.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index e655794..417567b 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} + {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} diff --git a/templates/components/BootstrapModal.html.twig b/templates/components/BootstrapModal.html.twig index 9c226de..c7976d0 100644 --- a/templates/components/BootstrapModal.html.twig +++ b/templates/components/BootstrapModal.html.twig @@ -34,4 +34,4 @@ {% endblock %} - + \ No newline at end of file From 65b20038391b125667cd1882bca7f3aea91dcb1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 15:29:03 +0100 Subject: [PATCH 108/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. PhpStan --- src/Controller/Admin/Process/LaunchAction.php | 11 +++++++++-- src/Manager/ProcessConfigurationsManager.php | 2 ++ src/Twig/Runtime/ProcessExtensionRuntime.php | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 149f92c..f828366 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -30,6 +30,7 @@ use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; +use Symfony\Component\Validator\Exception\MissingOptionsException; #[Route( '/process/launch', @@ -55,6 +56,9 @@ public function __invoke( throw new MissingProcessException(); } $uiOptions = $processConfigurationsManager->getUiOptions($processCode); + if (null === $uiOptions) { + throw new \InvalidArgumentException("Missing UI Options"); + } if (false === $uiOptions['input_context_launcher_form']) { $this->dispatch($processCode); $this->addFlash( @@ -68,12 +72,12 @@ public function __invoke( LaunchType::class, null, [ - 'constraints' => $uiOptions['constraints'] ?? [], + 'constraints' => $uiOptions['constraints'], 'process_code' => $processCode, ] ); if (false === $form->isSubmitted()) { - $default = $uiOptions['default'] ?? []; + $default = $uiOptions['default']; if (false === $form->get('input')->getConfig()->getType()->getInnerType() instanceof TextType && isset($default['input']) ) { @@ -111,6 +115,9 @@ public function __invoke( ); } + /** + * @param mixed[] $context + */ protected function dispatch(string $processCode, mixed $input = null, array $context = []): void { $message = new ProcessExecuteMessage( diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index e3a9aae..7d2caf7 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -24,6 +24,8 @@ * @phpstan-type UiOptions array{ * 'source': ?string, * 'target': ?string, + * 'input_context_launcher_form': bool, + * 'run_confirmation_modal': bool, * 'entrypoint_type': string, * 'constraints': Constraint[], * 'run': 'null|bool', diff --git a/src/Twig/Runtime/ProcessExtensionRuntime.php b/src/Twig/Runtime/ProcessExtensionRuntime.php index 3ae5777..e4f31ed 100644 --- a/src/Twig/Runtime/ProcessExtensionRuntime.php +++ b/src/Twig/Runtime/ProcessExtensionRuntime.php @@ -14,12 +14,18 @@ use CleverAge\UiProcessBundle\Manager\ProcessConfigurationsManager; use Twig\Extension\RuntimeExtensionInterface; +/** + * @phpstan-import-type UiOptions from ProcessConfigurationsManager + */ class ProcessExtensionRuntime implements RuntimeExtensionInterface { public function __construct(protected ProcessConfigurationsManager $processConfigurationsManager) { } + /** + * @return UiOptions|array{} + */ public function getUiOptions(string $code): array { return $this->processConfigurationsManager->getUiOptions($code) ?? []; From ad6d10a71f226cbb3a96a6a00fc5afce68778914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 15:42:21 +0100 Subject: [PATCH 109/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Quality --- src/Controller/Admin/Process/LaunchAction.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index f828366..226ae5d 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -30,7 +30,6 @@ use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; use Symfony\Component\Uid\Uuid; -use Symfony\Component\Validator\Exception\MissingOptionsException; #[Route( '/process/launch', @@ -57,7 +56,7 @@ public function __invoke( } $uiOptions = $processConfigurationsManager->getUiOptions($processCode); if (null === $uiOptions) { - throw new \InvalidArgumentException("Missing UI Options"); + throw new \InvalidArgumentException('Missing UI Options'); } if (false === $uiOptions['input_context_launcher_form']) { $this->dispatch($processCode); From dd2e0990dccb61e490e210bc2d99878cf6c4a1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Mon, 16 Dec 2024 15:47:34 +0100 Subject: [PATCH 110/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Quality --- templates/admin/process/list.html.twig | 2 +- templates/components/BootstrapModal.html.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 417567b..e655794 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} + {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} diff --git a/templates/components/BootstrapModal.html.twig b/templates/components/BootstrapModal.html.twig index c7976d0..9c226de 100644 --- a/templates/components/BootstrapModal.html.twig +++ b/templates/components/BootstrapModal.html.twig @@ -34,4 +34,4 @@ {% endblock %} - \ No newline at end of file + From b103677dc91eae2722eff1e4b796da25319059d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 17 Dec 2024 09:58:46 +0100 Subject: [PATCH 111/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Rework options names --- docs/index.md | 12 ++++++------ src/Controller/Admin/Process/LaunchAction.php | 2 +- src/Manager/ProcessConfigurationsManager.php | 8 +++----- templates/admin/field/report.html.twig | 4 +--- templates/admin/process/list.html.twig | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/index.md b/docs/index.md index e6d3950..db90d03 100644 --- a/docs/index.md +++ b/docs/index.md @@ -35,13 +35,13 @@ Now you can access UI Process via http://your-domain.com/process ### Launch process via UI From UI "Process List" menu entry you can run a process by clicking on "Rocket" action. -You can manage this behaviour by setting some ui options on process configuration ui option. +You can manage this behaviour by setting some ui option `ui_launch_mode` -| Options | Values | UI behaviour | -|----------------------------------|----------------|:---------:| -| input_context_launcher_form
    run_confirmation_modal | false
    false | Run process without any confirmation -| input_context_launcher_form
    run_confirmation_modal | true
    false | On click, open a form to set input and context execution -| input_context_launcher_form
    run_confirmation_modal | false
    true | On click, open confirmation model to confirm process execution +| Value | UI behaviour | +|:---------------:|:--------------------------------------------------------------:| +| modal (default) | On click, open confirmation modal to confirm process execution | +| form | On click, open a form to set input and context execution | +| null | Run process without any confirmation | ### Launch process via http request You can launch a process via http post request diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 226ae5d..8f6bed5 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -58,7 +58,7 @@ public function __invoke( if (null === $uiOptions) { throw new \InvalidArgumentException('Missing UI Options'); } - if (false === $uiOptions['input_context_launcher_form']) { + if (null === $uiOptions['ui_launch_mode'] || 'modal' === $uiOptions['ui_launch_mode']) { $this->dispatch($processCode); $this->addFlash( 'success', diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index 7d2caf7..ff8b8de 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -24,7 +24,7 @@ * @phpstan-type UiOptions array{ * 'source': ?string, * 'target': ?string, - * 'input_context_launcher_form': bool, + * 'ui_launch_mode': ?string, * 'run_confirmation_modal': bool, * 'entrypoint_type': string, * 'constraints': Constraint[], @@ -78,8 +78,7 @@ private function resolveUiOptions(array $options): array 'source' => null, 'target' => null, 'entrypoint_type' => 'text', - 'input_context_launcher_form' => false, - 'run_confirmation_modal' => false, + 'ui_launch_mode' => 'modal', 'constraints' => [], 'run' => null, 'default' => function (OptionsResolver $defaultResolver) { @@ -99,8 +98,7 @@ private function resolveUiOptions(array $options): array ); $uiResolver->setAllowedValues('entrypoint_type', ['text', 'file']); $uiResolver->setNormalizer('constraints', fn (Options $options, array $values): array => (new ConstraintLoader())->buildConstraints($values)); - $uiResolver->setAllowedTypes('input_context_launcher_form', ['bool']); - $uiResolver->setAllowedTypes('run_confirmation_modal', ['bool']); + $uiResolver->setAllowedValues('ui_launch_mode', ['modal', null, 'form']); }); /** * @var array{'ui': UiOptions} $options diff --git a/templates/admin/field/report.html.twig b/templates/admin/field/report.html.twig index c24b268..745e19c 100644 --- a/templates/admin/field/report.html.twig +++ b/templates/admin/field/report.html.twig @@ -2,7 +2,5 @@ {# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #} {# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
      - {% for key, item in field.value %} -
    • {{ key }} : {{ item }}
    • - {% endfor %} + {{ field.value }}
    diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index e655794..53c3c45 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if (false == uiOptions.input_context_launcher_form and true == uiOptions.run_confirmation_modal) %} + {% if ("modal" == uiOptions.ui_launch_mode) %} From 05c1878cf4bc6a7ddf41e9b05fcfb87496d1d7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 17 Dec 2024 10:00:28 +0100 Subject: [PATCH 112/115] #13 ability to add modal confirmation or nothing instead of launch from of process run ui. Rework options names --- templates/admin/process/list.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/process/list.html.twig b/templates/admin/process/list.html.twig index 53c3c45..083f821 100644 --- a/templates/admin/process/list.html.twig +++ b/templates/admin/process/list.html.twig @@ -33,7 +33,7 @@ {% if process.options.ui.source is defined %}{{ process.options.ui.source }}{% endif %} {% if process.options.ui.target is defined %}{{ process.options.ui.target }}{% endif %} - {% if ("modal" == uiOptions.ui_launch_mode) %} + {% if ('modal' == uiOptions.ui_launch_mode) %} From 55f982e7b656607d198a4e5c09e629cbf99e7f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 17 Dec 2024 10:19:26 +0100 Subject: [PATCH 113/115] #16 Fix context field on nested array --- src/Controller/Admin/LogRecordCrudController.php | 5 ++--- src/Controller/Admin/ProcessExecutionCrudController.php | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 7279dda..ce515a5 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -14,6 +14,7 @@ namespace CleverAge\UiProcessBundle\Controller\Admin; use CleverAge\ProcessBundle\Configuration\ProcessConfiguration; +use CleverAge\UiProcessBundle\Admin\Field\ContextField; use CleverAge\UiProcessBundle\Admin\Field\LogLevelField; use CleverAge\UiProcessBundle\Admin\Filter\LogProcessFilter; use CleverAge\UiProcessBundle\Entity\LogRecord; @@ -23,7 +24,6 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; -use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; @@ -52,8 +52,7 @@ public function configureFields(string $pageName): iterable LogLevelField::new('level'), TextField::new('message')->setMaxLength(512), DateTimeField::new('createdAt')->setFormat('Y/M/dd H:mm:ss'), - ArrayField::new('context') - ->setTemplatePath('@CleverAgeUiProcess/admin/field/array.html.twig') + ContextField::new('context') ->onlyOnDetail(), BooleanField::new('contextIsEmpty', 'Has context info ?') ->onlyOnIndex() diff --git a/src/Controller/Admin/ProcessExecutionCrudController.php b/src/Controller/Admin/ProcessExecutionCrudController.php index f0bd2ca..5e60a60 100644 --- a/src/Controller/Admin/ProcessExecutionCrudController.php +++ b/src/Controller/Admin/ProcessExecutionCrudController.php @@ -13,6 +13,7 @@ namespace CleverAge\UiProcessBundle\Controller\Admin; +use CleverAge\UiProcessBundle\Admin\Field\ContextField; use CleverAge\UiProcessBundle\Admin\Field\EnumField; use CleverAge\UiProcessBundle\Entity\ProcessExecution; use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; @@ -58,7 +59,7 @@ public function configureFields(string $pageName): iterable return $entity->duration(); // returned format can be changed here }), ArrayField::new('report')->setTemplatePath('@CleverAgeUiProcess/admin/field/report.html.twig'), - ArrayField::new('context')->setTemplatePath('@CleverAgeUiProcess/admin/field/report.html.twig'), + ContextField::new('context'), ]; } From 37a0b8b408af3de6f3f46daa715cd2bc07092893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tonon=20Gr=C3=A9gory?= Date: Tue, 17 Dec 2024 10:30:52 +0100 Subject: [PATCH 114/115] #16 Fix context field on nested array --- src/Admin/Field/ContextField.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/Admin/Field/ContextField.php diff --git a/src/Admin/Field/ContextField.php b/src/Admin/Field/ContextField.php new file mode 100644 index 0000000..c67a930 --- /dev/null +++ b/src/Admin/Field/ContextField.php @@ -0,0 +1,30 @@ +setProperty($propertyName) + ->setLabel($label) + ->setTemplatePath('@CleverAgeUiProcess/admin/field/array.html.twig'); + } +} From 990523ac993ef428743f1216f5201f1b48a78781 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Tue, 17 Dec 2024 15:49:58 +0100 Subject: [PATCH 115/115] #6 Bump dependency "cleverage/process-bundle": "^4.0" --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5b7b9e0..4e75364 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", - "cleverage/process-bundle": "dev-prepare-release", + "cleverage/process-bundle": "^4.0", "doctrine/common": "^3.0", "doctrine/dbal": "^2.9 || ^3.0", "doctrine/doctrine-bundle": "^2.5",