Compare commits

...

905 Commits
7.3.4 ... 7.5.2

Author SHA1 Message Date
Yuri Kuznetsov
1f04ba5083 7.5.2 2023-06-19 19:15:40 +03:00
Yuri Kuznetsov
1ad265611f fix entity manager 2023-06-19 17:39:53 +03:00
Yuri Kuznetsov
04906c5307 fix attachment access in posts to all users 2023-06-16 10:49:20 +03:00
Yuri Kuznetsov
fefadc58bd 7.5.1 2023-06-13 17:31:13 +03:00
Yuri Kuznetsov
1628d3b566 fix update 2023-06-13 17:22:32 +03:00
Yuri Kuznetsov
b456d86b22 ref 2023-06-13 17:19:38 +03:00
Yuri Kuznetsov
c3a1236ca9 fix email assignment notificator 2023-06-13 17:19:15 +03:00
Yuri Kuznetsov
d76a6fa0ec lang 2023-06-08 20:08:21 +03:00
Kyle Mathers
b008270fe6 Update Global.json (#2763)
Fix grammar in error messages
2023-06-08 08:28:21 +03:00
Yuri Kuznetsov
2deb826266 fix array search custom options not stored 2023-06-05 22:54:37 +03:00
Yuri Kuznetsov
66815e3192 de 2023-06-05 09:10:16 +03:00
Yuri Kuznetsov
9e34de69f0 fix enum position 2023-06-04 15:00:31 +03:00
Yuri Kuznetsov
6346fae044 fix array 2023-06-01 13:32:25 +03:00
Yuri Kuznetsov
5ab64077e8 bg 2023-06-01 09:46:47 +03:00
Yuri Kuznetsov
ae8221e208 v 2023-06-01 09:23:07 +03:00
Yuri Kuznetsov
84062f331f fix parent field loader 2023-05-29 13:13:50 +03:00
Yuri Kuznetsov
0a1cd5cb74 schema fixes 2023-05-29 11:32:32 +03:00
Yuri Kuznetsov
f63b7e04d6 fixes 2023-05-29 11:32:32 +03:00
Yuri Kuznetsov
c287137283 grunt do not clean custom modules 2023-05-29 11:32:32 +03:00
Yuri Kuznetsov
d3d8a5dc25 fix docs 2023-05-29 11:32:32 +03:00
Yuri Kuznetsov
bf5468d4f4 Update README.md 2023-05-28 18:10:41 +03:00
Yuri Kuznetsov
7b93cf028a schema impr 2023-05-28 09:07:43 +03:00
Yuri Kuznetsov
3012008b85 cleanup 2023-05-28 08:54:16 +03:00
Yuri Kuznetsov
145312af2c fix 2023-05-27 15:44:06 +03:00
Yuri Kuznetsov
0414ee6aa0 vscode json schema mappings 2023-05-27 15:36:23 +03:00
Yuri Kuznetsov
bf716b7953 fix schema 2023-05-27 15:34:32 +03:00
Yuri Kuznetsov
d4657ff85d fix 2023-05-27 14:14:04 +03:00
Yuri Kuznetsov
5023a58cc1 schema 2023-05-27 13:59:52 +03:00
Yuri Kuznetsov
9ea75f1abf metadata app orm change 2023-05-27 12:14:21 +03:00
Yuri Kuznetsov
50a91836e8 schema 2023-05-27 11:44:41 +03:00
Yuri Kuznetsov
12d05f7a6b schema 2023-05-26 14:47:25 +03:00
Yuri Kuznetsov
bff4002cad schema 2023-05-26 13:39:29 +03:00
Yuri Kuznetsov
29388a8a8d add complex expressions 2023-05-26 11:44:09 +03:00
Yuri Kuznetsov
7f29a66ad3 Merge branch 'fix' 2023-05-26 10:12:18 +03:00
Yuri Kuznetsov
e7067447b6 7.4.6 2023-05-26 09:44:35 +03:00
Yuri Kuznetsov
b807f32669 ref 2023-05-25 22:40:15 +03:00
Yuri Kuznetsov
db596c886e fix 2023-05-25 17:21:21 +03:00
Yuri Kuznetsov
0e37635373 schema 2023-05-25 17:18:55 +03:00
Yuri Kuznetsov
58ac7de123 fix comment 2023-05-25 13:57:58 +03:00
Yuri Kuznetsov
ab8421dbae ref 2023-05-25 12:28:42 +03:00
Yuri Kuznetsov
915b8f288b fix duration 2023-05-25 10:12:00 +03:00
Andrew Fontana
52b7a59085 Add title to list-tree-item to preview name (#2750)
When a folder name is too long it will be almost impossible to read it, with this addition it will be possible to hover the mouse on the folder name to view it fully.
2023-05-25 09:41:47 +03:00
Yuri Kuznetsov
e75119645b fix portal edit acl frontend check 2023-05-24 17:07:49 +03:00
Yuri Kuznetsov
a39cd8f114 Merge branch 'fix' 2023-05-24 16:35:01 +03:00
Yuri Kuznetsov
4e8f771ef7 fix has children search 2023-05-24 16:34:20 +03:00
Yuri Kuznetsov
e0ce18407d fix has children search 2023-05-24 16:31:07 +03:00
Yuri Kuznetsov
fcdcf78629 orm: fix string with colom 2023-05-24 12:16:15 +03:00
Andrew Fontana
821e346e7d edit-attributes.js fix missing translation label (#2748)
fix missing translation label for cancel button
2023-05-23 16:18:00 +03:00
Yuri Kuznetsov
0276fcf5ce orm fix select item array with 1 element 2023-05-23 14:24:43 +03:00
Yuri Kuznetsov
7c729aa23f fix 2023-05-23 14:02:23 +03:00
Yuri Kuznetsov
14d08204f1 fix 2023-05-23 14:01:32 +03:00
Yuri Kuznetsov
2747fe2716 fix test 2023-05-21 11:31:02 +03:00
Yuri Kuznetsov
ff6957f577 binding builtin check commented 2023-05-21 11:10:01 +03:00
Yuri Kuznetsov
39c0da248b cs 2023-05-21 10:05:48 +03:00
Yuri Kuznetsov
4a29c14051 primary filter name parameter 2023-05-21 10:02:19 +03:00
Yuri Kuznetsov
4f8dcf0447 Update README.md 2023-05-19 13:43:51 +03:00
Yuri Kuznetsov
081998c79f Update README.md 2023-05-19 10:34:24 +03:00
Yuri Kuznetsov
23f0f0bc6d Update README.md 2023-05-19 10:28:06 +03:00
Yuri Kuznetsov
4f7f40a245 Update README.md 2023-05-19 10:16:43 +03:00
Yuri Kuznetsov
624be85604 Update README.md 2023-05-19 10:12:06 +03:00
Yuri Kuznetsov
452eca267d Update README.md 2023-05-19 09:34:43 +03:00
Yuri Kuznetsov
0711781a1e Update README.md 2023-05-19 09:33:18 +03:00
Yuri Kuznetsov
65d3c25a9e Update README.md 2023-05-19 09:20:18 +03:00
Yuri Kuznetsov
3a94e1fb98 Update README.md 2023-05-19 09:19:22 +03:00
Yuri Kuznetsov
c621b84a4c Update README.md 2023-05-19 09:14:27 +03:00
Yuri Kuznetsov
df69375644 Merge branch 'fix' 2023-05-14 13:40:33 +03:00
Yuri Kuznetsov
53ecb36705 fix cleanup 2023-05-14 13:40:17 +03:00
Yuri Kuznetsov
2c5ba1b826 Update bug_report.md 2023-05-14 13:18:05 +03:00
Yuri Kuznetsov
90ddfe3b43 Update config.yml 2023-05-14 13:09:59 +03:00
Yuri Kuznetsov
a58d4be849 style fix 2023-05-13 15:07:00 +03:00
Yuri Kuznetsov
6f7b5e9973 cleanup 2023-05-13 15:01:57 +03:00
Yuri Kuznetsov
a727cee3a6 login 2nd step focus 2023-05-13 15:00:29 +03:00
Yuri Kuznetsov
562da819a6 fix typo 2023-05-13 14:57:24 +03:00
Yuri Kuznetsov
7cc980d525 Update bug_report.md 2023-05-12 22:27:48 +03:00
Yuri Kuznetsov
4af973015f Update bug_report.md 2023-05-12 22:26:11 +03:00
Yuri Kuznetsov
210fac225d Update config.yml 2023-05-12 22:16:05 +03:00
Yuri Kuznetsov
875377e0d2 Update bug_report.md 2023-05-12 22:10:10 +03:00
Yuri Kuznetsov
eacd62f7fb Merge branch 'fix' 2023-05-12 10:02:07 +03:00
Yuri Kuznetsov
4faaa2d082 v 2023-05-11 13:28:01 +03:00
Yuri Kuznetsov
8dda1321b5 event fix patch upgrade 2023-05-11 13:12:57 +03:00
Yuri Kuznetsov
bb59cda131 event upgrade fix 2023-05-11 12:59:41 +03:00
Yuri Kuznetsov
ed12c6f6bd cs 2023-05-10 11:54:26 +03:00
Yuri Kuznetsov
324ded28de cs 2023-05-10 10:52:34 +03:00
David
1262fdbf29 fixed group by in count (#2734)
Co-authored-by: David Moškoř <david.moskor@apertia.cz>
2023-05-10 09:13:26 +03:00
Yuri Kuznetsov
901c0ba24e use forceDisplayTopBar 2023-05-09 14:35:07 +03:00
Yuri Kuznetsov
8213f704ce fix 2023-05-09 14:20:38 +03:00
Yuri Kuznetsov
17af6bf515 Merge branch 'fix' 2023-05-09 13:28:35 +03:00
Yuri Kuznetsov
0d9f1a225f v 2023-05-09 13:14:44 +03:00
Yuri Kuznetsov
8518a44935 document dnd fix 2023-05-09 13:03:17 +03:00
Yuri Kuznetsov
458fb47f43 list button contanier placeholder 2023-05-08 18:20:34 +03:00
Yuri Kuznetsov
f4db21af2c cs 2023-05-08 14:39:22 +03:00
Yuri Kuznetsov
9d426f7feb css fix 2023-05-08 14:37:03 +03:00
Yuri Kuznetsov
52ae61b1a5 portal detail view tabs 2023-05-08 13:52:09 +03:00
Yuri Kuznetsov
c3c76fab71 dashboard field style fix 2023-05-08 12:36:05 +03:00
Yuri Kuznetsov
61db883330 kanban stick top use offset 2023-05-08 10:04:06 +03:00
Yuri Kuznetsov
447c236953 import no duplicare 2023-05-08 09:30:40 +03:00
Yuri Kuznetsov
8bbfb743f0 fix 2023-05-08 09:29:00 +03:00
Yuri Kuznetsov
3e18f488c6 cs 2023-05-07 19:40:51 +03:00
Yuri Kuznetsov
ad6d001e9f ref 2023-05-07 19:22:08 +03:00
Yuri Kuznetsov
faa11d603e cs 2023-05-07 19:18:28 +03:00
Yuri Kuznetsov
ae2eff925b fix 2023-05-07 18:49:12 +03:00
Yuri Kuznetsov
f180a8ff84 Update feature_request.md 2023-05-06 19:08:07 +03:00
Yuri Kuznetsov
e6ad56d6d0 quick create message 2023-05-06 09:46:07 +03:00
Yuri Kuznetsov
37f1948f9f ref 2023-05-06 09:35:59 +03:00
Yuri Kuznetsov
1adea79d23 notify fixes 2023-05-06 09:32:39 +03:00
Yuri Kuznetsov
dd640c2fbe ref 2023-05-06 09:32:22 +03:00
Yuri Kuznetsov
6c49e93cbf add field quick search 2023-05-05 15:07:16 +03:00
Yuri Kuznetsov
247858d295 ref 2023-05-05 15:02:32 +03:00
Yuri Kuznetsov
797679ce7a fix js docs 2023-05-05 14:53:03 +03:00
Yuri Kuznetsov
ae17acce20 disable inline edit disabled for autoincrement 2023-05-05 14:33:59 +03:00
Yuri Kuznetsov
5974098482 created at indexes for template entities 2023-05-05 14:06:37 +03:00
Yuri Kuznetsov
0ae0a7e1f9 fix label 2023-05-04 17:06:07 +03:00
Yuri Kuznetsov
fb1e4acd60 remove default empty string 2023-05-04 16:51:20 +03:00
Yuri Kuznetsov
e6407bf292 cleanup 2023-05-04 16:48:55 +03:00
Yuri Kuznetsov
2ee1728776 foreign url multiple 2023-05-04 11:29:28 +03:00
Yuri Kuznetsov
5cab488a81 url multiple export 2023-05-03 19:10:54 +03:00
Yuri Kuznetsov
c623dfac75 docs 2023-05-03 12:23:05 +03:00
Yuri Kuznetsov
3e94e18b73 disable storing text filters param 2023-05-03 11:40:58 +03:00
Yuri Kuznetsov
1d00350fa1 function generate record id 2023-05-03 11:27:18 +03:00
Yuri Kuznetsov
9056ad493b cs 2023-05-02 18:21:28 +03:00
Yuri Kuznetsov
b5a9007619 cs 2023-05-02 18:08:47 +03:00
Yuri Kuznetsov
9221cbc361 cs 2023-05-02 18:08:05 +03:00
Yuri Kuznetsov
9a6cfd4228 cs 2023-05-02 18:06:33 +03:00
Yuri Kuznetsov
81ac053818 record fetch 2023-05-02 16:19:12 +03:00
Yuri Kuznetsov
693bb804b6 cs 2023-05-02 14:56:38 +03:00
Yuri Kuznetsov
6ec70d7792 duplicates use list view 2023-05-02 14:34:56 +03:00
Yuri Kuznetsov
0c6ddb725b docs 2023-05-02 12:38:57 +03:00
Yuri Kuznetsov
fe7689297c dont create select manager 2023-05-02 12:38:13 +03:00
Yuri Kuznetsov
95809454b8 freeEmailProviderDomains custom 2023-05-02 12:34:29 +03:00
Yuri Kuznetsov
9bc932d54f user is busy function 2023-05-02 12:12:51 +03:00
Yuri Kuznetsov
d57d5d1d4a methods 2023-05-02 11:52:59 +03:00
Yuri Kuznetsov
b929aa07ec cs 2023-05-02 10:58:58 +03:00
Yuri Kuznetsov
0c0e118ea2 duplicates use preapre entity for output 2023-05-02 09:57:58 +03:00
Yuri Kuznetsov
d522eab8f5 entity manager params panels 2023-05-01 15:27:03 +03:00
Yuri Kuznetsov
21d5ea9fe6 upgrade fix 2023-05-01 15:26:36 +03:00
Yuri Kuznetsov
9bb1cb3efc fix metadata save custom 2023-05-01 15:25:22 +03:00
Yuri Kuznetsov
c681c3ba54 event status treatment editable 2023-05-01 14:21:36 +03:00
Yuri Kuznetsov
7960eb87cc change 2023-05-01 11:50:55 +03:00
Yuri Kuznetsov
f565f4cf04 revert 2023-05-01 11:34:15 +03:00
Yuri Kuznetsov
5775ddcf6a convert currency change 2023-05-01 11:24:42 +03:00
Yuri Kuznetsov
a220bce2a4 rename 2023-05-01 10:20:01 +03:00
Yuri Kuznetsov
184573946f mainCurrencyFieldList 2023-05-01 10:12:39 +03:00
Yuri Kuznetsov
e0a00f4d41 currency convesion ref 2023-04-30 20:12:03 +03:00
Yuri Kuznetsov
4fe1a035c6 currency disable action 2023-04-30 19:13:49 +03:00
Yuri Kuznetsov
5148f5e341 use customizationOptionsReferenceDisabled 2023-04-30 15:07:13 +03:00
Yuri Kuznetsov
19fa50b6a7 history status list param 2023-04-30 14:55:46 +03:00
Yuri Kuznetsov
19949f4217 template specific entity params 2023-04-30 12:23:20 +03:00
Yuri Kuznetsov
bef906e421 status field locked 2023-04-30 12:07:22 +03:00
Yuri Kuznetsov
0c68ecef37 api error output status reason only specific exceptions 2023-04-30 10:39:05 +03:00
Yuri Kuznetsov
4c5cd11ffb Merge branch 'fix' 2023-04-30 10:07:34 +03:00
Yuri Kuznetsov
b4a5d28f53 duplicate check only name 2023-04-30 10:07:19 +03:00
Yuri Kuznetsov
06ffc8c6f6 fix title 2023-04-29 22:54:51 +03:00
Yuri Kuznetsov
eb32f23d38 ref 2023-04-29 20:32:28 +03:00
Yuri Kuznetsov
5d61b049b5 api-before-save-script 2023-04-29 19:18:02 +03:00
Yuri Kuznetsov
2b667ffa03 cs 2023-04-29 10:55:29 +03:00
Yuri Kuznetsov
fdb24513b5 cs 2023-04-29 10:49:25 +03:00
Yuri Kuznetsov
a822535537 cs 2023-04-28 16:26:07 +03:00
Yuri Kuznetsov
83b60e49c6 ref 2023-04-28 16:19:41 +03:00
Yuri Kuznetsov
86c8fe9a83 ref 2023-04-28 16:08:06 +03:00
Yuri Kuznetsov
d460805c8b ref 2023-04-28 15:57:25 +03:00
Yuri Kuznetsov
a9d73a8501 ref 2023-04-28 15:44:47 +03:00
Yuri Kuznetsov
a3cf76be92 ref 2023-04-28 15:26:06 +03:00
Yuri Kuznetsov
23c9893362 ref 2023-04-28 15:21:19 +03:00
Yuri Kuznetsov
7efbe56763 clnup 2023-04-28 15:20:01 +03:00
Yuri Kuznetsov
9759ab523c ref 2023-04-28 14:28:51 +03:00
Yuri Kuznetsov
21f8ff0168 docs 2023-04-28 13:31:07 +03:00
Yuri Kuznetsov
f865bd9282 docs fix 2023-04-28 13:29:41 +03:00
Yuri Kuznetsov
8e0770b15d entity manager params 2023-04-28 12:58:06 +03:00
Yuri Kuznetsov
0b696f8388 doc fix 2023-04-28 11:07:52 +03:00
Yuri Kuznetsov
6b6c166eca ref 2023-04-28 09:48:07 +03:00
Yuri Kuznetsov
598422a822 cs 2023-04-28 09:38:36 +03:00
Yuri Kuznetsov
15b3a89520 dashboard locked remove 2023-04-27 17:14:38 +03:00
Yuri Kuznetsov
7d06d0f6a4 cs docs 2023-04-27 16:40:15 +03:00
Yuri Kuznetsov
b975799231 layoutDefs usage 2023-04-27 15:59:19 +03:00
Yuri Kuznetsov
96a8194775 update bullbone 2023-04-27 15:58:10 +03:00
Yuri Kuznetsov
600150c363 ref 2023-04-27 15:18:09 +03:00
Yuri Kuznetsov
8a1242c312 Bull extend usage 2023-04-27 14:40:19 +03:00
Yuri Kuznetsov
b44b8721c5 layout edit impr 2023-04-27 13:56:16 +03:00
Yuri Kuznetsov
6149f1a476 no total text 2023-04-27 13:38:43 +03:00
Yuri Kuznetsov
f4eb69c831 dashboard tab name max length 2023-04-27 12:54:28 +03:00
Yuri Kuznetsov
0e94a9708a dashboard locked prefrerences param 2023-04-27 12:45:18 +03:00
Yuri Kuznetsov
97cc94d3d9 clnup 2023-04-27 11:27:16 +03:00
Yuri Kuznetsov
ec848524a6 create related link read only 2023-04-27 11:25:48 +03:00
Yuri Kuznetsov
ec20edde5e cs 2023-04-27 11:12:06 +03:00
Yuri Kuznetsov
d6093e7764 ref 2023-04-27 10:34:38 +03:00
Yuri Kuznetsov
b71bc36061 clnp 2023-04-27 10:21:56 +03:00
Yuri Kuznetsov
359fc94d99 update phpstan 2023-04-27 10:21:30 +03:00
Yuri Kuznetsov
5e59cbea8a type fixes 2023-04-27 10:21:24 +03:00
Yuri Kuznetsov
843a7c1f1e Merge branch 'fix' 2023-04-27 09:58:03 +03:00
Yuri Kuznetsov
aa5427d976 fix 2023-04-27 09:43:09 +03:00
Yuri Kuznetsov
04218e0291 fix 2023-04-27 09:43:02 +03:00
Yuri Kuznetsov
9a7c4da780 fix 2023-04-26 22:46:27 +03:00
Yuri Kuznetsov
da777f2e40 cs 2023-04-26 22:41:39 +03:00
Yuri Kuznetsov
7fc92a6a03 ref 2023-04-26 22:38:25 +03:00
Yuri Kuznetsov
f93958ffea ref 2023-04-26 22:11:18 +03:00
Yuri Kuznetsov
1f71856d59 test fix 2023-04-26 18:28:24 +03:00
Yuri Kuznetsov
097f5141d3 ref 2023-04-26 18:14:45 +03:00
Yuri Kuznetsov
9547c45109 email import ref, use locking 2023-04-26 18:12:48 +03:00
Yuri Kuznetsov
753158ae7a link multiple with id list 2023-04-26 17:56:55 +03:00
Yuri Kuznetsov
f50752df6f improve text search autocomplete 2023-04-26 16:12:18 +03:00
Yuri Kuznetsov
1525401105 style fix 2023-04-26 14:49:44 +03:00
Yuri Kuznetsov
d62d4265a8 url-multiple field 2023-04-26 14:25:56 +03:00
Yuri Kuznetsov
4aae685c6e ref 2023-04-26 13:20:37 +03:00
Yuri Kuznetsov
18cd794fe1 ref 2023-04-26 12:25:57 +03:00
Yuri Kuznetsov
b20a4e768e Merge branch 'fix' 2023-04-26 11:59:42 +03:00
Yuri Kuznetsov
c7c6cfe27f fix dompdf custom page size 2023-04-26 11:57:44 +03:00
Yuri Kuznetsov
87077c7644 ref 2023-04-26 11:34:48 +03:00
Yuri Kuznetsov
fd02e83cea css fix 2023-04-26 11:29:37 +03:00
Yuri Kuznetsov
8da8285c56 css fix 2023-04-25 17:44:13 +03:00
Yuri Kuznetsov
5c7f67a711 cleanup 2023-04-25 17:42:50 +03:00
Yuri Kuznetsov
26634de090 stored text search 2023-04-25 16:44:10 +03:00
Yuri Kuznetsov
1f2c89517e typo 2023-04-25 13:29:39 +03:00
Yuri Kuznetsov
472a4a63d7 add filter quick search 2023-04-25 12:03:23 +03:00
Yuri Kuznetsov
634315f9e4 cs 2023-04-25 10:12:11 +03:00
Yuri Kuznetsov
064ccd31fc fix edit modal header 2023-04-24 15:45:40 +03:00
Yuri Kuznetsov
0c694447d6 event filters 2023-04-24 15:36:32 +03:00
Yuri Kuznetsov
3ae84a0e5b consts 2023-04-24 14:43:06 +03:00
Yuri Kuznetsov
234de9b812 ref 2023-04-24 14:37:23 +03:00
Yuri Kuznetsov
257e3621ea email filter body contains all 2023-04-24 13:56:55 +03:00
Yuri Kuznetsov
65e31f15a2 email filter cache 2023-04-24 13:08:13 +03:00
Yuri Kuznetsov
982201a1fa ref 2023-04-24 12:22:02 +03:00
Yuri Kuznetsov
bb9c2f5e92 image radius 2023-04-24 11:46:28 +03:00
Yuri Kuznetsov
9dc04b2357 Merge branch 'fix' 2023-04-24 11:43:11 +03:00
Yuri Kuznetsov
98d457dae6 fix list view image height 2023-04-24 11:42:59 +03:00
Yuri Kuznetsov
d0f7798d55 avatar radius 2023-04-24 11:39:56 +03:00
Yuri Kuznetsov
5ee7b4ffad style fix 2023-04-24 11:24:14 +03:00
Yuri Kuznetsov
7b15b13e8b email validations 2023-04-24 11:16:11 +03:00
Yuri Kuznetsov
2b10be3464 ref 2023-04-24 10:21:57 +03:00
Yuri Kuznetsov
4911d7caa1 cs 2023-04-24 10:08:31 +03:00
Yuri Kuznetsov
a23886143a ref 2023-04-24 09:49:11 +03:00
Yuri Kuznetsov
16e0ee4576 cs 2023-04-23 09:45:33 +03:00
Yuri Kuznetsov
33dccd4ef7 cs 2023-04-22 21:27:57 +03:00
Yuri Kuznetsov
7d03ae498b ref 2023-04-22 21:20:58 +03:00
Yuri Kuznetsov
fda1dedbe4 ref 2023-04-22 21:09:37 +03:00
Yuri Kuznetsov
07c2a2e49b cs 2023-04-22 21:08:18 +03:00
Yuri Kuznetsov
4964056343 ref 2023-04-22 20:49:54 +03:00
Yuri Kuznetsov
98e15c8f87 cs 2023-04-22 15:43:10 +03:00
Yuri Kuznetsov
6c602610d4 ref 2023-04-22 15:40:34 +03:00
Yuri Kuznetsov
08efd3f979 style fix 2023-04-21 17:56:16 +03:00
Yuri Kuznetsov
49a9cf9248 ref 2023-04-21 17:54:16 +03:00
Yuri Kuznetsov
d56877c591 ref 2023-04-21 17:47:07 +03:00
Yuri Kuznetsov
6fe123b3f9 ref 2023-04-21 17:47:04 +03:00
Yuri Kuznetsov
427d2dcf52 ref 2023-04-21 17:24:54 +03:00
Yuri Kuznetsov
755f3de523 fix 2023-04-21 14:34:50 +03:00
Yuri Kuznetsov
fc72d847da print email 2023-04-21 14:14:00 +03:00
Yuri Kuznetsov
6a963f39d4 username unique index 2023-04-21 13:08:56 +03:00
Yuri Kuznetsov
5161fbb1d4 save error handling fix 2023-04-21 12:37:17 +03:00
Yuri Kuznetsov
fe32d8d47b job no table locking param 2023-04-21 11:13:09 +03:00
Yuri Kuznetsov
fffa608816 note update empty 2023-04-21 10:50:39 +03:00
Yuri Kuznetsov
fb79de7903 Merge branch 'fix' 2023-04-21 10:34:31 +03:00
Yuri Kuznetsov
007cf8c2aa action button race condition fix 2023-04-21 10:34:08 +03:00
Yuri Kuznetsov
67c86c9521 clnup 2023-04-20 19:50:01 +03:00
Yuri Kuznetsov
780d83f049 ref 2023-04-20 19:48:34 +03:00
Yuri Kuznetsov
1e420ed6f7 comment 2023-04-20 19:31:52 +03:00
Yuri Kuznetsov
e5a382b2ec ref 2023-04-20 19:26:29 +03:00
Yuri Kuznetsov
b326142952 cs 2023-04-20 19:24:25 +03:00
Yuri Kuznetsov
6870c47132 ref 2023-04-20 19:11:27 +03:00
Yuri Kuznetsov
5251fcd4ec ref 2023-04-20 18:32:24 +03:00
Yuri Kuznetsov
f9c6147396 ref 2023-04-20 18:03:30 +03:00
Yuri Kuznetsov
937b2adf57 ref 2023-04-20 17:36:41 +03:00
Yuri Kuznetsov
b4e4c875b9 ref 2023-04-20 17:18:53 +03:00
Yuri Kuznetsov
1d52afb45a ip address util 2023-04-20 16:42:26 +03:00
Yuri Kuznetsov
37165fc735 job ref 2023-04-20 16:11:43 +03:00
Yuri Kuznetsov
bed891289f ref 2023-04-20 15:45:54 +03:00
Yuri Kuznetsov
3a007518e5 ref 2023-04-20 15:00:58 +03:00
Yuri Kuznetsov
c2b856c3da cs 2023-04-20 14:40:02 +03:00
Yuri Kuznetsov
5f944554cf ip address forwarded 2023-04-20 13:56:10 +03:00
dependabot[bot]
db34791130 Bump guzzlehttp/psr7 from 1.8.4 to 1.9.1 (#2704)
Bumps [guzzlehttp/psr7](https://github.com/guzzle/psr7) from 1.8.4 to 1.9.1.
- [Release notes](https://github.com/guzzle/psr7/releases)
- [Changelog](https://github.com/guzzle/psr7/blob/1.9.1/CHANGELOG.md)
- [Commits](https://github.com/guzzle/psr7/compare/1.8.4...1.9.1)

---
updated-dependencies:
- dependency-name: guzzlehttp/psr7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-20 09:20:15 +03:00
Yuri Kuznetsov
8b73912c3d revert 2023-04-19 12:17:23 +03:00
Yuri Kuznetsov
1ac2f489ab person-name use coalesce 2023-04-19 12:08:33 +03:00
Yuri Kuznetsov
4309d79c56 ref 2023-04-19 09:28:20 +03:00
Yuri Kuznetsov
a802f740c5 docs 2023-04-19 09:28:20 +03:00
dependabot[bot]
9eb4fd7cf9 Bump slim/psr7 from 1.4 to 1.6.1 (#2700)
Bumps [slim/psr7](https://github.com/slimphp/Slim-Psr7) from 1.4 to 1.6.1.
- [Release notes](https://github.com/slimphp/Slim-Psr7/releases)
- [Commits](https://github.com/slimphp/Slim-Psr7/compare/1.4...1.6.1)

---
updated-dependencies:
- dependency-name: slim/psr7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-19 09:27:44 +03:00
Yuri Kuznetsov
4dd5784838 enum title 2023-04-18 19:34:29 +03:00
Yuri Kuznetsov
87911fc3b6 ref cs 2023-04-18 19:23:01 +03:00
Yuri Kuznetsov
d2a1737a9e array style fix 2023-04-18 18:39:59 +03:00
Yuri Kuznetsov
352eefdb29 complex-text-memo 2023-04-18 16:25:26 +03:00
Yuri Kuznetsov
e3a2042990 memo dashlet 2023-04-18 16:11:26 +03:00
Yuri Kuznetsov
a492a3bbb6 doc 2023-04-18 16:06:19 +03:00
Yuri Kuznetsov
fac84830d3 Update config.yml 2023-04-18 14:25:47 +03:00
Yuri Kuznetsov
3d743d306b copy to clipboard varchar/url/number 2023-04-18 13:44:19 +03:00
Yuri Kuznetsov
6de9e82709 Merge branch 'fix' 2023-04-18 12:45:24 +03:00
Yuri Kuznetsov
773f929b01 fix language cleanup 2023-04-18 12:45:15 +03:00
Yuri Kuznetsov
3a6a185548 admin focus on search 2023-04-18 12:37:04 +03:00
Yuri Kuznetsov
32d1863411 doc 2023-04-18 12:28:24 +03:00
Yuri Kuznetsov
23dd15e979 Merge branch 'fix' 2023-04-18 12:20:28 +03:00
Yuri Kuznetsov
f3da3e0fb3 fix 2023-04-18 12:01:50 +03:00
Yuri Kuznetsov
396d74df63 side bar wider 2023-04-18 11:52:35 +03:00
Yuri Kuznetsov
7293893fc7 email folders sticked wide screen fix 2023-04-18 11:25:58 +03:00
Yuri Kuznetsov
9b796e7832 list border radius on wide screen 2023-04-18 11:08:19 +03:00
Yuri Kuznetsov
a8dab3a3b1 Merge branch 'fix' 2023-04-18 10:33:30 +03:00
Yuri Kuznetsov
e432e14a95 ref 2023-04-17 16:56:01 +03:00
Yuri Kuznetsov
ee865662b2 cs 2023-04-17 16:51:48 +03:00
Yuri Kuznetsov
a24313c789 clnup 2023-04-17 16:46:09 +03:00
Yuri Kuznetsov
02fd5c430f ref 2023-04-17 16:45:50 +03:00
Yuri Kuznetsov
4e0e223766 Update config.yml 2023-04-17 13:38:12 +03:00
Yuri Kuznetsov
2df5017e94 Update feature_request.md 2023-04-17 13:37:50 +03:00
Yuri Kuznetsov
6deb9b4ab7 Update bug_report.md 2023-04-17 13:37:37 +03:00
Yuri Kuznetsov
0a57e538d5 fix layout 2023-04-17 12:20:20 +03:00
Yuri Kuznetsov
e8dae0cfd1 account role title 2023-04-17 12:20:14 +03:00
Yuri Kuznetsov
e9c55bbd43 css fix 2023-04-15 17:22:16 +03:00
Yuri Kuznetsov
7a98325eae fix email stickable 2023-04-15 10:54:58 +03:00
Yuri Kuznetsov
b0a811c51d stream update css fix 2023-04-15 10:25:47 +03:00
Yuri Kuznetsov
da013d8aae Merge branch 'fix' 2023-04-14 17:12:53 +03:00
Yuri Kuznetsov
a1d920f003 email stickable fix 2023-04-14 11:53:16 +03:00
Yuri Kuznetsov
07443e54de createSearchView method 2023-04-14 11:00:57 +03:00
Yuri Kuznetsov
717a678c9a fix show detail 2023-04-13 23:44:32 +03:00
Yuri Kuznetsov
ffaf999587 ref 2023-04-13 21:16:33 +03:00
Yuri Kuznetsov
37fba10ba7 ref 2023-04-13 21:05:34 +03:00
Yuri Kuznetsov
0a9de8cf56 ref 2023-04-13 20:48:06 +03:00
Yuri Kuznetsov
a02be88c4a cleanup 2023-04-13 17:13:21 +03:00
Yuri Kuznetsov
e8dc05ad99 ref 2023-04-13 16:53:33 +03:00
Yuri Kuznetsov
6338a73eaa discard tryReady usage 2023-04-13 14:56:30 +03:00
Yuri Kuznetsov
73533080f6 list bottom radius class 2023-04-13 11:34:04 +03:00
Yuri Kuznetsov
1c7a6d9825 mailto fix 2023-04-13 11:08:12 +03:00
Yuri Kuznetsov
c553bc8d0a linkCheckDisabled 2023-04-12 17:17:27 +03:00
Yuri Kuznetsov
9ff967249b teams users active filter 2023-04-12 13:24:32 +03:00
Yuri Kuznetsov
3011cdf22c cs 2023-04-12 13:21:04 +03:00
Yuri Kuznetsov
4f2ade5f7f css fix 2023-04-12 11:15:45 +03:00
Yuri Kuznetsov
b882aad4ab iframe line height 2023-04-12 11:07:32 +03:00
Yuri Kuznetsov
0d6f98319d Merge branch 'fix' 2023-04-11 18:31:45 +03:00
Yuri Kuznetsov
8541c12441 dynamic logic reminder 2023-04-11 18:31:35 +03:00
Yuri Kuznetsov
57d9dbc33e fix stream dashlet 2023-04-11 16:23:35 +03:00
Yuri Kuznetsov
81d92870e9 attachmentAvailableStorageList 2023-04-11 16:08:25 +03:00
Yuri Kuznetsov
a86795ea48 forbid system field/link name 2023-04-11 15:54:19 +03:00
Yuri Kuznetsov
cb6a320eb5 fix typo 2023-04-11 15:52:42 +03:00
Yuri Kuznetsov
c9ab718666 cs 2023-04-11 15:51:53 +03:00
Yuri Kuznetsov
46cace5ed2 Merge branch 'fix' 2023-04-11 15:50:44 +03:00
Yuri Kuznetsov
2a967261b3 mass action disable 2023-04-11 14:36:52 +03:00
Yuri Kuznetsov
66ecf7794e options ref 2023-04-11 14:10:38 +03:00
Yuri Kuznetsov
7365007511 aclDependency refactoring 2023-04-11 11:55:42 +03:00
Yuri Kuznetsov
88870ccac8 Merge branch 'version/7.5' 2023-04-11 10:20:52 +03:00
Yuri Kuznetsov
12e40352fe fix jpeg 2023-04-11 10:06:26 +03:00
Yuri Kuznetsov
2b0bde8c0b cs 2023-04-10 15:45:32 +03:00
Yuri Kuznetsov
931e8b934c user view usage 2023-04-10 15:45:16 +03:00
Yuri Kuznetsov
a07cb5ef38 range fields autonumeric 2023-04-10 15:17:06 +03:00
Yuri Kuznetsov
66a6f70a30 v 2023-04-07 22:18:02 +03:00
Yuri Kuznetsov
d7a629c5a3 int/float fix 2023-04-07 22:17:25 +03:00
Yuri Kuznetsov
506e96e333 float preventing same decimal mark and th separator 2023-04-07 17:38:06 +03:00
Yuri Kuznetsov
76a9177c46 v 2023-04-07 16:42:17 +03:00
Yuri Kuznetsov
a8baac3f92 missing counterpart link warning 2023-04-07 16:40:57 +03:00
Yuri Kuznetsov
8d9d073c16 fix currency decimal places null 2023-04-07 10:10:36 +03:00
Yuri Kuznetsov
177ecdb70b relation issue msg 2023-04-06 20:40:48 +03:00
Yuri Kuznetsov
89ce80d5b2 fix empty type 2023-04-06 19:19:44 +03:00
Yuri Kuznetsov
7f07175bee v 2023-04-06 19:08:54 +03:00
Yuri Kuznetsov
8bca35934c error msg 2023-04-06 19:05:28 +03:00
Yuri Kuznetsov
65bef1df65 fix link-parent not-storable 2023-04-06 18:57:38 +03:00
Yuri Kuznetsov
922a2e835c 2fa portals 2023-04-06 15:31:28 +03:00
Yuri Kuznetsov
048c83def8 upgrade check 2023-04-05 13:06:42 +03:00
Yuri Kuznetsov
cf4a8c6c11 ref 2023-04-04 16:35:37 +03:00
Yuri Kuznetsov
7259142117 ref 2023-04-04 15:12:36 +03:00
Yuri Kuznetsov
746398c5ca cs 2023-04-04 15:10:19 +03:00
Yuri Kuznetsov
6a61772e43 cs 2023-04-04 15:09:21 +03:00
Yuri Kuznetsov
2412fb5151 cs 2023-04-04 15:08:44 +03:00
Yuri Kuznetsov
5e5a229366 cleanup 2023-04-04 10:21:48 +03:00
Yuri Kuznetsov
5d27a7a828 linkForeignAccessCheckDisabled 2023-04-04 10:15:48 +03:00
Yuri Kuznetsov
82cc4a7f03 link check allow defaults 2023-04-04 10:00:57 +03:00
Yuri Kuznetsov
d2033c53fc link-check fix 2023-04-04 09:30:08 +03:00
Yuri Kuznetsov
86043a5ce5 link check portal bypass 2023-04-03 21:46:22 +03:00
SuchAFuriousDeath
1fae4ac84b integration-order (#2686)
Co-authored-by: tompro <tomas.prochazka@apertia.cz>
2023-04-03 15:46:15 +03:00
Yuri Kuznetsov
6301ba491c formula set link multiple column 2023-04-03 13:43:50 +03:00
Yuri Kuznetsov
defe9965d4 getColumnById 2023-04-03 13:20:34 +03:00
Yuri Kuznetsov
937ad48841 fix 2023-04-03 13:20:11 +03:00
Yuri Kuznetsov
781030df60 ref 2023-04-03 12:40:50 +03:00
Yuri Kuznetsov
9b009962a5 print fix 2023-04-03 09:45:46 +03:00
Rabii Brahimi
255b6637ff Update Delete to allow to remove recordDefs and selectDefs (#2684)
When a custom entity of type event is deleted - its recordDefs and selectDefs files are not removed. 
Hope this doesn't break anything and just add ability to remove the two files.
2023-04-03 09:35:27 +03:00
Yuri Kuznetsov
28d1c052d2 formula parser fixes 2023-03-31 22:42:44 +03:00
Yuri Kuznetsov
828d8da741 fix link check 2023-03-31 10:38:32 +03:00
Eymen Elkum
54688795e2 rtl vertical theme (#2678)
Co-authored-by: Eymen Elkum <eymen@eblasoft.com.tr>
2023-03-30 11:33:23 +03:00
Yuri Kuznetsov
6414a13c6f template assigned user required false 2023-03-30 10:20:59 +03:00
Yuri Kuznetsov
c48f17449b v 2023-03-30 09:58:39 +03:00
Yuri Kuznetsov
cbf65feb09 before-upgrade script 2023-03-30 09:46:53 +03:00
Yuri Kuznetsov
f1a3021c1c fix email applier 2023-03-29 14:14:10 +03:00
Arkadiy Asuratov
b70327874e ensure notes by portal users are always public (#2681) 2023-03-29 11:24:22 +03:00
Yuri Kuznetsov
9345ada934 attachment size bigint 2023-03-29 08:17:09 +03:00
Yuri Kuznetsov
92c66a3b9a group email folder mass remove disabled 2023-03-29 08:13:22 +03:00
Yuri Kuznetsov
c78f84650c fix dbType 2023-03-29 08:05:59 +03:00
Eymen Elkum
cf1692a8a4 border-radios fixes for rtl theme (#2676)
* border-radios fixes for rtl theme

* RTL: improve the fix of rounded borders

* RTL: use css variable for radios

---------

Co-authored-by: Eymen Elkum <eymen@eblasoft.com.tr>
2023-03-29 08:04:07 +03:00
Yuri Kuznetsov
94321b3500 read-only side/bottom panels fix 2023-03-29 07:53:35 +03:00
Yuri Kuznetsov
2010d16d4d ref 2023-03-24 20:35:12 +02:00
Yuri Kuznetsov
c1a1e1094a Update SECURITY.md 2023-03-24 20:16:52 +02:00
Yuri Kuznetsov
c2fefd6227 cs 2023-03-24 19:47:49 +02:00
Yuri Kuznetsov
99946c8da5 working time calendar icon 2023-03-24 11:46:31 +02:00
Yuri Kuznetsov
86c2478721 style fix 2023-03-23 14:54:02 +02:00
Yuri Kuznetsov
5331332103 duplicate fix 2023-03-23 14:33:28 +02:00
Yuri Kuznetsov
0e380e1c10 mass update empty fix 2023-03-23 14:18:03 +02:00
Yuri Kuznetsov
c54dbdc169 cleanup 2023-03-23 14:18:03 +02:00
Yuri Kuznetsov
f88261a40a Update README.md 2023-03-21 19:39:24 +02:00
Yuri Kuznetsov
7ec8d1f69c revert 2023-03-21 19:11:32 +02:00
Yuri Kuznetsov
77ce0a3b4e Update README.md 2023-03-21 18:01:13 +02:00
Yuri Kuznetsov
134bde3370 Update README.md 2023-03-21 18:00:42 +02:00
Yuri Kuznetsov
811c841420 Update README.md 2023-03-21 17:41:27 +02:00
Yuri Kuznetsov
48751813fb fix warning 2023-03-21 16:07:23 +02:00
Yuri Kuznetsov
79c182d173 kanban records per page 2023-03-21 15:42:40 +02:00
Yuri Kuznetsov
87a612a1bc change user interface settings layout 2023-03-21 15:41:52 +02:00
Yuri Kuznetsov
388da3db70 name duplicate checker 2023-03-21 14:34:32 +02:00
Yuri Kuznetsov
60fdeafd77 cs 2023-03-21 13:12:19 +02:00
Yuri Kuznetsov
2057534f19 robots.txt 2023-03-21 08:16:16 +02:00
Yuri Kuznetsov
b85f60b855 ref cs 2023-03-20 13:36:50 +02:00
Yuri Kuznetsov
b4d02130fb typo 2023-03-20 13:32:51 +02:00
Yuri Kuznetsov
9a9d924b19 typo 2023-03-20 13:32:10 +02:00
Yuri Kuznetsov
1fb06f60e0 Merge branch 'fix' 2023-03-20 09:46:12 +02:00
Yuri Kuznetsov
9d65855868 fix array-is-not-empty 2023-03-20 09:43:25 +02:00
Yuri Kuznetsov
8cf2e270a5 fix record-modal helper 2023-03-20 09:34:55 +02:00
Yuri Kuznetsov
07ebd43ac6 max log message length 10000 2023-03-20 09:34:55 +02:00
Yuri Kuznetsov
b1447a2922 Update README.md 2023-03-19 10:23:51 +02:00
Yuri Kuznetsov
66b85bf4e9 Update CONTRIBUTING.md 2023-03-19 10:22:19 +02:00
Yuri Kuznetsov
e9b58926b4 Update CONTRIBUTING.md 2023-03-19 10:22:13 +02:00
Yuri Kuznetsov
75724b28b2 Update CONTRIBUTING.md 2023-03-19 10:21:06 +02:00
Yuri Kuznetsov
79f0730257 Update CONTRIBUTING.md 2023-03-19 10:14:21 +02:00
Yuri Kuznetsov
13abed67f2 Update README.md 2023-03-19 09:55:13 +02:00
Yuri Kuznetsov
84b98c1cfe Update README.md 2023-03-18 12:19:39 +02:00
Yuri Kuznetsov
bc557706ca Update README.md 2023-03-18 12:18:53 +02:00
SuchAFuriousDeath
2ef0f5f80e fixed duplicate key (#2667)
Co-authored-by: tompro <tomas.prochazka@apertia.cz>
2023-03-18 12:01:23 +02:00
Yuri Kuznetsov
33db2270d6 Update README.md 2023-03-18 10:28:02 +02:00
Yuri Kuznetsov
6810ee37ac Update README.md 2023-03-18 09:10:40 +02:00
Yuri Kuznetsov
9e25804f89 update moment timezone 2023-03-17 13:44:29 +02:00
Yuri Kuznetsov
42d30a3f8e date picker in modal 2023-03-17 11:03:26 +02:00
Yuri Kuznetsov
524f94cd54 fix xlsx 2023-03-17 10:23:44 +02:00
Yuri Kuznetsov
739230c4b9 fix currency factory 2023-03-17 10:12:51 +02:00
Yuri Kuznetsov
caeadc2f28 css fix 2023-03-16 12:58:08 +02:00
Yuri Kuznetsov
fd330f991c ref 2023-03-16 11:02:32 +02:00
David
e09bf8fa31 fix remove row (#2663)
Co-authored-by: David Moškoř <david.moskor@apertia.cz>
2023-03-16 09:01:40 +02:00
Yuri Kuznetsov
2ea60e66ba not storable select foreign 2023-03-15 18:51:40 +02:00
Yuri Kuznetsov
f184e34838 extensions sortable by name 2023-03-15 18:07:30 +02:00
Eymen Elkum
d721e9b448 entityType instead of scope (#2661) 2023-03-15 12:45:41 +02:00
Yuri Kuznetsov
e1241eddb7 css fix 2023-03-15 10:33:00 +02:00
Yuri Kuznetsov
c693654e80 fix 2023-03-15 09:54:42 +02:00
Yuri Kuznetsov
9d0f3dadad fix multi-enum validation popover 2023-03-15 08:19:37 +02:00
Yuri Kuznetsov
2c4033f363 formula currency convert 2023-03-14 11:15:23 +02:00
Yuri Kuznetsov
3c62414c8d doc 2023-03-14 11:01:27 +02:00
Yuri Kuznetsov
9dddd0b92f dark theme table bold 700 2023-03-13 17:27:51 +02:00
Yuri Kuznetsov
2284a3e2e5 orm: map function 2023-03-13 13:43:51 +02:00
Yuri Kuznetsov
60d83b138a cs 2023-03-13 11:13:23 +02:00
Yuri Kuznetsov
c94d41a79c types, rename 2023-03-13 11:08:53 +02:00
Yuri Kuznetsov
fc78cd28a6 docs 2023-03-13 10:47:09 +02:00
Yuri Kuznetsov
b0e01a1fcb select order no complex expressions 2023-03-13 10:43:58 +02:00
Yuri Kuznetsov
41222f8e9e docs 2023-03-13 10:19:57 +02:00
Yuri Kuznetsov
64baaa5253 wysiwyg iframe shortcuts support 2023-03-13 09:53:42 +02:00
Yuri Kuznetsov
35a0f14d28 id generator usage 2023-03-13 08:59:09 +02:00
Yuri Kuznetsov
9bb2197717 ref, id generator usage 2023-03-13 08:54:38 +02:00
Yuri Kuznetsov
1607240f5d readme change 2023-03-12 19:59:32 +02:00
Yuri Kuznetsov
8be1af0671 orm: all/any operators 2023-03-12 17:17:43 +02:00
Yuri Kuznetsov
58ac0800f9 ref 2023-03-12 16:38:22 +02:00
Yuri Kuznetsov
2acac3d0b0 type 2023-03-11 22:46:01 +02:00
Yuri Kuznetsov
5e44fc2d40 Merge branch 'fix' 2023-03-10 18:26:02 +02:00
Yuri Kuznetsov
2b08f83ac2 fix email plain text encoding issue 2023-03-10 18:25:44 +02:00
Yuri Kuznetsov
cc1bfce3dd fix email plain text encoding issue 2023-03-10 18:24:08 +02:00
Yuri Kuznetsov
08647b3ed6 ref 2023-03-10 17:31:41 +02:00
Yuri Kuznetsov
b97f4ee124 cleanup 2023-03-10 17:20:44 +02:00
Yuri Kuznetsov
d4e73f500f ref 2023-03-10 17:20:32 +02:00
Yuri Kuznetsov
5e13e6cf99 ref 2023-03-10 14:32:40 +02:00
Yuri Kuznetsov
3fd06a89f1 fix 2023-03-10 14:12:25 +02:00
Yuri Kuznetsov
6678500d1b cleanup 2023-03-10 13:47:23 +02:00
Yuri Kuznetsov
1a6f236dc7 fix route cache file 2023-03-10 13:39:57 +02:00
Yuri Kuznetsov
f57a95349a bind client manager 2023-03-10 13:10:10 +02:00
Yuri Kuznetsov
b3496268e0 orm: where clause value as expression 2023-03-10 12:47:11 +02:00
Yuri Kuznetsov
fa38ece181 ref 2023-03-10 12:33:19 +02:00
Yuri Kuznetsov
5866f02eca orm: row constructor 2023-03-10 12:22:11 +02:00
Yuri Kuznetsov
6edce56ca7 orm: comparison sub-query 2023-03-10 12:03:46 +02:00
Yuri Kuznetsov
3dc239acc5 ref 2023-03-10 11:30:59 +02:00
Yuri Kuznetsov
385c70845a test 2023-03-10 11:03:02 +02:00
Yuri Kuznetsov
4f65a46434 orm where clause subquery as instance 2023-03-10 10:41:04 +02:00
Yuri Kuznetsov
a9c4689500 cs 2023-03-09 20:42:30 +02:00
Yuri Kuznetsov
75b544a995 cs ref 2023-03-09 19:53:56 +02:00
Yuri Kuznetsov
451d5e5659 cleanup 2023-03-09 19:12:58 +02:00
Yuri Kuznetsov
134f5862dd ref 2023-03-09 19:12:33 +02:00
Yuri Kuznetsov
b59279ab16 cs 2023-03-09 15:50:17 +02:00
Yuri Kuznetsov
0621c8aefc email to task: subject in description 2023-03-09 15:37:18 +02:00
Yuri Kuznetsov
3229ba1043 foreign field helper 2023-03-09 13:35:16 +02:00
Yuri Kuznetsov
06868b8b57 Merge branch 'fix' 2023-03-09 12:05:40 +02:00
Yuri Kuznetsov
fce1d49407 v 2023-03-09 11:59:30 +02:00
Yuri Kuznetsov
8c2cf02891 cs 2023-03-09 11:59:29 +02:00
Yuri Kuznetsov
ccdafc67b5 ref 2023-03-09 11:59:29 +02:00
Yuri Kuznetsov
b6a470c52e ref 2023-03-09 11:59:29 +02:00
Yuri Kuznetsov
76c63bede4 field view skip re-render in edit mode 2023-03-09 11:59:29 +02:00
dependabot[bot]
2bebe4b045 Bump phpseclib/phpseclib from 3.0.16 to 3.0.19 (#2655)
Bumps [phpseclib/phpseclib](https://github.com/phpseclib/phpseclib) from 3.0.16 to 3.0.19.
- [Release notes](https://github.com/phpseclib/phpseclib/releases)
- [Changelog](https://github.com/phpseclib/phpseclib/blob/master/CHANGELOG.md)
- [Commits](https://github.com/phpseclib/phpseclib/compare/3.0.16...3.0.19)

---
updated-dependencies:
- dependency-name: phpseclib/phpseclib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-09 10:04:41 +02:00
Yuri Kuznetsov
9ee1b41b52 import phone number starts with + fix 2023-03-09 09:12:12 +02:00
Yuri Kuznetsov
f18a3043eb open spout export sanitize 2023-03-09 09:12:12 +02:00
Yuri Kuznetsov
01d5f1a07f global search check name exists 2023-03-09 09:12:12 +02:00
Yuri Kuznetsov
06b31d537f note no globals search 2023-03-09 09:12:12 +02:00
David
989a04dddf fix inline edit close (#2653)
Co-authored-by: David Moškoř <david.moskor@apertia.cz>
2023-03-09 09:11:18 +02:00
Yuri Kuznetsov
055e968660 match exctract 2023-03-08 11:16:28 +02:00
Yuri Kuznetsov
585512773d formula record delete 2023-03-08 10:32:30 +02:00
Yuri Kuznetsov
71f4abeb97 formula test fix 2023-03-08 10:19:55 +02:00
Yuri Kuznetsov
4f973e057e only middle join test 2023-03-08 10:03:15 +02:00
Yuri Kuznetsov
416bf152f0 prevent thousand separator null 2023-03-08 09:30:28 +02:00
Yuri Kuznetsov
3f473617c0 cs 2023-03-08 09:30:28 +02:00
IgorA100
56766e2246 Localization of email templates (ru_RU ) (#2649)
* Create body.tpl

* Create subject.tpl

* Create subject.tpl

* Create body.tpl

* Update body.tpl

* Create subject.tpl

* Create body.tpl

* Create body.tpl

* Create subject.tpl

* Update body.tpl

* Update body.tpl

* Create body.tpl

* Create subject.tpl
2023-03-07 18:56:01 +02:00
Yuri Kuznetsov
a92e44bd6c fix msg 2023-03-07 18:53:17 +02:00
Yuri Kuznetsov
369f3ba9a5 switch complex expr 2023-03-07 18:52:49 +02:00
Yuri Kuznetsov
2d62c902cb Merge branch 'fix' 2023-03-07 17:26:01 +02:00
Yuri Kuznetsov
5985b6d93f fix meeting/call set held 2023-03-07 17:09:36 +02:00
Yuri Kuznetsov
587bda5c73 cs 2023-03-07 17:09:36 +02:00
Yuri Kuznetsov
230a9aced0 ref 2023-03-07 17:09:36 +02:00
IgorA100
023b0ea892 Trying to localize Email templates (#2647)
* Create body.tpl

* Create subject.tpl

* Create subject.tpl

* Create body.tpl

* Update body.tpl
2023-03-07 17:09:16 +02:00
Yuri Kuznetsov
0afd5e1d73 inline-edit-close reset attributes before re-rendering 2023-03-07 14:12:30 +02:00
Yuri Kuznetsov
f824d8eaf5 rebuild config metadata support default 2023-03-07 10:19:51 +02:00
Yuri Kuznetsov
abab4e2061 fix entityTeam name 2023-03-07 09:58:52 +02:00
Eymen Elkum
36c6883743 Fix formatter enum translation (#2642)
* email template formatter consider enum translation

* htmlizer default value for enum translation & rename variable

---------

Co-authored-by: Eymen Elkum <eymen@eblasoft.com.tr>
2023-03-07 09:58:36 +02:00
Yuri Kuznetsov
9c44f79b4d Merge branch 'fix' 2023-03-07 09:35:10 +02:00
Yuri Kuznetsov
6afd616e42 change poeditor link 2023-03-06 15:22:14 +02:00
Yuri Kuznetsov
7aabbc5d28 fix query composer in array issue 2023-03-06 10:05:55 +02:00
Yuri Kuznetsov
9589b0b70a portal url not sortable 2023-03-06 09:59:48 +02:00
Yuri Kuznetsov
8822104227 contrinuting 2023-03-05 20:23:03 +02:00
Yuri Kuznetsov
e34e6b5d9a test 2023-03-05 18:14:11 +02:00
Yuri Kuznetsov
6341492965 ref 2023-03-05 17:25:23 +02:00
Yuri Kuznetsov
aeece9acda authlogdisabled 2023-03-05 17:09:16 +02:00
Yuri Kuznetsov
f5823d04dd fix 2023-03-05 17:07:29 +02:00
Yuri Kuznetsov
28df6738e2 cs fix 2023-03-05 16:45:38 +02:00
Yuri Kuznetsov
0e371ebe04 discard applierClassNameMap 2023-03-05 16:37:39 +02:00
Yuri Kuznetsov
6fe4034237 readme fix 2023-03-05 14:15:21 +02:00
Yuri Kuznetsov
48c3ea5f13 ref 2023-03-04 19:43:13 +02:00
Anthony Andriano
da5b1cf005 bug fix: tcpdf total page numbers for groups (#2632)
The total page number was not correct for groups. The page number for a non-group was used, which produced the wrong result.
2023-03-04 19:42:58 +02:00
Yuri Kuznetsov
2655f0d9c5 ref 2023-03-04 10:59:39 +02:00
Yuri Kuznetsov
e11e3d6168 cleanup 2023-03-04 10:34:09 +02:00
Eymen Elkum
90806c0e82 pdf consider enum translation param (#2631) 2023-03-04 09:54:08 +02:00
Yuri Kuznetsov
ca9f25636b ref 2023-03-03 17:33:51 +02:00
Yuri Kuznetsov
abcc290a7c pg encoding 2023-03-03 15:09:00 +02:00
Yuri Kuznetsov
091b64dd3d ref 2023-03-03 14:41:11 +02:00
Yuri Kuznetsov
8fd8434d68 ref 2023-03-03 11:56:30 +02:00
Yuri Kuznetsov
9ef5c0bc1b fix test 2023-03-03 10:43:15 +02:00
Yuri Kuznetsov
8adfb80558 orm defs try get methods 2023-03-03 10:42:41 +02:00
Yuri Kuznetsov
5ccbf49773 fix link check attachments 2023-03-03 10:27:43 +02:00
Yuri Kuznetsov
e2cde84447 ref 2023-03-03 10:19:32 +02:00
Yuri Kuznetsov
26e7f3dfd2 type ref 2023-03-03 10:07:04 +02:00
Yuri Kuznetsov
6a75b28f8c test fix 2023-03-03 09:56:46 +02:00
Yuri Kuznetsov
e8b6db20a2 orm discard aggregation 2023-03-03 09:55:15 +02:00
Yuri Kuznetsov
9e37739197 Merge branch 'fix' 2023-03-02 15:19:03 +02:00
Yuri Kuznetsov
aae918886f authApiUserLogDisabled 2023-03-02 14:38:39 +02:00
Yuri Kuznetsov
cbf0a82c52 config param system 2023-03-02 14:24:31 +02:00
Yuri Kuznetsov
fb7683e35b ref 2023-03-02 14:15:13 +02:00
Yuri Kuznetsov
105bb8a80f cs 2023-03-02 13:13:20 +02:00
Yuri Kuznetsov
eab0596c33 orm executor ref 2023-03-02 13:11:28 +02:00
Yuri Kuznetsov
7e84278cef ref 2023-03-02 12:47:13 +02:00
Yuri Kuznetsov
f2a27c024f ref 2023-03-02 12:32:53 +02:00
Yuri Kuznetsov
1b76097311 sql log 2023-03-02 10:21:16 +02:00
Yuri Kuznetsov
ae23f58bf5 ref 2023-03-02 09:19:30 +02:00
Yuri Kuznetsov
f3bf7d93c1 pg action user 2023-03-01 13:58:34 +02:00
Yuri Kuznetsov
656ff76a8d lock alias mysql 2023-03-01 13:04:50 +02:00
Yuri Kuznetsov
c72bcc365a pg fix week 2023-03-01 10:58:49 +02:00
Yuri Kuznetsov
f58687ad6b pg fix quarter fiscal 2023-03-01 10:24:46 +02:00
Yuri Kuznetsov
aefe547ef8 has many bc 2023-03-01 09:55:28 +02:00
Yuri Kuznetsov
3619696b12 fix 2023-02-28 19:06:15 +02:00
Yuri Kuznetsov
40d0ad5d08 remove scheduled job service 2023-02-28 19:01:12 +02:00
Yuri Kuznetsov
c9d3a3f967 install ref 2023-02-28 18:00:47 +02:00
Yuri Kuznetsov
0b1f7d1548 tester changes 2023-02-28 16:34:16 +02:00
Yuri Kuznetsov
59cee9a2ee pg integration tests action 2023-02-28 15:57:23 +02:00
Yuri Kuznetsov
e7373ab817 mass action encode serialized data 2023-02-28 14:03:18 +02:00
Yuri Kuznetsov
9570a28066 exclude test 2023-02-28 13:37:19 +02:00
Yuri Kuznetsov
b3f7242bae integratino test platform env 2023-02-28 12:44:18 +02:00
Yuri Kuznetsov
823d371e9d integration-pg test suite 2023-02-28 12:28:17 +02:00
Yuri Kuznetsov
2399d21829 PostgreSQL (#2599)
* dev

* postgres update set

* position in list

* discard charset

* binary => blob

* rollback transaction

* insert on conflict

* fix POSITION_IN_LIST

* TIMESTAMPDIFF

* functions

* functions

* set UTC time zone

* functions and operators

* function

* fulltext

* fix details provider

* full text config usage

* fix param

* full text index rebuild

* full text and round fix

* add uuid db type

* if function

* tests

* delete with joins order limit

* update

* alias max length
2023-02-28 12:12:21 +02:00
Yuri Kuznetsov
01d5091aa3 integration test fix 2023-02-28 12:00:07 +02:00
Yuri Kuznetsov
ed867d1b95 array validation max item length rename 2023-02-28 10:37:06 +02:00
Yuri Kuznetsov
3392c843e6 fix case hook 2023-02-28 09:01:05 +02:00
Yuri Kuznetsov
1e29280a1d fix 2023-02-27 18:02:26 +02:00
Yuri Kuznetsov
aeecd1f3a6 ref 2023-02-27 16:20:57 +02:00
Yuri Kuznetsov
5ecce30720 fix test 2023-02-27 16:11:32 +02:00
Yuri Kuznetsov
c02f87d1c0 integration test quote identifier and ref 2023-02-27 16:07:48 +02:00
Yuri Kuznetsov
929dce6b2e integration tests do not use full-reset 2023-02-27 15:00:20 +02:00
Yuri Kuznetsov
c82d35af27 integration test ref 2023-02-27 14:13:01 +02:00
Yuri Kuznetsov
a0a0b22d2f bind file manager 2023-02-27 10:46:41 +02:00
Yuri Kuznetsov
db3af5749c bind config 2023-02-27 10:20:41 +02:00
Yuri Kuznetsov
f1e13f4b95 change inspections 2023-02-27 09:48:41 +02:00
Yuri Kuznetsov
9f43a0ff89 docs 2023-02-26 20:46:56 +02:00
Yuri Kuznetsov
17bc8a6137 ref 2023-02-24 16:22:23 +02:00
Yuri Kuznetsov
66b06b8baa ref 2023-02-24 15:59:45 +02:00
Yuri Kuznetsov
1d6745396d ref 2023-02-24 15:30:26 +02:00
Yuri Kuznetsov
4f53038578 ref 2023-02-24 15:25:59 +02:00
Yuri Kuznetsov
79f5a7a94b expression renamings 2023-02-24 15:17:11 +02:00
Yuri Kuznetsov
77a433445b fix label 2023-02-24 14:03:36 +02:00
Yuri Kuznetsov
be54198265 phone email invalid on list view 2023-02-24 13:49:31 +02:00
Yuri Kuznetsov
7da892ba98 fix 2023-02-24 13:33:49 +02:00
Yuri Kuznetsov
7b2526430a email address phone number tools 2023-02-24 13:30:25 +02:00
Yuri Kuznetsov
e416dac56f fix validation 2023-02-24 12:14:41 +02:00
Yuri Kuznetsov
d11f0f4f1b delete relationships on import revert 2023-02-24 11:40:23 +02:00
Yuri Kuznetsov
f72fbed6e1 relation defs getConditions 2023-02-24 11:18:15 +02:00
Yuri Kuznetsov
56fe4e2ef7 cs 2023-02-24 11:00:03 +02:00
Yuri Kuznetsov
684a995e17 fix doc type 2023-02-24 10:54:38 +02:00
Yuri Kuznetsov
2f03572df8 orm alias max length prop 2023-02-24 09:25:10 +02:00
Yuri Kuznetsov
5bb0222abd Merge branch 'fix' 2023-02-24 09:15:00 +02:00
Yuri Kuznetsov
29fd164023 ref cs 2023-02-23 16:17:02 +02:00
Yuri Kuznetsov
c52fedcf07 ref 2023-02-23 16:11:11 +02:00
Yuri Kuznetsov
68b12ff848 ref 2023-02-23 14:32:21 +02:00
Yuri Kuznetsov
a351af06a1 ref 2023-02-23 14:05:28 +02:00
Yuri Kuznetsov
72c502b492 cs 2023-02-23 13:45:47 +02:00
Yuri Kuznetsov
1047d243a2 ref 2023-02-23 13:44:23 +02:00
Yuri Kuznetsov
5ab129bd9b ref 2023-02-23 13:06:09 +02:00
Yuri Kuznetsov
6e5e940b30 cs 2023-02-23 12:54:51 +02:00
Yuri Kuznetsov
fa577a4fa9 ref 2023-02-23 12:40:41 +02:00
Yuri Kuznetsov
64f2c59134 list with categories fallback css fix 2023-02-23 10:18:08 +02:00
Yuri Kuznetsov
a82408a06f fix message 2023-02-23 09:38:56 +02:00
Yuri Kuznetsov
b80d8830ba create admin user command 2023-02-22 18:01:49 +02:00
Yuri Kuznetsov
edcdf3c8be fixes 2023-02-22 18:01:41 +02:00
Yuri Kuznetsov
ae27f360ca command io readSecretLine 2023-02-22 17:40:41 +02:00
Yuri Kuznetsov
474759ab6e cs 2023-02-22 17:28:45 +02:00
Yuri Kuznetsov
02ea7cc041 logger ignore empty context 2023-02-22 17:09:02 +02:00
Yuri Kuznetsov
0a67950913 ref 2023-02-22 17:02:07 +02:00
Yuri Kuznetsov
4ef66b1601 fix link conflict 2023-02-22 14:34:50 +02:00
Yuri Kuznetsov
33220d607a phpdocs 2023-02-22 13:25:30 +02:00
Yuri Kuznetsov
ac9f80312d container get by class 2023-02-22 12:37:30 +02:00
Yuri Kuznetsov
0db2ee0a8d ref cs 2023-02-22 12:13:47 +02:00
Yuri Kuznetsov
7d4ab54505 greatest/least expression 2023-02-22 11:51:10 +02:00
Yuri Kuznetsov
a06bfde766 fix link quick search 2023-02-22 10:57:53 +02:00
Yuri Kuznetsov
46f333fced entityDefs modifier 2023-02-22 10:51:20 +02:00
Yuri Kuznetsov
f9294c652d settings skip rebuild 2023-02-21 19:05:38 +02:00
Yuri Kuznetsov
a22dc4b2fb languageAclDisabled moved to scopes 2023-02-21 19:01:05 +02:00
Yuri Kuznetsov
b293086482 cleanup 2023-02-21 18:57:43 +02:00
Yuri Kuznetsov
93139cb3ef preferences id fix 2023-02-21 18:56:22 +02:00
Yuri Kuznetsov
1db70eeaa8 entity acl changes 2023-02-21 18:56:07 +02:00
Yuri Kuznetsov
8ccda3fd2d currency db type string 2023-02-21 17:18:24 +02:00
Yuri Kuznetsov
60eb9008f7 mail merge endpoint 2023-02-21 14:14:14 +02:00
Yuri Kuznetsov
635fa8b893 activities endpoints 2023-02-21 14:00:09 +02:00
Yuri Kuznetsov
183603e09a forbid layout link name 2023-02-21 13:14:55 +02:00
Yuri Kuznetsov
3399b2cc01 email template api endpoint 2023-02-21 13:12:45 +02:00
Yuri Kuznetsov
9d4d441ec2 import api entrypoints 2023-02-21 12:56:36 +02:00
Yuri Kuznetsov
51bda2f5d2 cleanup 2023-02-21 11:32:45 +02:00
Yuri Kuznetsov
92e62c7760 orm greatest least functions 2023-02-21 11:07:58 +02:00
Yuri Kuznetsov
7bb204a432 authAnotherUserDisabled admin readOnly 2023-02-21 08:38:03 +02:00
Yuri Kuznetsov
39939191e5 fix portal starter 2023-02-20 18:17:12 +02:00
Yuri Kuznetsov
aa43f29615 add line 2023-02-20 18:12:09 +02:00
Yuri Kuznetsov
f109131d38 route cache check use cache 2023-02-20 18:11:15 +02:00
Yuri Kuznetsov
a6fb0bbded slim route cache 2023-02-20 17:45:07 +02:00
Yuri Kuznetsov
9b808908b6 user api entry points routes 2023-02-20 17:19:10 +02:00
Eymen Elkum
0691a3cdda trTag helper put attributes part (#2615) 2023-02-20 14:31:50 +02:00
Yuri Kuznetsov
7208a4f88c cs fix 2023-02-20 14:27:31 +02:00
Yuri Kuznetsov
7d37006450 email address api action, global search endpoint fix 2023-02-20 14:22:53 +02:00
Yuri Kuznetsov
73f1e425ca fix tests 2023-02-20 13:44:36 +02:00
Yuri Kuznetsov
2336ae74da entity manager tool conflict with routes check 2023-02-20 12:56:10 +02:00
Yuri Kuznetsov
4419d0827a global search api endpoint change 2023-02-20 12:33:31 +02:00
Yuri Kuznetsov
0d1bc90848 api endpoints 2023-02-20 12:01:46 +02:00
Yuri Kuznetsov
7665010bff ref 2023-02-20 09:30:31 +02:00
Yuri Kuznetsov
5ba16b4c27 record id type 2023-02-19 16:47:09 +02:00
Yuri Kuznetsov
cbf6b0cc6b ref 2023-02-19 13:30:28 +02:00
Yuri Kuznetsov
c51a51e110 api apply response headers added by auth 2023-02-19 13:30:21 +02:00
Yuri Kuznetsov
b59ff42ac2 ref 2023-02-19 12:58:37 +02:00
Yuri Kuznetsov
b635018949 ref 2023-02-19 12:26:21 +02:00
Yuri Kuznetsov
fcb2a0b7a5 ref 2023-02-19 11:49:22 +02:00
Yuri Kuznetsov
2048f3fa10 ref 2023-02-19 08:46:15 +02:00
Yuri Kuznetsov
0fe7fb032f phpdoc fix 2023-02-19 08:44:06 +02:00
Yuri Kuznetsov
bb24b576e0 cs 2023-02-19 08:42:53 +02:00
Yuri Kuznetsov
2a7a12f58c cs 2023-02-18 22:49:43 +02:00
Yuri Kuznetsov
5ccb081af5 cs and fix class hint 2023-02-18 22:29:34 +02:00
Yuri Kuznetsov
ddcb5ccbf9 ref 2023-02-18 14:54:24 +02:00
Yuri Kuznetsov
5b8dc4e629 fix doc 2023-02-18 12:06:47 +02:00
Yuri Kuznetsov
1032b73b85 api response preparing 2023-02-18 11:42:04 +02:00
Yuri Kuznetsov
e7b914ff4b ref 2023-02-18 11:37:41 +02:00
Yuri Kuznetsov
30e94f25e6 action middlewares 2023-02-18 09:22:30 +02:00
Yuri Kuznetsov
7fa7fe63f8 api action return response 2023-02-17 21:42:32 +02:00
Yuri Kuznetsov
716a5b86ff rensponse methods 2023-02-17 21:21:27 +02:00
Yuri Kuznetsov
a29ce1a873 cleanup 2023-02-17 21:06:16 +02:00
Yuri Kuznetsov
ace2dc802a api action 2023-02-17 20:34:29 +02:00
Yuri Kuznetsov
1018bfd4d4 cs 2023-02-17 18:16:57 +02:00
Yuri Kuznetsov
cc828661da cs 2023-02-17 17:44:29 +02:00
Yuri Kuznetsov
4c265dbae1 cs 2023-02-17 17:32:17 +02:00
Yuri Kuznetsov
2615869691 cs 2023-02-17 17:13:42 +02:00
Yuri Kuznetsov
fbbb7c99c0 cs 2023-02-17 16:38:13 +02:00
Yuri Kuznetsov
da7fc9d6a0 cs 2023-02-17 16:28:31 +02:00
Yuri Kuznetsov
9b63470e9a email from autocomplete fix 2023-02-17 16:12:00 +02:00
Yuri Kuznetsov
5879a57cd1 cleanup 2023-02-17 15:47:41 +02:00
Yuri Kuznetsov
702b3f4e2b cs ref 2023-02-17 15:46:44 +02:00
Yuri Kuznetsov
75749efacb formula func interface 2023-02-17 14:01:06 +02:00
Yuri Kuznetsov
854f6c6390 fix 2023-02-17 13:00:22 +02:00
Yuri Kuznetsov
717c21e91b cs 2023-02-17 11:50:53 +02:00
Yuri Kuznetsov
07f1100ccc fix install alert css 2023-02-17 11:40:20 +02:00
Yuri Kuznetsov
3157bb4fcf set read only config params 2023-02-17 10:43:18 +02:00
Yuri Kuznetsov
a3a35be818 cleanup 2023-02-17 10:41:32 +02:00
Yuri Kuznetsov
1c1042cd75 stream note unrelate fix 2023-02-17 10:31:41 +02:00
Yuri Kuznetsov
8f8eb4807d cs fix 2023-02-17 10:18:30 +02:00
Yuri Kuznetsov
f97bb82d9e unrelate stream note 2023-02-17 10:05:31 +02:00
Yuri Kuznetsov
62b325c24b cs 2023-02-17 09:38:29 +02:00
Yuri Kuznetsov
4051b83b30 docs 2023-02-17 09:08:34 +02:00
Yuri Kuznetsov
75444b3e0b uuid db type 2023-02-17 08:55:32 +02:00
Yuri Kuznetsov
961a7bd0bf ref 2023-02-16 17:17:02 +02:00
Eymen Elkum
f4b09c0135 fix foreign enum & array with optionPath & translations (#2610)
* fix foreign enum & array with optionPath & translations

* foreign enum & array clone options

---------

Co-authored-by: Eymen Elkum <eymen@eblasoft.com.tr>
2023-02-16 16:49:19 +02:00
Yuri Kuznetsov
d09f83e267 system user id in config 2023-02-16 14:23:01 +02:00
Yuri Kuznetsov
b874cc283f read only config param 2023-02-16 14:19:15 +02:00
Yuri Kuznetsov
b5873c9c1d orm md5 function 2023-02-16 12:51:55 +02:00
Yuri Kuznetsov
89bde00e3b cs 2023-02-16 12:11:57 +02:00
Yuri Kuznetsov
242de1824f exception fix 2023-02-16 12:10:20 +02:00
Yuri Kuznetsov
02d277d045 drop mariadb 10.1 2023-02-16 10:30:07 +02:00
Yuri Kuznetsov
46bd520b52 cs 2023-02-15 17:09:36 +02:00
Yuri Kuznetsov
d9c0f7d055 uuid generator 2023-02-15 17:03:14 +02:00
Yuri Kuznetsov
4a9bd1b54c fix getSet 2023-02-15 16:05:30 +02:00
Yuri Kuznetsov
1626e4b6bf update getSet 2023-02-15 15:27:17 +02:00
Yuri Kuznetsov
c1cfa0483a orm update in not null 2023-02-15 15:15:13 +02:00
Yuri Kuznetsov
c7d5bc8169 fix orm get join 2023-02-15 14:40:15 +02:00
Yuri Kuznetsov
a7c33afd93 cs 2023-02-14 20:37:54 +02:00
Yuri Kuznetsov
f7678abad1 fix 2023-02-14 18:34:54 +02:00
Yuri Kuznetsov
b181624064 ref 2023-02-14 18:34:21 +02:00
Yuri Kuznetsov
8a6c63e12c modified by id fix 2023-02-14 13:28:00 +02:00
Yuri Kuznetsov
aba1881a5c fix docs and cleanup 2023-02-14 13:00:52 +02:00
Yuri Kuznetsov
3350ffc0b7 system user id ref 2023-02-14 12:48:42 +02:00
Yuri Kuznetsov
c498d463e7 merge fix 2023-02-14 10:58:50 +02:00
Yuri Kuznetsov
54bf67e8bd cleanup 2023-02-13 18:16:35 +02:00
Yuri Kuznetsov
59e852a285 install ref 2023-02-13 18:11:13 +02:00
Yuri Kuznetsov
dcbe24746e deprecate SYSTEM_USER_ID const 2023-02-13 17:10:34 +02:00
Yuri Kuznetsov
deb3ee0653 system user id ref 2023-02-13 17:00:06 +02:00
Yuri Kuznetsov
698db9ebd6 ref 2023-02-13 14:52:00 +02:00
Rabii Brahimi
214cf538ad Update select-records.js (#2603)
Add ability to show pagination one select records modal (if pagination enabled).
2023-02-13 14:16:46 +02:00
Yuri Kuznetsov
f578fd4af9 external account, integration id db type string 2023-02-13 13:46:49 +02:00
Yuri Kuznetsov
57c011ee94 fix test 2023-02-13 13:43:07 +02:00
Yuri Kuznetsov
e4285d1d2a ref 2023-02-13 13:28:06 +02:00
Yuri Kuznetsov
5f4643d725 docs 2023-02-13 12:03:02 +02:00
Yuri Kuznetsov
fcc13ef10c skip text search for email address if whitespaces 2023-02-13 10:14:43 +02:00
Yuri Kuznetsov
826c1734a2 fix test 2023-02-13 10:01:07 +02:00
Yuri Kuznetsov
849ddadb8c cs fix 2023-02-13 09:59:21 +02:00
Yuri Kuznetsov
3e4bd12a76 fulltext boolean expression 2023-02-13 09:48:47 +02:00
Yuri Kuznetsov
e6aae5f4ed schema manager creation change 2023-02-12 19:00:19 +02:00
Yuri Kuznetsov
d8bd2f451f orm refactor match expr 2023-02-12 15:13:43 +02:00
Yuri Kuznetsov
9c47341fc1 test fix 2023-02-12 11:40:52 +02:00
Yuri Kuznetsov
bbea0c0215 filters improvements 2023-02-12 11:34:55 +02:00
Yuri Kuznetsov
4e4e29e0f1 fix 2023-02-11 23:23:18 +02:00
Yuri Kuznetsov
4658eb800e join only middle, filters change 2023-02-11 23:18:06 +02:00
Yuri Kuznetsov
16a313f659 orm exists operator 2023-02-11 20:04:54 +02:00
Yuri Kuznetsov
c2fcd8d86c ref 2023-02-11 16:11:04 +02:00
Yuri Kuznetsov
8666a3977a orm operator key fix 2023-02-11 12:05:01 +02:00
Yuri Kuznetsov
fa06a437e5 fix test 2023-02-10 14:40:51 +02:00
Yuri Kuznetsov
0dcea2ad5b fix additionalSelect alias not string 2023-02-10 14:39:51 +02:00
Yuri Kuznetsov
5a3142b252 fix foreign select join value bool 2023-02-10 14:32:57 +02:00
Yuri Kuznetsov
4598b58fbb schema diff modifier handle dropped sequences 2023-02-10 13:23:53 +02:00
Yuri Kuznetsov
7ff9d85a11 id length 17 2023-02-09 18:38:00 +02:00
Yuri Kuznetsov
89b912ee73 fix some foreign id fields and max-length 2023-02-09 16:24:02 +02:00
Yuri Kuznetsov
a4f75f1423 person name name not storable 2023-02-09 13:13:52 +02:00
Yuri Kuznetsov
03a69cb364 ORM use COALESCE 2023-02-09 13:01:01 +02:00
Yuri Kuznetsov
e7fa98dc09 lock table ref 2023-02-09 12:55:47 +02:00
Yuri Kuznetsov
5eb49d6c3d fix test 2023-02-09 12:51:28 +02:00
Yuri Kuznetsov
1d84aad483 fix bool 0 where clause 2023-02-09 12:47:25 +02:00
Yuri Kuznetsov
af847a8fe7 fix test 2023-02-08 13:40:36 +02:00
dependabot[bot]
08a6a2c66b Bump dompdf/dompdf from 2.0.2 to 2.0.3 (#2597)
Bumps [dompdf/dompdf](https://github.com/dompdf/dompdf) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/dompdf/dompdf/releases)
- [Commits](https://github.com/dompdf/dompdf/compare/v2.0.2...v2.0.3)

---
updated-dependencies:
- dependency-name: dompdf/dompdf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-07 20:20:42 +02:00
Yuri Kuznetsov
0a4a3938fb foreign id usage 2023-02-07 18:39:07 +02:00
Yuri Kuznetsov
0bc05b4a6d subscription bigint 2023-02-07 17:37:42 +02:00
Yuri Kuznetsov
b7ad2dd760 docs and ref 2023-02-07 16:17:04 +02:00
Yuri Kuznetsov
363842aff2 integration entity id max length 2023-02-07 15:29:53 +02:00
Yuri Kuznetsov
ac889dea91 currency column length 3 2023-02-07 12:19:04 +02:00
Yuri Kuznetsov
89e31795cc mass update link test 2023-02-07 11:41:04 +02:00
Yuri Kuznetsov
9953ea8419 link check integration test 2023-02-07 11:20:54 +02:00
Yuri Kuznetsov
1ae1f07de2 merge fix 2023-02-07 10:23:21 +02:00
Yuri Kuznetsov
6fcd0e155d record link check 2023-02-06 22:58:02 +02:00
Yuri Kuznetsov
3e945b7fd8 ref 2023-02-06 21:32:43 +02:00
Yuri Kuznetsov
99464c5210 comment 2023-02-06 16:54:41 +02:00
Yuri Kuznetsov
64c9fbf4f8 fix tests 2023-02-06 16:15:00 +02:00
Yuri Kuznetsov
029d09e689 access link check 2023-02-06 15:24:25 +02:00
Yuri Kuznetsov
be27fc45ee link multiple access check 2023-02-06 10:44:04 +02:00
Yuri Kuznetsov
0eefc5d75d ref 2023-02-06 09:50:25 +02:00
Yuri Kuznetsov
876817ffe9 acl link checker 2023-02-06 09:43:59 +02:00
Yuri Kuznetsov
f6b3e33e7e ref 2023-02-05 19:46:01 +02:00
Yuri Kuznetsov
24301b22a9 note select optimization 2023-02-05 18:23:59 +02:00
Yuri Kuznetsov
31be2f81ff fix tests 2023-02-05 17:45:25 +02:00
Yuri Kuznetsov
bc435b0729 select optimizations 2023-02-05 17:38:08 +02:00
Yuri Kuznetsov
4cd0961f80 assigned users avatar 2023-02-04 17:29:00 +02:00
Yuri Kuznetsov
70edfbb88b ref 2023-02-04 16:38:01 +02:00
Yuri Kuznetsov
9066a2bf97 rel table id params 2023-02-04 16:19:10 +02:00
Yuri Kuznetsov
b39bffa1f2 record id dbType 2023-02-04 15:51:30 +02:00
Yuri Kuznetsov
c49db089f5 docs 2023-02-04 14:57:19 +02:00
Yuri Kuznetsov
2a110851df column fixed param 2023-02-04 14:56:26 +02:00
Yuri Kuznetsov
3e60103516 fix tests 2023-02-04 14:37:27 +02:00
Yuri Kuznetsov
481b870565 rename 2023-02-04 11:44:01 +02:00
Yuri Kuznetsov
9564d0807a rename 2023-02-04 11:37:00 +02:00
Yuri Kuznetsov
785746c801 ref 2023-02-04 11:34:30 +02:00
Yuri Kuznetsov
a89ac23625 rebuild database hard 2023-02-04 10:38:45 +02:00
Yuri Kuznetsov
adc2cb5a66 field manager reset rebuild 2023-02-04 10:08:19 +02:00
Yuri Kuznetsov
4b5787c0d0 metadata record id length 2023-02-04 09:36:11 +02:00
Yuri Kuznetsov
dcbd2bfa42 fix metadata 2023-02-03 18:31:35 +02:00
Yuri Kuznetsov
147fcb02b6 rename metadata app database 2023-02-03 18:25:07 +02:00
Yuri Kuznetsov
1762096532 orm converter refactoring 2023-02-03 16:00:55 +02:00
Yuri Kuznetsov
d21857075e fix typo 2023-02-02 16:16:36 +02:00
Yuri Kuznetsov
a81759b0f1 dbal ref 2023-02-02 16:12:14 +02:00
Yuri Kuznetsov
99fb897b63 cleanup 2023-02-02 16:12:13 +02:00
dependabot[bot]
f6e7da57f7 Bump dompdf/dompdf from 2.0.1 to 2.0.2 (#2587)
Bumps [dompdf/dompdf](https://github.com/dompdf/dompdf) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/dompdf/dompdf/releases)
- [Commits](https://github.com/dompdf/dompdf/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: dompdf/dompdf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-01 08:39:35 +02:00
David
aa001b4a7f mime type already contains "image/" (#2585)
Co-authored-by: David Moškoř <david.moskor@apertia.cz>
2023-01-30 21:37:04 +02:00
Yuri Kuznetsov
37c3cfc539 cs 2023-01-30 20:39:35 +02:00
Yuri Kuznetsov
da45d958b7 orm field converter 2023-01-30 14:06:45 +02:00
Yuri Kuznetsov
aaf095e32b bool fix 0/1 usagge 2023-01-29 10:04:35 +02:00
Yuri Kuznetsov
282f701b77 fix schema manager proxy 2023-01-28 21:13:37 +02:00
Yuri Kuznetsov
ea8ba18d2e ref 2023-01-28 20:47:11 +02:00
Yuri Kuznetsov
d08e969915 dbal types refactor 2023-01-28 20:25:27 +02:00
Yuri Kuznetsov
5567cc6938 ref 2023-01-28 14:00:03 +02:00
Yuri Kuznetsov
720188822d currency service refactor 2023-01-28 13:46:56 +02:00
Yuri Kuznetsov
48e0e53ab1 ref 2023-01-28 12:49:19 +02:00
Yuri Kuznetsov
03c123d63e grand refactoring of schema and other database related things 2023-01-28 12:45:44 +02:00
Yuri Kuznetsov
7d4ded2480 Merge branch 'fix' 2023-01-28 12:43:11 +02:00
Yuri Kuznetsov
1ce3825338 ref 2023-01-24 12:11:40 +02:00
Yuri Kuznetsov
1fba05dd04 ref 2023-01-24 11:59:55 +02:00
Yuri Kuznetsov
2c9b16a2d5 ref 2023-01-24 11:54:34 +02:00
Yuri Kuznetsov
314b5bcd87 refactor 2023-01-24 11:18:05 +02:00
Yuri Kuznetsov
433af312cf converter ref 2023-01-23 22:41:48 +02:00
Yuri Kuznetsov
30b18cf945 index defs get flags 2023-01-23 21:43:38 +02:00
Yuri Kuznetsov
81b9991e6d fix login as user logout error 2023-01-23 16:07:56 +02:00
Yuri Kuznetsov
84f3830eca login style fix 2023-01-23 15:57:00 +02:00
Yuri Kuznetsov
cb878c70b5 fix 2023-01-23 15:36:54 +02:00
Yuri Kuznetsov
8224eec990 logout wait 2023-01-23 15:31:38 +02:00
Yuri Kuznetsov
d655ee92a2 discard user repo 2023-01-23 15:02:12 +02:00
Yuri Kuznetsov
a8d868e812 oidc portal fix 2023-01-22 20:26:03 +02:00
Yuri Kuznetsov
e5c400214a oidc backchannel logout portal 2023-01-22 20:09:30 +02:00
Yuri Kuznetsov
5be5275eda ref 2023-01-22 20:08:00 +02:00
Yuri Kuznetsov
e61535ee92 cleanup 2023-01-22 19:59:48 +02:00
Yuri Kuznetsov
e0abe23260 oidc ref 2023-01-22 19:58:31 +02:00
Yuri Kuznetsov
8d65a3256b query composer indexHints prop 2023-01-22 17:56:59 +02:00
Yuri Kuznetsov
d82c297b79 query composer order LIST to use POSITION_IN_LIST 2023-01-22 16:12:50 +02:00
Yuri Kuznetsov
f7ed15c507 query composer use quote for true false 2023-01-22 15:50:42 +02:00
Yuri Kuznetsov
37b583d431 query composer add quote column 2023-01-22 15:44:49 +02:00
Yuri Kuznetsov
c3286c7c4a cleanup 2023-01-22 14:18:26 +02:00
Yuri Kuznetsov
740c751d1b add methods to entity manager proxy 2023-01-22 14:15:13 +02:00
Yuri Kuznetsov
7e66f14e16 password change use method provider 2023-01-22 14:08:04 +02:00
Yuri Kuznetsov
c3d0559260 ref 2023-01-22 13:53:00 +02:00
Yuri Kuznetsov
27762e61a6 ref 2023-01-22 13:51:40 +02:00
Yuri Kuznetsov
cdbeab8e47 app service ref and recover password check change 2023-01-22 13:42:11 +02:00
Yuri Kuznetsov
15f337a319 oidc portal 2023-01-22 12:55:39 +02:00
Yuri Kuznetsov
dd0deeb967 Merge branch 'fix' 2023-01-22 12:50:37 +02:00
Yuri Kuznetsov
7d36e685b8 exportCOllection support params 2023-01-18 11:24:38 +02:00
Yuri Kuznetsov
48fa62105f change default font 2023-01-16 17:23:19 +02:00
Yuri Kuznetsov
7e354d560f cleanup 2023-01-16 17:19:39 +02:00
Yuri Kuznetsov
bd1fdaf9d9 change template defaults 2023-01-16 17:18:45 +02:00
Yuri Kuznetsov
ab87cff5bc fix 2023-01-15 17:01:02 +02:00
Yuri Kuznetsov
a5280ec0ac cleanup 2023-01-15 16:59:00 +02:00
Yuri Kuznetsov
6339690e58 dompdf engine 2023-01-15 16:57:45 +02:00
Yuri Kuznetsov
c5ae2800b5 html-container overflow hidden 2023-01-15 16:25:49 +02:00
Yuri Kuznetsov
62501dc20d Merge branch 'fix' 2023-01-15 16:18:00 +02:00
Yuri Kuznetsov
c7b7848e69 gruntfile chang 2023-01-14 10:07:03 +02:00
Yuri Kuznetsov
a3be63c6f1 fix test 2023-01-12 13:03:16 +02:00
Yuri Kuznetsov
52fe2ca1c9 labels 2023-01-12 13:03:16 +02:00
Yuri Kuznetsov
6513513108 fix hide/show remove 2023-01-12 13:03:16 +02:00
Yuri Kuznetsov
442d2c030b fix grouped notifications 2023-01-12 13:03:16 +02:00
Yuri Kuznetsov
391500a1c1 cleanup 2023-01-12 13:03:16 +02:00
Yuri Kuznetsov
f239d2c478 notifications fix 2023-01-12 13:03:16 +02:00
dependabot[bot]
101f8a29a3 Bump json5 from 2.2.0 to 2.2.3 (#2554)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-12 11:27:17 +02:00
Yuri Kuznetsov
dfb846fb7e lower exceptions log levels 2023-01-11 13:37:21 +02:00
Yuri Kuznetsov
ecd6d5a558 Merge branch 'fix' 2023-01-11 13:22:06 +02:00
Yuri Kuznetsov
048d54a7af revert constant usage 2023-01-09 13:07:12 +02:00
Yuri Kuznetsov
5645066d68 Merge branch 'version/7.4' 2023-01-09 12:56:18 +02:00
Yuri Kuznetsov
923ecc883a formula remove while 2023-01-06 12:07:57 +02:00
Yuri Kuznetsov
59a95fa3bc email list view show attachments 2023-01-06 12:03:29 +02:00
Yuri Kuznetsov
4789c3c2ad attachments modal 2023-01-06 11:54:00 +02:00
Yuri Kuznetsov
c149aa8560 import validation explanations 2023-01-06 11:01:34 +02:00
Yuri Kuznetsov
e9f5d99e9b markdown to string 2023-01-06 10:39:45 +02:00
Yuri Kuznetsov
4309dfb57a massRemoveDisabled param 2023-01-05 11:44:08 +02:00
Yuri Kuznetsov
4ad0a22a6a fix 2023-01-05 11:29:15 +02:00
Yuri Kuznetsov
2daff0eabb list view ref 2023-01-05 11:23:50 +02:00
Yuri Kuznetsov
cde59bce55 action handler support not in data 2023-01-05 10:08:12 +02:00
Yuri Kuznetsov
80b9d0dc7b ref 2023-01-05 09:43:28 +02:00
Yuri Kuznetsov
bfdaa4721d mass action list fixes 2023-01-04 13:55:34 +02:00
David
60db5cdc6c global mass actions defs fix (#2549)
Co-authored-by: David Moškoř <david.moskor@apertia.cz>
2023-01-04 13:37:20 +02:00
Yuri Kuznetsov
1a5a9060a6 fix 2023-01-04 12:01:49 +02:00
Yuri Kuznetsov
ddf9dfba47 decimal mark thousand separator options 2023-01-04 11:56:50 +02:00
Yuri Kuznetsov
f93060a5ca autonumeric 2023-01-04 11:38:30 +02:00
Yuri Kuznetsov
7e5b491313 formula: break & continue 2023-01-03 18:44:09 +02:00
Yuri Kuznetsov
b083a11099 use true/false 2023-01-03 17:59:17 +02:00
Taras Machyshyn
63f67e0f66 2023 year 2023-01-03 16:26:52 +02:00
Taras Machyshyn
141c6430c4 Merge master 2023-01-03 16:22:44 +02:00
Yuri Kuznetsov
b872e6960a fix db helper 2023-01-03 15:37:57 +02:00
Yuri Kuznetsov
8ba47b11ec orm quote column 2023-01-03 15:29:56 +02:00
Yuri Kuznetsov
883351eaf3 ref 2023-01-03 10:17:51 +02:00
Yuri Kuznetsov
7976e6d5b5 cs ref 2023-01-03 09:56:04 +02:00
Yuri Kuznetsov
8fcda8c621 ref 2023-01-03 09:43:50 +02:00
Yuri Kuznetsov
c1b2870c91 dbal connection factory 2023-01-03 09:18:20 +02:00
Yuri Kuznetsov
2b4f6239f7 revert 2023-01-02 17:31:06 +02:00
Yuri Kuznetsov
bae0144393 db helper ref 2023-01-02 17:24:08 +02:00
Yuri Kuznetsov
af21cc4400 Merge branch 'master' into version/7.4 2023-01-02 14:51:42 +02:00
Andrew Fontana
f50d7717a9 isSubscribedToWebSocket Typo (#2550)
* Fixed WebSocked typo to WebSocket

* Fixed WebSocked typo to WebSocket
2023-01-02 13:42:36 +02:00
Yuri Kuznetsov
03a79ddefe fix 2023-01-01 14:03:50 +02:00
Yuri Kuznetsov
353246281c currency decimal 2023-01-01 13:50:33 +02:00
Yuri Kuznetsov
747d8220e1 currency changes 2023-01-01 12:20:06 +02:00
Yuri Kuznetsov
b6a1648486 cleanup 2022-12-31 11:03:44 +02:00
Yuri Kuznetsov
e0e168945c cleanup 2022-12-31 10:42:20 +02:00
Yuri Kuznetsov
385d7af1b6 ref 2022-12-31 10:41:36 +02:00
Yuri Kuznetsov
14811a7c1a Merge branch 'master' into version/7.4 2022-12-31 10:10:08 +02:00
Yuri Kuznetsov
c828242359 Merge branch 'master' into version/7.4 2022-12-29 13:04:00 +02:00
Yuri Kuznetsov
c4610c4e24 jsdoc 2022-12-29 12:43:29 +02:00
Yuri Kuznetsov
583ba47e78 fix doc 2022-12-29 12:06:17 +02:00
Yuri Kuznetsov
a9e8d5b2b2 auth error translatable exception message 2022-12-27 14:37:34 +02:00
Yuri Kuznetsov
3c4e33f0c5 fix tests 2022-12-27 14:07:27 +02:00
Yuri Kuznetsov
a0d39be19c middlewares after auth 2022-12-27 13:58:04 +02:00
Yuri Kuznetsov
83ef7b32b5 hook interfaces 2022-12-26 14:18:51 +02:00
Yuri Kuznetsov
f365a38858 bind pdo provider 2022-12-25 20:28:09 +02:00
Yuri Kuznetsov
e6f081c7d1 injectable factory create resolved 2022-12-25 20:22:53 +02:00
Yuri Kuznetsov
f463421a33 psr container 2022-12-25 16:50:49 +02:00
Yuri Kuznetsov
49bb6771f6 pdo factory and dbal ref 2022-12-25 14:07:06 +02:00
Yuri Kuznetsov
28d8fcd31e middleware api 2022-12-25 10:28:51 +02:00
Yuri Kuznetsov
008935f054 fix 2022-12-24 20:44:37 +02:00
Yuri Kuznetsov
7ed90d7bbf Merge branch 'master' into version/7.4 2022-12-24 12:13:18 +02:00
Yuri Kuznetsov
7fdcb41547 hook suppress 2022-12-24 11:39:32 +02:00
Yuri Kuznetsov
7eca082d9f Merge branch 'master' into version/7.4 2022-12-24 11:27:47 +02:00
Yuri Kuznetsov
ab81d0fae6 fix typo 2022-12-21 18:29:00 +02:00
Yuri Kuznetsov
3f84551b50 entity defs fields validatorClassNameMap 2022-12-21 15:27:43 +02:00
Yuri Kuznetsov
0e56c727ff formula new statments and refactoring 2022-12-20 17:24:53 +02:00
Yuri Kuznetsov
c911c0f6e5 Merge branch 'master' into version/7.4 2022-12-20 14:49:50 +02:00
Yuri Kuznetsov
9e424f16d7 Merge branch 'master' into version/7.4 2022-12-18 21:34:06 +02:00
Yuri Kuznetsov
dcf1698dad ref 2022-12-15 19:09:22 +02:00
Yuri Kuznetsov
8b92df3f6a rename 2022-12-15 15:40:17 +02:00
Yuri Kuznetsov
c343a4600f xlsx changes 2022-12-15 15:36:12 +02:00
Yuri Kuznetsov
d196a574fd export with openspout 2022-12-15 15:04:08 +02:00
Yuri Kuznetsov
72b2a456b9 export filter field list 2022-12-15 11:47:21 +02:00
Yuri Kuznetsov
d9d42fd664 export params 2022-12-15 11:37:13 +02:00
Yuri Kuznetsov
a131308e1a export refactor 2022-12-14 12:49:15 +02:00
Yuri Kuznetsov
aff948f0a6 ref 2022-12-14 09:45:28 +02:00
Yuri Kuznetsov
0657d78eb5 move 2022-12-13 15:48:11 +02:00
Yuri Kuznetsov
4807beca0b move 2022-12-13 15:32:07 +02:00
Yuri Kuznetsov
8a26478019 export ref 2022-12-13 15:26:48 +02:00
Yuri Kuznetsov
3a9851c89b refactoring 2022-12-13 14:19:31 +02:00
Yuri Kuznetsov
2824d8cd84 ref 2022-12-12 18:23:56 +02:00
Yuri Kuznetsov
e041238d03 cleanup 2022-12-12 18:11:14 +02:00
Yuri Kuznetsov
df36d33b98 fix 2022-12-12 18:04:38 +02:00
Yuri Kuznetsov
f34ca2fe6b xlsx ref 2022-12-12 17:53:17 +02:00
2253 changed files with 61144 additions and 33286 deletions

View File

@@ -1,17 +1,25 @@
## Pull Requests
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
Before we can merge your pull request, you need to accept our CLA [here](https://github.com/espocrm/cla).
See [Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
It's desirable that one PR solves one specific problem. Do not include code style changes to PRs
(unless the main purpose of the PR is a code style fix).
If you would like to contribute something that is not a small fix, it's reasonable to create an issue first
(a bug report or feature request).
Branches:
* *hotfix/** upcoming maintenance release; fixes should be pushed to this branch;
* *master* develop branch; new features should be pushed to this branch;
* *stable* last stable release.
* *master* the develop branch; new features should be pushed to here;
* *fix* the upcoming maintenance release; small fixes should be pushed to here.
## Issues
When reporting a possible bug please provide detail steps so that we will be able to reproduce the issue. Please try not to use phrases like "very big bug", "huge issue", etc. No need to use exclamation marks as well.
We'd appreciate if you prefer posting issues on weekdays rather than weekends.
Note that we don't provide developer help or any kind of support on Github. Please use our [forum](https://forum.espocrm.com) for this.
When reporting a possible bug, please provide detail steps so that we will be able
to reproduce the issue. Please try not to use phrases like "very big bug",
"huge issue", etc. No need to use exclamation marks as well.
Note that we don't provide developer help or any kind of support on GitHub.
For this, please use our [forum](https://forum.espocrm.com).

View File

@@ -1,6 +1,6 @@
---
name: Bug report
about: Create a bug report
about: Create a bug report. Not to be used for help requests or server configuration issues. We appreciate if you prefer posting bug reports on weekdays rather than weekends.
title: ''
labels: ''
assignees: ''

View File

@@ -1,4 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: EspoCRM forum
url: https://forum.espocrm.com/
about: Please use our forum to ask questions not related to product development
about: "Use our forum for help requests and questions not related to product development. We don't provide support on GitHub."

View File

@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest an idea for EspoCRM
about: Freature requests are frozen til mid-June 2023. Please post on the forum instead. (Suggest an idea for EspoCRM).
title: ''
labels: ''
assignees: ''

2
.github/SECURITY.md vendored
View File

@@ -2,7 +2,7 @@
## Reporting a vulnerability
If you believe you have discovered a vulnerability in EspoCRM please contacts us via [this](https://www.espocrm.com/contacts/) or [this](https://www.espocrm.com/support/) forms.
If you believe you have discovered a vulnerability in EspoCRM, please contacts us via [this](https://www.espocrm.com/contacts/) or [this](https://www.espocrm.com/support/) forms. Or create a private vulnerability report on GitHub.
## Supported versions

View File

@@ -0,0 +1,63 @@
name: Test Integration on PostgreSQL
on:
schedule:
- cron: '0 11 * * *'
jobs:
test:
name: Test on PHP ${{ matrix.php-versions }}
runs-on: ubuntu-20.04
env:
TEST_DATABASE_HOST: '127.0.0.1'
TEST_DATABASE_PLATFORM: 'Postgresql'
TEST_DATABASE_CHARSET: 'utf8'
TEST_DATABASE_PORT: '8888'
TEST_DATABASE_NAME: integration_test
TEST_DATABASE_USER: postgres
TEST_DATABASE_PASSWORD: password
services:
postgres:
image: postgres:15.2
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: integration_test
ports:
- '8888:5432'
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
fail-fast: false
matrix:
php-versions: ['8.2']
branches: ['master']
steps:
- uses: actions/checkout@v2
with:
ref: ${{ matrix.branches }}
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Setup PHP with Composer
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: composer:v2
ini-values: memory_limit=1024M
- name: NPM install
run: npm install
- name: Build
run: grunt test
- name: Integration testing
run: vendor/bin/phpunit --testsuite integration-pg

1
.idea/.gitignore generated vendored
View File

@@ -4,3 +4,4 @@
!/fileTemplates
!/inspectionProfiles
!misc.xml
!jsonSchemas.xml

View File

@@ -6,6 +6,11 @@
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
<option name="FORCE_EMPTY_METHODS_IN_ONE_LINE" value="true" />
</PHPCodeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />

View File

@@ -14,6 +14,8 @@
</inspection_tool>
<inspection_tool class="PhpSwitchStatementWitSingleBranchInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PsalmAdvanceCallableParamsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialIfJS" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

1351
.idea/jsonSchemas.xml generated Normal file

File diff suppressed because it is too large Load Diff

3
.vscode/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*
!.gitignore
!settings.json

422
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,422 @@
{
"json.schemas": [
{
"fileMatch": [
"*/Resources/routes.json"
],
"url": "./schema/routes.json"
},
{
"fileMatch": [
"*/Resources/module.json"
],
"url": "./schema/routes.json"
},
{
"fileMatch": [
"*/Resources/layouts/*/detail.json",
"*/Resources/layouts/*/detailSmall.json",
"*/Resources/layouts/*/detailConvert.json"
],
"url": "./schema/layouts/detail.json"
},
{
"fileMatch": [
"*/Resources/layouts/*/list.json",
"*/Resources/layouts/*/listSmall.json",
"*/Resources/layouts/*/listFor*.json"
],
"url": "./schema/layouts/list.json"
},
{
"fileMatch": [
"*/metadata/aclDefs/*.json"
],
"url": "./schema/metadata/aclDefs.json"
},
{
"fileMatch": [
"*/metadata/authenticationMethods/*.json"
],
"url": "./schema/metadata/authenticationMethods.json"
},
{
"fileMatch": [
"*/metadata/clientDefs/*.json"
],
"url": "./schema/metadata/clientDefs.json"
},
{
"fileMatch": [
"*/metadata/dashlets/*.json"
],
"url": "./schema/metadata/dashlets.json"
},
{
"fileMatch": [
"*/metadata//*.json"
],
"url": "./schema/metadata/.json"
},
{
"fileMatch": [
"*/metadata/entityAcl/*.json"
],
"url": "./schema/metadata/entityAcl.json"
},
{
"fileMatch": [
"*/metadata/entityDefs/*.json"
],
"url": "./schema/metadata/entityDefs.json"
},
{
"fileMatch": [
"*/metadata/fields/*.json"
],
"url": "./schema/metadata/fields.json"
},
{
"fileMatch": [
"*/metadata/integrations/*.json"
],
"url": "./schema/metadata/integrations.json"
},
{
"fileMatch": [
"*/metadata/notificationDefs/*.json"
],
"url": "./schema/metadata/notificationDefs.json"
},
{
"fileMatch": [
"*/metadata/pdfDefs/*.json"
],
"url": "./schema/metadata/pdfDefs.json"
},
{
"fileMatch": [
"*/metadata/recordDefs/*.json"
],
"url": "./schema/metadata/recordDefs.json"
},
{
"fileMatch": [
"*/metadata/scopes/*.json"
],
"url": "./schema/metadata/scopes.json"
},
{
"fileMatch": [
"*/metadata/selectDefs/*.json"
],
"url": "./schema/metadata/selectDefs.json"
},
{
"fileMatch": [
"*/metadata/streamDefs/*.json"
],
"url": "./schema/metadata/streamDefs.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/acl.json"
],
"url": "./schema/metadata/app/acl.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/aclPortal.json"
],
"url": "./schema/metadata/app/aclPortal.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/actions.json"
],
"url": "./schema/metadata/app/actions.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/addressFormats.json"
],
"url": "./schema/metadata/app/addressFormats.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/adminPanel.json"
],
"url": "./schema/metadata/app/adminPanel.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/api.json"
],
"url": "./schema/metadata/app/api.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/appParams.json"
],
"url": "./schema/metadata/app/appParams.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/authentication.json"
],
"url": "./schema/metadata/app/authentication.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/authentication2FAMethods.json"
],
"url": "./schema/metadata/app/authentication2FAMethods.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/cleanup.json"
],
"url": "./schema/metadata/app/cleanup.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/client.json"
],
"url": "./schema/metadata/app/client.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/clientRoutes.json"
],
"url": "./schema/metadata/app/clientRoutes.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/complexExpression.json"
],
"url": "./schema/metadata/app/complexExpression.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/config.json"
],
"url": "./schema/metadata/app/config.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/consoleCommands.json"
],
"url": "./schema/metadata/app/consoleCommands.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/containerServices.json"
],
"url": "./schema/metadata/app/containerServices.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/currency.json"
],
"url": "./schema/metadata/app/currency.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/currencyConversion.json"
],
"url": "./schema/metadata/app/currencyConversion.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/databasePlatforms.json"
],
"url": "./schema/metadata/app/databasePlatforms.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/dateTime.json"
],
"url": "./schema/metadata/app/dateTime.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/defaultDashboardLayouts.json"
],
"url": "./schema/metadata/app/defaultDashboardLayouts.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/defaultDashboardOptions.json"
],
"url": "./schema/metadata/app/defaultDashboardOptions.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/entityManagerParams.json"
],
"url": "./schema/metadata/app/entityManagerParams.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/entityTemplateList.json"
],
"url": "./schema/metadata/app/entityTemplateList.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/export.json"
],
"url": "./schema/metadata/app/export.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/fieldProcessing.json"
],
"url": "./schema/metadata/app/fieldProcessing.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/file.json"
],
"url": "./schema/metadata/app/file.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/fileStorage.json"
],
"url": "./schema/metadata/app/fileStorage.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/formula.json"
],
"url": "./schema/metadata/app/formula.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/hook.json"
],
"url": "./schema/metadata/app/hook.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/image.json"
],
"url": "./schema/metadata/app/image.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/jsLibs.json"
],
"url": "./schema/metadata/app/jsLibs.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/language.json"
],
"url": "./schema/metadata/app/language.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/linkManager.json"
],
"url": "./schema/metadata/app/linkManager.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/massActions.json"
],
"url": "./schema/metadata/app/massActions.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/metadata.json"
],
"url": "./schema/metadata/app/metadata.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/orm.json"
],
"url": "./schema/metadata/app/orm.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/pdfEngines.json"
],
"url": "./schema/metadata/app/pdfEngines.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/popupNotifications.json"
],
"url": "./schema/metadata/app/popupNotifications.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/portalContainerServices.json"
],
"url": "./schema/metadata/app/portalContainerServices.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/rebuild.json"
],
"url": "./schema/metadata/app/rebuild.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/recordId.json"
],
"url": "./schema/metadata/app/recordId.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/regExpPatterns.json"
],
"url": "./schema/metadata/app/regExpPatterns.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/relationships.json"
],
"url": "./schema/metadata/app/relationships.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/scheduledJobs.json"
],
"url": "./schema/metadata/app/scheduledJobs.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/select.json"
],
"url": "./schema/metadata/app/select.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/smsProviders.json"
],
"url": "./schema/metadata/app/smsProviders.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/templateHelpers.json"
],
"url": "./schema/metadata/app/templateHelpers.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/templates.json"
],
"url": "./schema/metadata/app/templates.json"
},
{
"fileMatch": [
"*/Resources/metadata/app/webSocket.json"
],
"url": "./schema/metadata/app/webSocket.json"
}
]
}

View File

@@ -21,10 +21,10 @@
/**
* * `grunt` - full build;
* * `grunt dev` - build only items needed for development (takes less time);
* * `grunt dev` - build for development;
* * `grunt offline` - build but skip *composer install*;
* * `grunt internal` - build only libs and css;
* * `grunt release` - full build plus upgrade packages`;
* * `grunt release` - full build zipped with upgrade packages`;
* * `grunt test` - build for tests running;
* * `grunt run-tests` - build and run unit and integration tests.
*/
@@ -90,7 +90,7 @@ module.exports = grunt => {
mkdir: {
tmp: {
options: {
mode: 0755,
mode: 0o755,
create: [
'build/tmp',
],
@@ -110,9 +110,7 @@ module.exports = grunt => {
beforeFinal: {
src: [
'build/tmp/custom/Espo/Custom/*',
'build/tmp/custom/Espo/Modules/*',
'!build/tmp/custom/Espo/Custom/.htaccess',
'!build/tmp/custom/Espo/Modules/.htaccess',
'build/tmp/install/config.php',
'build/tmp/vendor/*/*/.git',
'build/tmp/custom/Espo/Custom/*',
@@ -236,7 +234,7 @@ module.exports = grunt => {
options: {
patterns: [
{
match: /\# \{\#dev\}(.*)\{\/dev\}/gs,
match: /# \{#dev}(.*)\{\/dev}/gs,
replacement: '',
}
]
@@ -503,7 +501,8 @@ module.exports = grunt => {
grunt.registerTask('dev', [
'composer-install-dev',
'less',
'npm-install',
'internal',
]);
grunt.registerTask('test', [

View File

@@ -2,47 +2,72 @@
[![PHPStan level 8](https://img.shields.io/badge/PHPStan-level%208-brightgreen)](#espocrm)
[EspoCRM is an Open Source CRM](https://www.espocrm.com) (Customer Relationship Management) software that allows you to see, enter and evaluate all your company relationships regardless of the type. People, companies or opportunities all in an easy and intuitive interface.
[EspoCRM is an Open Source CRM](https://www.espocrm.com) (Customer Relationship Management)
software that allows you to see, enter and evaluate all your company relationships regardless
of the type. People, companies or opportunities all in an easy and intuitive interface.
It's a web application with a frontend designed as a single page application and REST API backend written in PHP.
It's a web application with a frontend designed as a single page application and REST API
backend written in PHP.
[Download](https://www.espocrm.com/download/) the latest release from our website.
[Download](https://www.espocrm.com/download/) the latest release from our website. Release notes
and release packages are available at [Releases](https://github.com/espocrm/espocrm/releases) on GitHub.
![Screenshot](https://user-images.githubusercontent.com/1006792/226094559-995dfd2a-a18f-4619-a21b-79a4e671990a.png)
### Demo
You can try the CRM on the online [demo](https://www.espocrm.com/demo/).
### Requirements
* PHP 8.0 and later;
* MySQL 5.7 (and later), or MariaDB 10.1 (and later).
* MySQL 5.7 (and later), or MariaDB 10.2 (and later).
For more information about server configuration see [this article](https://docs.espocrm.com/administration/server-configuration/).
### Documentation
The documentation for administrators, users and developers is available [here](https://docs.espocrm.com).
See the [documentation](https://docs.espocrm.com) for administrators, users and developers.
### Bug reporting
Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our [forum](http://forum.espocrm.com/forum/bug-reports).
Create a [GitHub issue](https://github.com/espocrm/espocrm/issues/new/choose) or post on our [forum](https://forum.espocrm.com/forum/bug-reports).
### Installing the stable version
### Installing stable version
See the [instructions](https://docs.espocrm.com/administration/installation/) about installation.
See installation instructions:
* [Manual installation](https://docs.espocrm.com/administration/installation/)
* [Installation by script](https://docs.espocrm.com/administration/installation-by-script/)
* [Installation with Docker](https://docs.espocrm.com/administration/docker/installation/)
* [Installation with Traefik](https://docs.espocrm.com/administration/docker/traefik/)
### Development
* [Getting started](https://docs.espocrm.com/development/how-to-start)
* [Running tests](https://docs.espocrm.com/development/tests)
* [Making translation](https://docs.espocrm.com/development/translation)
See the [developer documentation](https://docs.espocrm.com/development/).
We highly recommend using IDE for development. The backend codebase follows SOLID principles, utilizes interfaces, static typing and generics. We recommend to start learning EspoCRM from the Dependency Injection article in the documentation.
### Contributing
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
Before we can merge your pull request, you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
Branches:
* *fix* upcoming maintenance release; fixes should be pushed to this branch;
* *fix* upcoming maintenance release; minor fixes should be pushed to this branch;
* *master* develop branch; new features should be pushed to this branch;
* *stable* last stable release.
### Language
If you want to improve existing translation or add a language that is not available yet, you can contribute on our [POEditor](https://poeditor.com/join/project/gLDKZtUF4i) project. See instructions [here](https://www.espocrm.com/blog/how-to-use-poeditor-to-translate-espocrm/).
Changes on POEditor are usually merged to the GitHub repository before minor releases.
### Community & Support
If you have a question regarding some features, need help or customizations, want to get in touch with other EspoCRM users, or add a feature request, please use our [community forum](https://forum.espocrm.com/). We believe that using the forum to ask for help and share experience allows everyone in the community to contribute and use this knowledge later.
### License
EspoCRM is published under the GNU GPLv3 [license](https://raw.githubusercontent.com/espocrm/espocrm/master/LICENSE.txt).

View File

@@ -44,6 +44,7 @@ class Binding implements BindingProcessor
public function process(Binder $binder): void
{
$this->bindServices($binder);
$this->bindCore($binder);
$this->bindMisc($binder);
$this->bindAcl($binder);
$this->bindWebSocket($binder);
@@ -63,7 +64,12 @@ class Binding implements BindingProcessor
);
$binder->bindService(
'Espo\\Core\\Container\\Container',
'Espo\\Core\\Container',
'container'
);
$binder->bindService(
'Psr\\Container\\ContainerInterface',
'container'
);
@@ -72,6 +78,16 @@ class Binding implements BindingProcessor
'module'
);
$binder->bindService(
'Espo\\Core\\Utils\\Config',
'config'
);
$binder->bindService(
'Espo\\Core\\Utils\\File\\Manager',
'fileManager'
);
$binder->bindService(
'Espo\\ORM\\EntityManager',
'entityManager'
@@ -208,8 +224,8 @@ class Binding implements BindingProcessor
);
$binder->bindService(
'Espo\\Core\\Acl',
'acl'
'Espo\\Core\\Utils\\ClientManager',
'clientManager'
);
$binder->bindService(
@@ -218,6 +234,14 @@ class Binding implements BindingProcessor
);
}
private function bindCore(Binder $binder): void
{
$binder->bindImplementation(
'Espo\\ORM\\PDO\\PDOProvider',
'Espo\\ORM\\PDO\\DefaultPDOProvider'
);
}
private function bindMisc(Binder $binder): void
{
$binder->bindImplementation(
@@ -246,7 +270,7 @@ class Binding implements BindingProcessor
->for('Espo\\Core\\Authentication\\Oidc\\Login')
->bindImplementation(
'Espo\\Core\\Authentication\\Oidc\\UserProvider',
'Espo\\Core\\Authentication\\Oidc\\DefaultUserProvider'
'Espo\\Core\\Authentication\\Oidc\\UserProvider\\DefaultUserProvider'
);
$binder->bindImplementation(

View File

@@ -48,17 +48,12 @@ class AccessChecker implements AccessEntityCREDChecker
{
use DefaultAccessCheckerDependency;
private AclManager $aclManager;
private EntityManager $entityManager;
public function __construct(
DefaultAccessChecker $defaultAccessChecker,
AclManager $aclManager,
EntityManager $entityManager
private AclManager $aclManager,
private EntityManager $entityManager
) {
$this->defaultAccessChecker = $defaultAccessChecker;
$this->aclManager = $aclManager;
$this->entityManager = $entityManager;
}
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
@@ -126,8 +121,8 @@ class AccessChecker implements AccessEntityCREDChecker
{
if ($note->getTargetType() === Note::TARGET_TEAMS) {
$intersect = array_intersect(
$note->getLinkMultipleIdList('teams') ?? [],
$user->getLinkMultipleIdList('teams') ?? []
$note->getLinkMultipleIdList('teams'),
$user->getLinkMultipleIdList('teams')
);
if (count($intersect)) {
@@ -150,6 +145,10 @@ class AccessChecker implements AccessEntityCREDChecker
return null;
}
if ($note->getTargetType() === Note::TARGET_ALL) {
return true;
}
if (!$note->getParentId() || !$note->getParentType()) {
return null;
}

View File

@@ -126,7 +126,7 @@ class AccessChecker implements AccessEntityCREDChecker
}
if ($entity->getTargetType() === Note::TARGET_TEAMS) {
$targetTeamIdList = $entity->getLinkMultipleIdList('teams') ?? [];
$targetTeamIdList = $entity->getLinkMultipleIdList('teams');
foreach ($user->getTeamIdList() as $teamId) {
if (in_array($teamId, $targetTeamIdList)) {
@@ -138,7 +138,7 @@ class AccessChecker implements AccessEntityCREDChecker
}
if ($entity->getTargetType() === Note::TARGET_USERS) {
return in_array($user->getId(), $entity->getLinkMultipleIdList('users') ?? []);
return in_array($user->getId(), $entity->getLinkMultipleIdList('users'));
}
return false;

View File

@@ -51,8 +51,8 @@ class OwnershipChecker implements OwnershipOwnChecker, OwnershipTeamChecker
assert($entity instanceof CoreEntity);
$intersect = array_intersect(
$user->getLinkMultipleIdList('teams') ?? [],
$entity->getLinkMultipleIdList('teams') ?? []
$user->getLinkMultipleIdList('teams'),
$entity->getLinkMultipleIdList('teams')
);
if (count($intersect)) {

View File

@@ -131,8 +131,8 @@ class AccessChecker implements AccessEntityCREDChecker
if ($note->getTargetType() === Note::TARGET_PORTALS) {
$intersect = array_intersect(
$note->getLinkMultipleIdList('portals') ?? [],
$user->getLinkMultipleIdList('portals') ?? []
$note->getLinkMultipleIdList('portals'),
$user->getLinkMultipleIdList('portals')
);
if (count($intersect)) {

View File

@@ -118,7 +118,7 @@ class AccessChecker implements AccessEntityCREDChecker
}
if ($entity->getTargetType() === Note::TARGET_PORTALS) {
return in_array($user->getPortalId(), $entity->getLinkMultipleIdList('portals') ?? []);
return in_array($user->getPortalId(), $entity->getLinkMultipleIdList('portals'));
}
return false;

View File

@@ -29,10 +29,8 @@
namespace Espo\Classes\AddressFormatters;
use Espo\Core\{
Field\Address,
Field\Address\AddressFormatter,
};
use Espo\Core\Field\Address;
use Espo\Core\Field\Address\AddressFormatter;
class Formatter1 implements AddressFormatter
{

View File

@@ -29,10 +29,8 @@
namespace Espo\Classes\AddressFormatters;
use Espo\Core\{
Field\Address,
Field\Address\AddressFormatter,
};
use Espo\Core\Field\Address;
use Espo\Core\Field\Address\AddressFormatter;
class Formatter2 implements AddressFormatter
{

View File

@@ -29,10 +29,8 @@
namespace Espo\Classes\AddressFormatters;
use Espo\Core\{
Field\Address,
Field\Address\AddressFormatter,
};
use Espo\Core\Field\Address;
use Espo\Core\Field\Address\AddressFormatter;
class Formatter3 implements AddressFormatter
{

View File

@@ -29,10 +29,8 @@
namespace Espo\Classes\AddressFormatters;
use Espo\Core\{
Field\Address,
Field\Address\AddressFormatter,
};
use Espo\Core\Field\Address;
use Espo\Core\Field\Address\AddressFormatter;
class Formatter4 implements AddressFormatter
{

View File

@@ -29,23 +29,14 @@
namespace Espo\Classes\AppInfo;
use Espo\Core\{
Container as ContainerService,
Utils\Metadata,
Console\Command\Params,
};
use Espo\Core\Console\Command\Params;
use Espo\Core\Container as ContainerService;
use Espo\Core\Utils\Metadata;
class Container
{
private $container;
private $metadata;
public function __construct(ContainerService $container, Metadata $metadata)
{
$this->container = $container;
$this->metadata = $metadata;
}
public function __construct(private ContainerService $container, private Metadata $metadata)
{}
public function process(Params $params): string
{

View File

@@ -0,0 +1,102 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\ConsoleCommands;
use Espo\Core\Console\Command;
use Espo\Core\Console\Command\Params;
use Espo\Core\Console\IO;
use Espo\Core\Utils\Config;
use Espo\Entities\User;
use Espo\ORM\EntityManager;
use RuntimeException;
class CreateAdminUser implements Command
{
public function __construct(
private EntityManager $entityManager,
private Config $config
) {}
public function run(Params $params, IO $io): void
{
$userName = $params->getArgument(0);
if (!$userName) {
$io->writeLine("A username must be specified as the first argument.");
$io->setExitStatus(1);
return;
}
/** @var ?string $regExp */
$regExp = $this->config->get('userNameRegularExpression');
if (!$regExp) {
throw new RuntimeException("No `userNameRegularExpression` in config.");
}
if (
str_contains($userName, ' ') ||
preg_replace("/{$regExp}/", '_', $userName) !== $userName
) {
$io->writeLine("Not allowed username.");
$io->setExitStatus(1);
return;
}
$repository = $this->entityManager->getRDBRepositoryByClass(User::class);
$existingUser = $repository
->where(['userName' => $userName])
->findOne();
if ($existingUser) {
$io->writeLine("A user with the same username already exists.");
$io->setExitStatus(1);
return;
}
$user = $repository->getNew();
$user->set('userName', $userName);
$user->set('type', User::TYPE_ADMIN);
$user->set('name', $userName);
$repository->save($user);
$message = "The user '{$userName}' has been created. " .
"Set password with the command: `bin/command set-password {$userName}`.";
$io->writeLine($message);
}
}

View File

@@ -32,26 +32,16 @@ namespace Espo\Classes\ConsoleCommands;
use Espo\Tools\Import\Service;
use Espo\Core\Utils\File\Manager as FileManager;
use Espo\Core\{
Console\Command,
Console\Command\Params,
Console\IO,
};
use Espo\Core\Console\Command;
use Espo\Core\Console\Command\Params;
use Espo\Core\Console\IO;
use Throwable;
class Import implements Command
{
private Service $service;
private FileManager $fileManager;
public function __construct(Service $service, FileManager $fileManager)
{
$this->service = $service;
$this->fileManager = $fileManager;
}
public function __construct(private Service $service, private FileManager $fileManager)
{}
public function run(Params $params, IO $io) : void
{

View File

@@ -63,7 +63,7 @@ class PopulateNumbers implements Command
$field = $params->getArgument(1);
$orderBy = $params->getOption('orderBy') ?? 'createdAt';
$order = $params->getOption('order') ?? Order::ASC;
$order = strtoupper($params->getOption('order') ?? Order::ASC);
if (!$entityType) {
throw new ArgumentNotSpecified("No entity type argument.");
@@ -73,6 +73,10 @@ class PopulateNumbers implements Command
throw new ArgumentNotSpecified("No field argument.");
}
if ($order !== Order::ASC && $order !== Order::DESC) {
throw new InvalidArgument("Bad order option.");
}
$fieldType = $this->entityManager
->getDefs()
->getEntity($entityType)

View File

@@ -33,22 +33,21 @@ use Espo\Core\Duplicate\WhereBuilder;
use Espo\Core\Field\EmailAddressGroup;
use Espo\Core\ORM\Entity as CoreEntity;
use Espo\ORM\{
Query\Part\Condition as Cond,
Query\Part\WhereItem,
Query\Part\Where\OrGroup,
Entity,
};
use Espo\ORM\Entity;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\ORM\Query\Part\Where\OrGroup;
use Espo\ORM\Query\Part\WhereItem;
/**
* @implements WhereBuilder<CoreEntity>
*/
class Company implements WhereBuilder
{
/**
* @param CoreEntity $entity
*/
public function build(Entity $entity): ?WhereItem
{
assert($entity instanceof CoreEntity);
$orBuilder = OrGroup::createBuilder();
$toCheck = false;

View File

@@ -0,0 +1,54 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\DuplicateWhereBuilders;
use Espo\Core\Duplicate\WhereBuilder;
use Espo\ORM\Entity;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\ORM\Query\Part\WhereItem;
/**
* @implements WhereBuilder<Entity>
*/
class Name implements WhereBuilder
{
public function build(Entity $entity): ?WhereItem
{
if ($entity->get('name')) {
return Cond::equal(
Cond::column('name'),
$entity->get('name')
);
}
return null;
}
}

View File

@@ -31,27 +31,24 @@ namespace Espo\Classes\DuplicateWhereBuilders;
use Espo\Core\ORM\Entity as CoreEntity;
use Espo\Core\{
Duplicate\WhereBuilder,
Field\EmailAddressGroup,
};
use Espo\Core\Duplicate\WhereBuilder;
use Espo\Core\Field\EmailAddressGroup;
use Espo\ORM\{
Query\Part\Condition as Cond,
Query\Part\WhereItem,
Query\Part\Where\OrGroup,
Entity,
};
use Espo\ORM\Entity;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\ORM\Query\Part\Where\OrGroup;
use Espo\ORM\Query\Part\WhereItem;
/**
* @implements WhereBuilder<CoreEntity>
*/
class Person implements WhereBuilder
{
/**
* @param CoreEntity $entity
*/
public function build(Entity $entity): ?WhereItem
{
assert($entity instanceof CoreEntity);
$orBuilder = OrGroup::createBuilder();
$toCheck = false;

View File

@@ -30,31 +30,27 @@
namespace Espo\Classes\FieldProcessing\Email;
use Espo\ORM\Entity;
use Espo\Core\{
FieldProcessing\Loader,
FieldProcessing\Loader\Params,
ORM\EntityManager,
};
use Espo\Core\FieldProcessing\Loader;
use Espo\Core\FieldProcessing\Loader\Params;
use Espo\Core\ORM\EntityManager;
use Espo\Repositories\Email as EmailRepository;
use Espo\Entities\Email;
/**
* @implements Loader<\Espo\Entities\Email>
* @implements Loader<Email>
*/
class AddressDataLoader implements Loader
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function __construct(private EntityManager $entityManager)
{}
/**
* @param Email $entity
*/
public function process(Entity $entity, Params $params): void
{
/** @var EmailRepository $repository */
$repository = $this->entityManager->getRepository('Email');
$repository = $this->entityManager->getRepository(Email::ENTITY_TYPE);
$repository->loadFromField($entity);
$repository->loadToField($entity);

View File

@@ -29,27 +29,21 @@
namespace Espo\Classes\FieldProcessing\Import;
use Espo\Entities\Import;
use Espo\ORM\Entity;
use Espo\Core\{
FieldProcessing\Loader,
FieldProcessing\Loader\Params,
ORM\EntityManager,
};
use Espo\Core\FieldProcessing\Loader;
use Espo\Core\FieldProcessing\Loader\Params;
use Espo\Core\ORM\EntityManager;
use Espo\Repositories\Import as ImportRepository;
/**
* @implements Loader<\Espo\Entities\Import>
* @implements Loader<Import>
*/
class CountsLoader implements Loader
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function __construct(private EntityManager $entityManager)
{}
public function process(Entity $entity, Params $params): void
{

View File

@@ -30,16 +30,12 @@
namespace Espo\Classes\FieldProcessing\Note;
use Espo\ORM\Entity;
use Espo\Core\{
FieldProcessing\Loader,
FieldProcessing\Loader\Params,
};
use Espo\Core\FieldProcessing\Loader;
use Espo\Core\FieldProcessing\Loader\Params;
use Espo\Entities\Note;
/**
* @implements Loader<\Espo\Entities\Note>
* @implements Loader<Note>
*/
class AttachmentsLoader implements Loader
{

View File

@@ -33,19 +33,16 @@ use Espo\ORM\Entity;
use Espo\Repositories\Portal as PortalRepository;
use Espo\Entities\Portal;
use Espo\Core\{
FieldProcessing\Loader,
FieldProcessing\Loader\Params,
ORM\EntityManager,
};
use Espo\Core\FieldProcessing\Loader;
use Espo\Core\FieldProcessing\Loader\Params;
use Espo\Core\ORM\EntityManager;
/**
* @implements Loader<\Espo\Entities\Portal>
* @implements Loader<Portal>
*/
class UrlLoader implements Loader
{
private $entityManager;
private EntityManager $entityManager;
public function __construct(EntityManager $entityManager)
{

View File

@@ -38,17 +38,10 @@ use stdClass;
class ArrayType
{
private Metadata $metadata;
private const DEFAULT_MAX_ITEM_LENGTH = 100;
private Defs $defs;
private const DEFAULT_MAX_LENGTH = 100;
public function __construct(Metadata $metadata, Defs $defs)
{
$this->metadata = $metadata;
$this->defs = $defs;
}
public function __construct(protected Metadata $metadata, private Defs $defs)
{}
public function checkRequired(Entity $entity, string $field): bool
{
@@ -135,6 +128,14 @@ class ArrayType
/** @var ?string $path */
$path = $fieldDefs->getParam('optionsPath');
/** @var ?string $path */
$ref = $fieldDefs->getParam('optionsReference');
if (!$path && $ref && str_contains($ref, '.')) {
[$refEntityType, $refField] = explode('.', $ref);
$path = "entityDefs.{$refEntityType}.fields.{$refField}.options";
}
/** @var string[]|null|false $optionList */
$optionList = $path ?
@@ -181,9 +182,9 @@ class ArrayType
return false;
}
public function checkMaxLength(Entity $entity, string $field, ?int $validationValue): bool
public function checkMaxItemLength(Entity $entity, string $field, ?int $validationValue): bool
{
$maxLength = $validationValue ?? self::DEFAULT_MAX_LENGTH;
$maxLength = $validationValue ?? self::DEFAULT_MAX_ITEM_LENGTH;
/** @var string[] $value */
$value = $entity->get($field) ?? [];

View File

@@ -0,0 +1,62 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\FieldValidators\AuthenticationProvider;
use Espo\Core\FieldValidation\Validator;
use Espo\Core\FieldValidation\Validator\Data;
use Espo\Core\FieldValidation\Validator\Failure;
use Espo\Core\Utils\Metadata;
use Espo\Entities\AuthenticationProvider;
use Espo\ORM\Entity;
/**
* @implements Validator<AuthenticationProvider>
*/
class MethodValid implements Validator
{
public function __construct(private Metadata $metadata) {}
public function validate(Entity $entity, string $field, Data $data): ?Failure
{
$value = $entity->get($field);
if (!$value) {
return Failure::create();
}
$isAvailable = $this->metadata->get(['authenticationMethods', $value, 'provider', 'isAvailable']);
if (!$isAvailable) {
return Failure::create();
}
return null;
}
}

View File

@@ -29,11 +29,15 @@
namespace Espo\Classes\FieldValidators;
use Espo\Core\Field\Currency;
use Espo\Core\Utils\Config;
use Espo\ORM\BaseEntity;
use Espo\ORM\Entity;
class CurrencyType extends FloatType
{
private const DEFAULT_PRECISION = 13;
public function __construct(private Config $config) {}
protected function isNotEmpty(Entity $entity, string $field): bool
@@ -44,6 +48,62 @@ class CurrencyType extends FloatType
$entity->get($field . 'Currency') !== '';
}
public function checkValid(Entity $entity, string $field): bool
{
if (!$this->isNotEmpty($entity, $field)) {
return true;
}
if ($entity->getAttributeType($field) !== Entity::VARCHAR) {
return true;
}
/** @var string $value */
$value = $entity->get($field);
if (preg_match('/-?[0-9]+\\.?[0-9]*/', $value)) {
return true;
}
return false;
}
public function checkInPermittedRange(Entity $entity, string $field): bool
{
if (!$this->isNotEmpty($entity, $field)) {
return true;
}
if ($entity->getAttributeType($field) !== Entity::VARCHAR) {
return true;
}
if (!$entity instanceof BaseEntity) {
return true;
}
/** @var int $precision */
$precision = $entity->getAttributeParam($field, 'precision') ?? self::DEFAULT_PRECISION;
$value = $entity->get($field);
$currency = Currency::create($value, 'USD');
if ($currency->isNegative()) {
$currency = $currency->multiply(-1);
}
$pad = str_pad('', $precision, '9');
$limit = Currency::create($pad, 'USD');
if ($currency->compare($limit) === 1) {
return false;
}
return true;
}
public function checkValidCurrency(Entity $entity, string $field): bool
{
$attribute = $field . 'Currency';

View File

@@ -0,0 +1,76 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\FieldValidators\Email\Addresses;
use Espo\Core\FieldValidation\Validator;
use Espo\Core\FieldValidation\Validator\Data;
use Espo\Core\FieldValidation\Validator\Failure;
use Espo\Core\Utils\Config;
use Espo\Entities\Email;
use Espo\ORM\Entity;
use LogicException;
/**
* @implements Validator<Email>
*/
class MaxCount implements Validator
{
private const MAX_COUNT = 100;
public function __construct(private Config $config) {}
/**
* @param Email $entity
*/
public function validate(Entity $entity, string $field, Data $data): ?Failure
{
if ($field === 'to') {
$addresses = $entity->getToAddressList();
}
else if ($field === 'cc') {
$addresses = $entity->getCcAddressList();
}
else if ($field === 'bcc') {
$addresses = $entity->getBccAddressList();
}
else {
throw new LogicException();
}
$maxCount = $this->config->get('emailRecipientAddressMaxCount') ?? self::MAX_COUNT;
if (count($addresses) > $maxCount) {
return Failure::create();
}
return null;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\FieldValidators\Email\Addresses;
use Espo\Core\FieldValidation\Validator;
use Espo\Core\FieldValidation\Validator\Data;
use Espo\Core\FieldValidation\Validator\Failure;
use Espo\ORM\Entity;
use Espo\Entities\Email;
use LogicException;
/**
* @implements Validator<Email>
*/
class Valid implements Validator
{
/**
* @param Email $entity
*/
public function validate(Entity $entity, string $field, Data $data): ?Failure
{
if ($field === 'to') {
$addresses = $entity->getToAddressList();
}
else if ($field === 'cc') {
$addresses = $entity->getCcAddressList();
}
else if ($field === 'bcc') {
$addresses = $entity->getBccAddressList();
}
else {
throw new LogicException();
}
foreach ($addresses as $address) {
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
return Failure::create();
}
}
return null;
}
}

View File

@@ -29,13 +29,17 @@
namespace Espo\Classes\FieldValidators\Email;
use Espo\Entities\Email;
use Espo\ORM\Entity;
class EmailAddresses
{
/**
* @param Email $entity
*/
public function checkRequired(Entity $entity, string $field): bool
{
if ($entity->get('status') === 'Draft') {
if ($entity->getStatus() === Email::STATUS_DRAFT) {
return true;
}

View File

@@ -37,7 +37,6 @@ use Espo\ORM\Entity;
class EnumType
{
private Metadata $metadata;
private Defs $defs;
private const DEFAULT_MAX_LENGTH = 255;
@@ -65,6 +64,14 @@ class EnumType
/** @var ?string $path */
$path = $fieldDefs->getParam('optionsPath');
/** @var ?string $path */
$ref = $fieldDefs->getParam('optionsReference');
if (!$path && $ref && str_contains($ref, '.')) {
[$refEntityType, $refField] = explode('.', $ref);
$path = "entityDefs.{$refEntityType}.fields.{$refField}.options";
}
/** @var string[]|null|false $optionList */
$optionList = $path ?

View File

@@ -117,7 +117,7 @@ class LinkMultipleType
return true;
}
/** @var ?array<string,string> $columnsMap */
/** @var ?array<string, string> $columnsMap */
$columnsMap = $fieldDefs->getParam('columns');
if ($columnsMap === null || $columnsMap === []) {

View File

@@ -30,19 +30,12 @@
namespace Espo\Classes\FieldValidators;
use Espo\ORM\Entity;
use Espo\Core\{
Utils\FieldUtil,
};
use Espo\Core\Utils\FieldUtil;
class PersonNameType
{
private $fieldUtil;
public function __construct(FieldUtil $fieldUtil)
{
$this->fieldUtil = $fieldUtil;
}
public function __construct(private FieldUtil $fieldUtil)
{}
public function checkRequired(Entity $entity, string $field): bool
{

View File

@@ -0,0 +1,55 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\FieldValidators;
use Espo\ORM\Entity;
class UrlMultipleType extends ArrayType
{
private const MAX_ITEM_LENGTH = 255;
public function checkNoEmptyString(Entity $entity, string $field, ?bool $validationValue): bool
{
return parent::checkNoEmptyString($entity, $field, true);
}
public function checkMaxItemLength(Entity $entity, string $field, ?int $validationValue): bool
{
return parent::checkMaxItemLength($entity, $field, self::MAX_ITEM_LENGTH);
}
public function checkPattern(Entity $entity, string $field, ?string $validationValue): bool
{
/** @var string $pattern */
$pattern = $this->metadata->get(['app', 'regExpPatterns', 'uriOptionalProtocol', 'pattern']);
return parent::checkPattern($entity, $field, $pattern);
}
}

View File

@@ -29,31 +29,28 @@
namespace Espo\Classes\JobPreparators;
use Espo\Core\Utils\DateTime;
use Espo\Core\Job\Job\Status;
use Espo\Core\Job\Preparator;
use Espo\Core\Job\Preparator\Data;
use Espo\Entities\EmailAccount;
use Espo\ORM\EntityManager;
use Espo\Entities\Job as JobEntity;
use Espo\Entities\EmailAccount;
use Espo\Core\Job\Preparator\CollectionHelper;
use DateTimeImmutable;
class CheckEmailAccounts implements Preparator
{
private EntityManager $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @param CollectionHelper<EmailAccount> $helper
*/
public function __construct(
private EntityManager $entityManager,
private CollectionHelper $helper
) {}
public function prepare(Data $data, DateTimeImmutable $executeTime): void
{
$collection = $this->entityManager
->getRDBRepository(EmailAccount::ENTITY_TYPE)
->getRDBRepositoryByClass(EmailAccount::class)
->join('assignedUser', 'assignedUserAdditional')
->where([
'status' => EmailAccount::STATUS_ACTIVE,
@@ -62,49 +59,6 @@ class CheckEmailAccounts implements Preparator
])
->find();
foreach ($collection as $entity) {
$running = $this->entityManager
->getRDBRepository(JobEntity::ENTITY_TYPE)
->where([
'scheduledJobId' => $data->getId(),
'status' => [
Status::RUNNING,
Status::READY,
],
'targetType' => EmailAccount::ENTITY_TYPE,
'targetId' => $entity->getId(),
])
->findOne();
if ($running) {
continue;
}
$countPending = $this->entityManager
->getRDBRepository(JobEntity::ENTITY_TYPE)
->where([
'scheduledJobId' => $data->getId(),
'status' => Status::PENDING,
'targetType' => EmailAccount::ENTITY_TYPE,
'targetId' => $entity->getId(),
])
->count();
if ($countPending > 1) {
continue;
}
$jobEntity = $this->entityManager->getNewEntity(JobEntity::ENTITY_TYPE);
$jobEntity->set([
'name' => $data->getName(),
'scheduledJobId' => $data->getId(),
'executeTime' => $executeTime->format(DateTime::SYSTEM_DATE_TIME_FORMAT),
'targetType' => EmailAccount::ENTITY_TYPE,
'targetId' => $entity->getId(),
]);
$this->entityManager->saveEntity($jobEntity);
}
$this->helper->prepare($collection, $data, $executeTime);
}
}

View File

@@ -29,80 +29,34 @@
namespace Espo\Classes\JobPreparators;
use Espo\Core\Utils\DateTime;
use Espo\Core\Job\Job\Status;
use Espo\Core\Job\Preparator;
use Espo\Core\Job\Preparator\Data;
use Espo\Entities\InboundEmail;
use Espo\ORM\EntityManager;
use Espo\Entities\Job as JobEntity;
use Espo\Entities\InboundEmail;
use Espo\Core\Job\Preparator\CollectionHelper;
use DateTimeImmutable;
class CheckInboundEmails implements Preparator
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @param CollectionHelper<InboundEmail> $helper
*/
public function __construct(
private EntityManager $entityManager,
private CollectionHelper $helper
) {}
public function prepare(Data $data, DateTimeImmutable $executeTime): void
{
$collection = $this->entityManager
->getRDBRepository(InboundEmail::ENTITY_TYPE)
->getRDBRepositoryByClass(InboundEmail::class)
->where([
'status' => InboundEmail::STATUS_ACTIVE,
'useImap' => true,
])
->find();
foreach ($collection as $entity) {
$running = $this->entityManager
->getRDBRepository(JobEntity::ENTITY_TYPE)
->where([
'scheduledJobId' => $data->getId(),
'status' => [
Status::RUNNING,
Status::READY,
],
'targetType' => InboundEmail::ENTITY_TYPE,
'targetId' => $entity->getId(),
])
->findOne();
if ($running) {
continue;
}
$countPending = $this->entityManager
->getRDBRepository(JobEntity::ENTITY_TYPE)
->where([
'scheduledJobId' => $data->getId(),
'status' => Status::PENDING,
'targetType' => InboundEmail::ENTITY_TYPE,
'targetId' => $entity->getId(),
])
->count();
if ($countPending > 1) {
continue;
}
$jobEntity = $this->entityManager->getNewEntity(JobEntity::ENTITY_TYPE);
$jobEntity->set([
'name' => $data->getName(),
'scheduledJobId' => $data->getId(),
'executeTime' => $executeTime->format(DateTime::SYSTEM_DATE_TIME_FORMAT),
'targetType' => InboundEmail::ENTITY_TYPE,
'targetId' => $entity->getId(),
]);
$this->entityManager->saveEntity($jobEntity);
}
$this->helper->prepare($collection, $data, $executeTime);
}
}

View File

@@ -420,7 +420,7 @@ class Cleanup implements JobDataLess
->from($scope)
->withDeleted()
->where([
'deleted' => 1,
'deleted' => true,
'modifiedAt<' => $datetime->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT),
'modifiedAt>' => $datetimeFrom->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT),
])
@@ -609,8 +609,6 @@ class Cleanup implements JobDataLess
$repository->deleteFromDb($entity->getId());
$query = $this->entityManager->getQueryComposer();
foreach ($entity->getRelationList() as $relation) {
if ($entity->getRelationType($relation) !== Entity::MANY_MANY) {
continue;
@@ -760,9 +758,18 @@ class Cleanup implements JobDataLess
$service = $this->recordServiceContainer->get($scope);
$whereClause = [
'deleted' => 1,
'deleted' => true,
];
if (
!$this->entityManager
->getDefs()
->getEntity($scope)
->hasAttribute('deleted')
) {
continue;
}
if ($this->metadata->get(['entityDefs', $scope, 'fields', 'modifiedAt'])) {
$whereClause['modifiedAt<'] = $datetime->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
}

View File

@@ -29,19 +29,13 @@
namespace Espo\Classes\Jobs;
use Espo\Core\{
Job\JobDataLess,
Webhook\Queue,
};
use Espo\Core\Job\JobDataLess;
use Espo\Core\Webhook\Queue;
class ProcessWebhookQueue implements JobDataLess
{
private $queue;
public function __construct(Queue $queue)
{
$this->queue = $queue;
}
public function __construct(private Queue $queue)
{}
public function run(): void
{

View File

@@ -41,29 +41,20 @@ use Espo\Entities\EmailFolder;
use Espo\Entities\GroupEmailFolder;
use Espo\Entities\User;
use Espo\ORM\EntityManager;
use Espo\Tools\Email\Folder;
use Espo\Tools\Email\InboxService as EmailService;
use Exception;
class MoveToFolder implements MassAction
{
private const FOLDER_INBOX = 'inbox';
private QueryBuilder $queryBuilder;
private EntityManager $entityManager;
private EmailService $service;
private User $user;
private const FOLDER_INBOX = Folder::INBOX;
public function __construct(
QueryBuilder $queryBuilder,
EntityManager $entityManager,
EmailService $service,
User $user
) {
$this->queryBuilder = $queryBuilder;
$this->entityManager = $entityManager;
$this->service = $service;
$this->user = $user;
}
private QueryBuilder $queryBuilder,
private EntityManager $entityManager,
private EmailService $service,
private User $user
) {}
/**
* @throws BadRequest
@@ -77,7 +68,7 @@ class MoveToFolder implements MassAction
throw new BadRequest("No folder ID.");
}
if ($folderId !== self::FOLDER_INBOX && strpos($folderId, 'group:') !== 0) {
if ($folderId !== self::FOLDER_INBOX && !str_starts_with($folderId, 'group:')) {
$folder = $this->entityManager
->getRDBRepositoryByClass(EmailFolder::class)
->where([
@@ -91,7 +82,7 @@ class MoveToFolder implements MassAction
}
}
if ($folderId && strpos($folderId, 'group:') === 0) {
if ($folderId && str_starts_with($folderId, 'group:')) {
$folder = $this->entityManager
->getRDBRepositoryByClass(GroupEmailFolder::class)
->where(['id' => substr($folderId, 6)])
@@ -117,7 +108,7 @@ class MoveToFolder implements MassAction
try {
$this->service->moveToFolder($email->getId(), $folderId, $this->user->getId());
}
catch (Exception $e) {
catch (Exception) {
continue;
}

View File

@@ -29,48 +29,36 @@
namespace Espo\Classes\MassAction\User;
use Espo\Core\{
ApplicationUser,
MassAction\Actions\MassDelete as MassDeleteOriginal,
MassAction\QueryBuilder,
MassAction\Params,
MassAction\Result,
MassAction\Data,
MassAction\MassAction,
Acl,
ORM\EntityManager,
Exceptions\Forbidden,
};
use Espo\Core\Acl;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\MassAction\Actions\MassDelete as MassDeleteOriginal;
use Espo\Core\MassAction\Data;
use Espo\Core\MassAction\MassAction;
use Espo\Core\MassAction\Params;
use Espo\Core\MassAction\QueryBuilder;
use Espo\Core\MassAction\Result;
use Espo\Core\ORM\EntityManager;
use Espo\{
Entities\User,
ORM\Entity,
};
use Espo\Core\Utils\SystemUser;
use Espo\Entities\User;
/**
* Extended to forbid removal of own and system users.
*/
class MassDelete implements MassAction
{
private MassDeleteOriginal $massDeleteOriginal;
private QueryBuilder $queryBuilder;
private EntityManager $entityManager;
private Acl $acl;
private User $user;
public function __construct(
MassDeleteOriginal $massDeleteOriginal,
QueryBuilder $queryBuilder,
EntityManager $entityManager,
Acl $acl,
User $user
) {
$this->massDeleteOriginal = $massDeleteOriginal;
$this->queryBuilder = $queryBuilder;
$this->entityManager = $entityManager;
$this->acl = $acl;
$this->user = $user;
}
private MassDeleteOriginal $massDeleteOriginal,
private QueryBuilder $queryBuilder,
private EntityManager $entityManager,
private Acl $acl,
private User $user
) {}
/**
* @throws Forbidden
* @throws BadRequest
*/
public function process(Params $params, Data $data): Result
{
@@ -93,7 +81,7 @@ class MassDelete implements MassAction
->getRDBRepository(User::ENTITY_TYPE)
->clone($query)
->sth()
->select(['id'])
->select(['id', 'userName'])
->find();
foreach ($collection as $entity) {
@@ -106,9 +94,9 @@ class MassDelete implements MassAction
/**
* @throws Forbidden
*/
protected function checkEntity(Entity $entity): void
private function checkEntity(User $entity): void
{
if ($entity->getId() === ApplicationUser::SYSTEM_USER_ID) {
if ($entity->getUserName() === SystemUser::NAME) {
throw new Forbidden("Can't delete 'system' user.");
}

View File

@@ -29,6 +29,7 @@
namespace Espo\Classes\MassAction\User;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\MassAction\Actions\MassUpdate as MassUpdateOriginal;
use Espo\Core\MassAction\QueryBuilder;
use Espo\Core\MassAction\Params;
@@ -42,24 +43,15 @@ use Espo\Core\Acl\Table;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Utils\SystemUser;
use Espo\Entities\User;
use Espo\ORM\Entity;
use Espo\ORM\EntityManager;
use Espo\Tools\MassUpdate\Data as MassUpdateData;
class MassUpdate implements MassAction
{
private MassUpdateOriginal $massUpdateOriginal;
private QueryBuilder $queryBuilder;
private EntityManager $entityManager;
private Acl $acl;
private User $user;
private FileManager $fileManager;
private DataManager $dataManager;
private const PERMISSION = 'massUpdatePermission';
private const SYSTEM_USER_ID = 'system';
/** @var string[] */
private array $notAllowedAttributeList = [
@@ -72,25 +64,18 @@ class MassUpdate implements MassAction
];
public function __construct(
MassUpdateOriginal $massUpdateOriginal,
QueryBuilder $queryBuilder,
EntityManager $entityManager,
Acl $acl,
User $user,
FileManager $fileManager,
DataManager $dataManager
) {
$this->massUpdateOriginal = $massUpdateOriginal;
$this->queryBuilder = $queryBuilder;
$this->entityManager = $entityManager;
$this->acl = $acl;
$this->user = $user;
$this->fileManager = $fileManager;
$this->dataManager = $dataManager;
}
private MassUpdateOriginal $massUpdateOriginal,
private QueryBuilder $queryBuilder,
private EntityManager $entityManager,
private Acl $acl,
private User $user,
private FileManager $fileManager,
private DataManager $dataManager
) {}
/**
* @throws Forbidden
* @throws BadRequest
*/
public function process(Params $params, Data $data): Result
{
@@ -118,7 +103,7 @@ class MassUpdate implements MassAction
->getRDBRepository(User::ENTITY_TYPE)
->clone($query)
->sth()
->select(['id'])
->select(['id', 'userName'])
->find();
foreach ($collection as $entity) {
@@ -147,9 +132,9 @@ class MassUpdate implements MassAction
/**
* @throws Forbidden
*/
private function checkEntity(Entity $entity, MassUpdateData $data): void
private function checkEntity(User $entity, MassUpdateData $data): void
{
if ($entity->getId() === self::SYSTEM_USER_ID) {
if ($entity->getUserName() === SystemUser::NAME) {
throw new Forbidden("Can't update 'system' user.");
}

View File

@@ -29,20 +29,14 @@
namespace Espo\Classes\Select\ActionHistoryRecord\AccessControlFilters;
use Espo\{
Core\Select\AccessControl\Filter,
ORM\Query\SelectBuilder as QueryBuilder,
Entities\User,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyOwn implements Filter
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function __construct(private User $user)
{}
public function apply(QueryBuilder $queryBuilder): void
{

View File

@@ -29,22 +29,16 @@
namespace Espo\Classes\Select\ActionHistoryRecord\BoolFilters;
use Espo\{
Core\Select\Bool\Filter,
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereClause,
ORM\Query\Part\Where\OrGroupBuilder,
Entities\User,
};
use Espo\Core\Select\Bool\Filter;
use Espo\Entities\User;
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyMy implements Filter
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function __construct(private User $user)
{}
public function apply(QueryBuilder $queryBuilder, OrGroupBuilder $orGroupBuilder): void
{

View File

@@ -29,34 +29,23 @@
namespace Espo\Classes\Select\Email\AccessControlFilters;
use Espo\Core\{
Select\AccessControl\Filter,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
Classes\Select\Email\Helpers\JoinHelper,
Entities\User,
};
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyOwn implements Filter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(
private User $user,
private JoinHelper $joinHelper
) {}
public function apply(QueryBuilder $queryBuilder): void
{
$this->joinHelper->joinEmailUser($queryBuilder, $this->user->getId());
$queryBuilder->where([
'emailUser.userId' => $this->user->getId(),
]);
$queryBuilder->where(['emailUser.userId' => $this->user->getId()]);
}
}

View File

@@ -29,39 +29,47 @@
namespace Espo\Classes\Select\Email\AccessControlFilters;
use Espo\Core\{
Select\AccessControl\Filter,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
Classes\Select\Email\Helpers\JoinHelper,
Entities\User,
};
use Espo\Entities\Email;
use Espo\Entities\Team;
use Espo\Entities\User;
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyTeam implements Filter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user)
{}
public function apply(QueryBuilder $queryBuilder): void
{
$this->joinHelper->joinEmailUser($queryBuilder, $this->user->getId());
$queryBuilder->distinct();
$queryBuilder->leftJoin('teams', 'teamsAccess');
$queryBuilder->where([
'OR' => [
'teamsAccessMiddle.teamId' => $this->user->getLinkMultipleIdList('teams'),
$subQuery = QueryBuilder::create()
->select('id')
->from(Email::ENTITY_TYPE)
->leftJoin(Team::RELATIONSHIP_ENTITY_TEAM, 'entityTeam', [
'entityTeam.entityId:' => 'id',
'entityTeam.entityType' => Email::ENTITY_TYPE,
'entityTeam.deleted' => false,
])
->leftJoin(Email::RELATIONSHIP_EMAIL_USER, 'emailUser', [
'emailUser.emailId:' => 'id',
'emailUser.deleted' => false,
'emailUser.userId' => $this->user->getId(),
]
]);
])
->where([
'OR' => [
'entityTeam.teamId' => $this->user->getTeamIdList(),
'emailUser.userId' => $this->user->getId(),
]
])
->build();
$queryBuilder->where(
Cond::in(
Cond::column('id'),
$subQuery
)
);
}
}

View File

@@ -29,27 +29,15 @@
namespace Espo\Classes\Select\Email\AccessControlFilters;
use Espo\Core\{
Select\AccessControl\Filter,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
Classes\Select\Email\Helpers\JoinHelper,
Entities\User,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class PortalOnlyAccount implements Filter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function apply(QueryBuilder $queryBuilder): void
{

View File

@@ -29,27 +29,15 @@
namespace Espo\Classes\Select\Email\AccessControlFilters;
use Espo\Core\{
Select\AccessControl\Filter,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
Classes\Select\Email\Helpers\JoinHelper,
Entities\User,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class PortalOnlyContact implements Filter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function apply(QueryBuilder $queryBuilder): void
{

View File

@@ -30,45 +30,53 @@
namespace Espo\Classes\Select\Email\AdditionalAppliers;
use Espo\Core\Select\Applier\AdditionalApplier;
use Espo\ORM\Query\SelectBuilder;
use Espo\Core\Select\SearchParams;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\Email;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder;
use Espo\Tools\Email\Folder;
class Main implements AdditionalApplier
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(
private User $user,
private JoinHelper $joinHelper
) {}
public function apply(SelectBuilder $queryBuilder, SearchParams $searchParams): void
{
$folder = $this->retrieveFolder($searchParams);
if ($folder === 'drafts') {
$queryBuilder->useIndex('createdById');
}
else if ($folder === 'important') {
// skip
}
else if ($this->checkApplyDateSentIndex($queryBuilder, $searchParams)) {
$queryBuilder->useIndex('dateSent');
}
$this->applyIndexes($folder, $queryBuilder, $searchParams);
if ($folder !== 'drafts') {
if ($folder !== Folder::DRAFTS) {
$this->joinEmailUser($queryBuilder);
}
}
protected function joinEmailUser(SelectBuilder $queryBuilder): void
private function applyIndexes(?string $folder, SelectBuilder $queryBuilder, SearchParams $searchParams): void
{
if ($searchParams->getTextFilter()) {
return;
}
if ($folder === Folder::IMPORTANT) {
return;
}
if ($folder === Folder::DRAFTS) {
$queryBuilder->useIndex('createdById');
return;
}
if ($this->checkApplyDateSentIndex($queryBuilder, $searchParams)) {
$queryBuilder->useIndex('dateSent');
}
}
private function joinEmailUser(SelectBuilder $queryBuilder): void
{
$this->joinHelper->joinEmailUser($queryBuilder, $this->user->getId());
@@ -77,10 +85,10 @@ class Main implements AdditionalApplier
}
$itemList = [
'isRead',
'isImportant',
'inTrash',
'folderId',
Email::USERS_COLUMN_IS_READ,
Email::USERS_COLUMN_IS_IMPORTANT,
Email::USERS_COLUMN_IN_TRASH,
Email::USERS_COLUMN_FOLDER_ID,
];
foreach ($itemList as $item) {
@@ -88,7 +96,7 @@ class Main implements AdditionalApplier
}
}
protected function retrieveFolder(SearchParams $searchParams): ?string
private function retrieveFolder(SearchParams $searchParams): ?string
{
if (!$searchParams->getWhere()) {
return null;
@@ -103,7 +111,7 @@ class Main implements AdditionalApplier
return null;
}
protected function checkApplyDateSentIndex(SelectBuilder $queryBuilder, SearchParams $searchParams): bool
private function checkApplyDateSentIndex(SelectBuilder $queryBuilder, SearchParams $searchParams): bool
{
if ($searchParams->getTextFilter()) {
return false;

View File

@@ -29,26 +29,17 @@
namespace Espo\Classes\Select\Email\BoolFilters;
use Espo\{
Core\Select\Bool\Filter,
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereClause,
ORM\Query\Part\Where\OrGroupBuilder,
Classes\Select\Email\Helpers\JoinHelper,
Entities\User,
};
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Core\Select\Bool\Filter;
use Espo\Entities\User;
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyMy implements Filter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function apply(QueryBuilder $queryBuilder, OrGroupBuilder $orGroupBuilder): void
{

View File

@@ -29,9 +29,8 @@
namespace Espo\Classes\Select\Email\Helpers;
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
};
use Espo\Entities\Email;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class JoinHelper
{
@@ -41,14 +40,10 @@ class JoinHelper
return;
}
$queryBuilder->leftJoin(
'EmailUser',
'emailUser',
[
'emailUser.emailId:' => 'id',
'emailUser.deleted' => false,
'emailUser.userId' => $userId,
]
);
$queryBuilder->leftJoin(Email::RELATIONSHIP_EMAIL_USER, 'emailUser', [
'emailUser.emailId:' => 'id',
'emailUser.deleted' => false,
'emailUser.userId' => $userId,
]);
}
}

View File

@@ -29,6 +29,7 @@
namespace Espo\Classes\Select\Email;
use Espo\Core\Exceptions\Error;
use Espo\Core\Select\Text\Filter;
use Espo\Core\Select\Text\Filter\Data;
use Espo\Core\Select\Text\DefaultFilter;
@@ -44,22 +45,15 @@ use Espo\Entities\EmailAddress;
class TextFilter implements Filter
{
private $defaultFilter;
private $config;
private $entityManager;
public function __construct(
DefaultFilter $defaultFilter,
ConfigProvider $config,
EntityManager $entityManager
) {
$this->defaultFilter = $defaultFilter;
$this->config = $config;
$this->entityManager = $entityManager;
}
private DefaultFilter $defaultFilter,
private ConfigProvider $config,
private EntityManager $entityManager
) {}
/**
* @throws Error
*/
public function apply(QueryBuilder $queryBuilder, Data $data): void
{
$filter = $data->getFilter();
@@ -67,7 +61,7 @@ class TextFilter implements Filter
if (
mb_strlen($filter) < $this->config->getMinLengthForContentSearch() ||
strpos($filter, '@') === false ||
!str_contains($filter, '@') ||
$data->forceFullTextSearch()
) {
$this->defaultFilter->apply($queryBuilder, $data);

View File

@@ -29,32 +29,20 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
Select\Helpers\RandomStringGenerator,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Classes\Select\Email\Helpers\EmailAddressHelper,
};
use Espo\Core\Select\Helpers\RandomStringGenerator;
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\EmailAddressHelper;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class EmailAddressEquals implements ItemConverter
{
private $emailAddressHelper;
private $randomStringGenerator;
public function __construct(
EmailAddressHelper $emailAddressHelper,
RandomStringGenerator $randomStringGenerator
) {
$this->emailAddressHelper = $emailAddressHelper;
$this->randomStringGenerator = $randomStringGenerator;
}
private EmailAddressHelper $emailAddressHelper,
private RandomStringGenerator $randomStringGenerator
) {}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,38 +29,18 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
ORM\EntityManager,
Classes\Select\Email\Helpers\EmailAddressHelper,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\EmailAddressHelper;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class FromEquals implements ItemConverter
{
/**
* @var EntityManager
*/
protected $entityManager;
/**
* @var EmailAddressHelper
*/
protected $emailAddressHelper;
public function __construct(
EntityManager $entityManager,
EmailAddressHelper $emailAddressHelper
) {
$this->entityManager = $entityManager;
$this->emailAddressHelper = $emailAddressHelper;
}
private EmailAddressHelper $emailAddressHelper
) {}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -39,46 +39,29 @@ use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\EntityManager;
use Espo\Entities\User;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Tools\Email\Folder;
class InFolder implements ItemConverter
{
private User $user;
private EntityManager $entityManager;
private JoinHelper $joinHelper;
public function __construct(User $user, EntityManager $entityManager, JoinHelper $joinHelper)
{
$this->user = $user;
$this->entityManager = $entityManager;
$this->joinHelper = $joinHelper;
}
public function __construct(
private User $user,
private EntityManager $entityManager,
private JoinHelper $joinHelper
) {}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{
$folderId = $item->getValue();
switch ($folderId) {
case 'all':
return WhereClause::fromRaw([]);
case 'inbox':
return $this->convertInbox($queryBuilder);
case 'important':
return $this->convertImportant($queryBuilder);
case 'sent':
return $this->convertSent($queryBuilder);
case 'trash':
return $this->convertTrash($queryBuilder);
case 'drafts':
return $this->convertDraft($queryBuilder);
default:
return $this->convertFolderId($queryBuilder, $folderId);
}
return match ($folderId) {
Folder::ALL => WhereClause::fromRaw([]),
Folder::INBOX => $this->convertInbox($queryBuilder),
Folder::IMPORTANT => $this->convertImportant($queryBuilder),
Folder::SENT => $this->convertSent($queryBuilder),
Folder::TRASH => $this->convertTrash($queryBuilder),
Folder::DRAFTS => $this->convertDraft($queryBuilder),
default => $this->convertFolderId($queryBuilder, $folderId),
};
}
protected function convertInbox(QueryBuilder $queryBuilder): WhereClauseItem
@@ -171,7 +154,7 @@ class InFolder implements ItemConverter
{
$this->joinEmailUser($queryBuilder);
if (substr($folderId, 0, 6) === 'group:') {
if (str_starts_with($folderId, 'group:')) {
$groupFolderId = substr($folderId, 6);
if ($groupFolderId === '') {

View File

@@ -29,30 +29,18 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Entities\User,
Classes\Select\Email\Helpers\JoinHelper,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsImportantIsFalse implements ItemConverter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,30 +29,18 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Entities\User,
Classes\Select\Email\Helpers\JoinHelper,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsImportantIsTrue implements ItemConverter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,30 +29,18 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Entities\User,
Classes\Select\Email\Helpers\JoinHelper,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsNotReadIsFalse implements ItemConverter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,30 +29,18 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Entities\User,
Classes\Select\Email\Helpers\JoinHelper,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\JoinHelper;
use Espo\Entities\User;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsNotReadIsTrue implements ItemConverter
{
private $user;
private $joinHelper;
public function __construct(User $user, JoinHelper $joinHelper)
{
$this->user = $user;
$this->joinHelper = $joinHelper;
}
public function __construct(private User $user, private JoinHelper $joinHelper)
{}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,16 +29,11 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsNotRepliedIsFalse implements ItemConverter
{

View File

@@ -29,16 +29,11 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsNotRepliedIsTrue implements ItemConverter
{

View File

@@ -29,32 +29,20 @@
namespace Espo\Classes\Select\Email\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
Select\Helpers\RandomStringGenerator,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
Classes\Select\Email\Helpers\EmailAddressHelper,
};
use Espo\Core\Select\Helpers\RandomStringGenerator;
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Classes\Select\Email\Helpers\EmailAddressHelper;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class ToEquals implements ItemConverter
{
private $emailAddressHelper;
private $randomStringGenerator;
public function __construct(
EmailAddressHelper $emailAddressHelper,
RandomStringGenerator $randomStringGenerator
) {
$this->emailAddressHelper = $emailAddressHelper;
$this->randomStringGenerator = $randomStringGenerator;
}
private EmailAddressHelper $emailAddressHelper,
private RandomStringGenerator $randomStringGenerator
) {}
public function convert(QueryBuilder $queryBuilder, Item $item): WhereClauseItem
{

View File

@@ -29,20 +29,14 @@
namespace Espo\Classes\Select\EmailAccount\AccessControlFilters;
use Espo\{
Core\Select\AccessControl\Filter,
ORM\Query\SelectBuilder as QueryBuilder,
Entities\User,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class Mandatory implements Filter
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function __construct(private User $user)
{}
public function apply(QueryBuilder $queryBuilder): void
{

View File

@@ -29,13 +29,11 @@
namespace Espo\Classes\Select\EmailFilter\AccessControlFilters;
use Espo\{
Core\Select\AccessControl\Filter,
Entities\EmailAccount,
ORM\Query\SelectBuilder as QueryBuilder,
ORM\EntityManager,
Entities\User,
};
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\EmailAccount;
use Espo\Entities\User;
use Espo\ORM\EntityManager;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyOwn implements Filter
{

View File

@@ -29,26 +29,18 @@
namespace Espo\Classes\Select\EmailFilter\BoolFilters;
use Espo\{
Core\Select\Bool\Filter,
Entities\EmailAccount,
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereClause,
ORM\Query\Part\Where\OrGroupBuilder,
ORM\EntityManager,
Entities\User,
};
use Espo\Core\Select\Bool\Filter;
use Espo\Entities\EmailAccount;
use Espo\Entities\User;
use Espo\ORM\EntityManager;
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class OnlyMy implements Filter
{
private User $user;
private EntityManager $entityManager;
public function __construct(User $user, EntityManager $entityManager)
{
$this->user = $user;
$this->entityManager = $entityManager;
}
public function __construct(private User $user, private EntityManager $entityManager)
{}
public function apply(QueryBuilder $queryBuilder, OrGroupBuilder $orGroupBuilder): void
{

View File

@@ -0,0 +1,49 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\Select\Event\PrimaryFilters;
use Espo\Core\Select\Primary\Filter;
use Espo\Core\Utils\Metadata;
use Espo\ORM\Query\SelectBuilder;
class Held implements Filter
{
public function __construct(
private string $entityType,
private Metadata $metadata
) {}
public function apply(SelectBuilder $queryBuilder): void
{
$statusList = $this->metadata->get(['scopes', $this->entityType, 'completedStatusList']) ?? [];
$queryBuilder->where(['status' => $statusList]);
}
}

View File

@@ -0,0 +1,49 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\Select\Event\PrimaryFilters;
use Espo\Core\Select\Primary\Filter;
use Espo\Core\Utils\Metadata;
use Espo\ORM\Query\SelectBuilder;
class Planned implements Filter
{
public function __construct(
private string $entityType,
private Metadata $metadata
) {}
public function apply(SelectBuilder $queryBuilder): void
{
$statusList = $this->metadata->get(['scopes', $this->entityType, 'activityStatusList']) ?? [];
$queryBuilder->where(['status' => $statusList]);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Classes\Select\Event\PrimaryFilters;
use Espo\Core\Exceptions\Error;
use Espo\Core\Select\Primary\Filter;
use Espo\Core\Select\Helpers\UserTimeZoneProvider;
use Espo\Core\Select\Where\ConverterFactory;
use Espo\Core\Select\Where\Item;
use Espo\ORM\Query\SelectBuilder;
use Espo\Entities\User;
use LogicException;
class Todays implements Filter
{
public function __construct(
private User $user,
private UserTimeZoneProvider $userTimeZoneProvider,
private ConverterFactory $converterFactory,
private string $entityType
) {}
public function apply(SelectBuilder $queryBuilder): void
{
$item = Item::fromRaw([
'type' => Item\Type::TODAY,
'attribute' => 'dateStart',
'timeZone' => $this->userTimeZoneProvider->get(),
'dateTime' => true,
]);
try {
$whereItem = $this->converterFactory
->create($this->entityType, $this->user)
->convert($queryBuilder, $item);
}
catch (Error $e) {
throw new LogicException($e->getMessage());
}
$queryBuilder->where($whereItem);
}
}

View File

@@ -30,22 +30,14 @@
namespace Espo\Classes\Select\Team\AccessControlFilters;
use Espo\Entities\User;
use Espo\Core\Select\AccessControl\Filter;
use Espo\ORM\Query\{
SelectBuilder,
Part\Condition as Cond,
};
use Espo\ORM\Query\Part\Condition as Cond;
use Espo\ORM\Query\SelectBuilder;
class OnlyTeam implements Filter
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function __construct(private User $user)
{}
public function apply(SelectBuilder $queryBuilder): void
{

View File

@@ -29,33 +29,21 @@
namespace Espo\Classes\Select\Template\AccessControlFilters;
use Espo\ORM\{
Query\SelectBuilder,
Defs,
};
use Espo\Core\{
Select\AccessControl\Filter,
AclManager,
Acl\Exceptions\NotImplemented,
};
use Espo\ORM\Defs;
use Espo\ORM\Query\SelectBuilder;
use Espo\Core\Acl\Exceptions\NotImplemented;
use Espo\Core\AclManager;
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
class Mandatory implements Filter
{
private $user;
private $defs;
private $aclManager;
public function __construct(User $user, Defs $defs, AclManager $aclManager)
{
$this->user = $user;
$this->defs = $defs;
$this->aclManager = $aclManager;
}
public function __construct(
private User $user,
private Defs $defs,
private AclManager $aclManager
) {}
public function apply(SelectBuilder $queryBuilder): void
{

View File

@@ -30,40 +30,31 @@
namespace Espo\Classes\Select\User\AccessControlFilters;
use Espo\ORM\Query\SelectBuilder;
use Espo\Core\{
Select\AccessControl\Filter,
AclManager,
Acl\Table,
};
use Espo\Core\Acl\Table;
use Espo\Core\AclManager;
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
class Mandatory implements Filter
{
private $user;
private $aclManager;
public function __construct(User $user, AclManager $aclManager)
{
$this->user = $user;
$this->aclManager = $aclManager;
}
public function __construct(
private User $user,
private AclManager $aclManager
) {}
public function apply(SelectBuilder $queryBuilder): void
{
if (!$this->user->isAdmin()) {
$queryBuilder->where([
'isActive' => true,
'type!=' => 'api',
'type!=' => User::TYPE_API,
]);
}
if ($this->aclManager->getPermissionLevel($this->user, 'portalPermission') !== Table::LEVEL_YES) {
$queryBuilder->where([
'OR' => [
'type!=' => 'portal',
'type!=' => User::TYPE_PORTAL,
'id' => $this->user->getId(),
]
]);
@@ -71,12 +62,12 @@ class Mandatory implements Filter
if (!$this->user->isSuperAdmin()) {
$queryBuilder->where([
'type!=' => 'super-admin'
'type!=' => User::TYPE_SUPER_ADMIN,
]);
}
$queryBuilder->where([
'type!=' => 'system'
'type!=' => User::TYPE_SYSTEM,
]);
}
}

View File

@@ -30,26 +30,16 @@
namespace Espo\Classes\Select\User\AccessControlFilters;
use Espo\ORM\Query\SelectBuilder;
use Espo\Core\{
Select\AccessControl\Filter,
AclManager,
Acl\Table,
};
use Espo\Core\Acl\Table;
use Espo\Core\AclManager;
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
class OnlyOwn implements Filter
{
private $user;
private $aclManager;
public function __construct(User $user, AclManager $aclManager)
{
$this->user = $user;
$this->aclManager = $aclManager;
}
public function __construct(private User $user, private AclManager $aclManager)
{}
public function apply(SelectBuilder $queryBuilder): void
{
@@ -57,7 +47,7 @@ class OnlyOwn implements Filter
$queryBuilder->where([
'OR' => [
'id' => $this->user->getId(),
'type' => 'portal',
'type' => User::TYPE_PORTAL,
],
]);

View File

@@ -31,25 +31,18 @@ namespace Espo\Classes\Select\User\AccessControlFilters;
use Espo\ORM\Query\SelectBuilder;
use Espo\Core\{
Select\AccessControl\Filter,
AclManager,
Acl\Table,
};
use Espo\Core\Acl\Table;
use Espo\Core\AclManager;
use Espo\Core\Select\AccessControl\Filter;
use Espo\Entities\User;
class OnlyTeam implements Filter
{
private $user;
private $aclManager;
public function __construct(User $user, AclManager $aclManager)
{
$this->user = $user;
$this->aclManager = $aclManager;
}
public function __construct(
private User $user,
private AclManager $aclManager
) {}
public function apply(SelectBuilder $queryBuilder): void
{
@@ -59,7 +52,7 @@ class OnlyTeam implements Filter
];
if ($this->aclManager->getPermissionLevel($this->user, 'portalPermission') === Table::LEVEL_YES) {
$orGroup['type'] = 'portal';
$orGroup['type'] = User::TYPE_PORTAL;
}
$queryBuilder

View File

@@ -30,6 +30,7 @@
namespace Espo\Classes\Select\User\PrimaryFilters;
use Espo\Core\Select\Primary\Filter;
use Espo\Entities\User;
use Espo\ORM\Query\SelectBuilder;
class Internal implements Filter
@@ -37,7 +38,11 @@ class Internal implements Filter
public function apply(SelectBuilder $queryBuilder): void
{
$queryBuilder->where([
'type!=' => ['portal', 'api', 'system'],
'type!=' => [
User::TYPE_PORTAL,
User::TYPE_API,
User::TYPE_SYSTEM,
],
]);
}
}

View File

@@ -29,16 +29,12 @@
namespace Espo\Classes\Select\User\Where\ItemConverters;
use Espo\Core\{
Select\Where\ItemConverter,
Select\Where\Item,
};
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\WhereItem as WhereClauseItem,
ORM\Query\Part\WhereClause,
};
use Espo\Core\Select\Where\Item;
use Espo\Core\Select\Where\ItemConverter;
use Espo\Entities\User;
use Espo\ORM\Query\Part\WhereClause;
use Espo\ORM\Query\Part\WhereItem as WhereClauseItem;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
class IsOfType implements ItemConverter
{
@@ -46,23 +42,21 @@ class IsOfType implements ItemConverter
{
$type = $item->getValue();
switch ($type) {
case 'internal':
return WhereClause::fromRaw([
'type!=' => ['portal', 'api', 'system'],
]);
case 'api':
return WhereClause::fromRaw([
'type' => 'api',
]);
case 'portal':
return WhereClause::fromRaw([
'type' => 'portal',
]);
}
return WhereClause::fromRaw(['id' => null]);
return match ($type) {
'internal' => WhereClause::fromRaw([
'type!=' => [
User::TYPE_PORTAL,
User::TYPE_API,
User::TYPE_SYSTEM,
],
]),
User::TYPE_PORTAL => WhereClause::fromRaw([
'type' => User::TYPE_PORTAL,
]),
User::TYPE_API => WhereClause::fromRaw([
'type' => User::TYPE_API,
]),
default => WhereClause::fromRaw(['id' => null]),
};
}
}

View File

@@ -51,8 +51,10 @@ class TableTag implements Helper
$content = $function !== null ? $function() : '';
$style = "border: {$border}; border-spacing: 0; border-collapse: collapse;";
return Result::createSafeString(
"<table border=\"{$border}\" cellpadding=\"{$cellpadding}\" {$attributesPart}>" .
"<table style=\"{$style}\" border=\"{$border}\" cellpadding=\"{$cellpadding}\" {$attributesPart}>" .
$content .
"</table>"
);

View File

@@ -56,7 +56,7 @@ class TdTag implements Helper
$content = $function !== null ? $function() : '';
return Result::createSafeString(
"<td>" . $content . "</td>"
"<td {$attributesPart}>{$content}</td>"
);
}
}

View File

@@ -44,30 +44,15 @@ use Espo\Entities\User;
class Admin
{
private Container $container;
private Config $config;
private User $user;
private AdminNotificationManager $adminNotificationManager;
private SystemRequirements $systemRequirements;
private ScheduledJob $scheduledJob;
private DataManager $dataManager;
public function __construct(
Container $container,
Config $config,
User $user,
AdminNotificationManager $adminNotificationManager,
SystemRequirements $systemRequirements,
ScheduledJob $scheduledJob,
DataManager $dataManager
private Container $container,
private Config $config,
private User $user,
private AdminNotificationManager $adminNotificationManager,
private SystemRequirements $systemRequirements,
private ScheduledJob $scheduledJob,
private DataManager $dataManager
) {
$this->container = $container;
$this->config = $config;
$this->user = $user;
$this->adminNotificationManager = $adminNotificationManager;
$this->systemRequirements = $systemRequirements;
$this->scheduledJob = $scheduledJob;
$this->dataManager = $dataManager;
if (!$this->user->isAdmin()) {
throw new Forbidden();
@@ -98,7 +83,7 @@ class Admin
/**
* @param array<string,mixed> $params
* @param array<string, mixed> $params
* @param string $data
* @return array{
* id: string,
@@ -160,7 +145,7 @@ class Admin
}
/**
* @return array<int,array{id:string,type:string,message:string}>
* @return array<int, array{id: string, type: string, message: string}>
*/
public function actionAdminNotificationList(): array
{
@@ -169,9 +154,9 @@ class Admin
/**
* @return array{
* php: array<string,array<string,mixed>>,
* database: array<string,array<string,mixed>>,
* permission: array<string,array<string,mixed>>,
* php: array<string, array<string, mixed>>,
* database: array<string, array<string, mixed>>,
* permission: array<string, array<string, mixed>>,
* }
*/
public function actionSystemRequirementList(): array

View File

@@ -29,17 +29,11 @@
namespace Espo\Controllers;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Api\Request;
use Espo\Core\Api\Response;
use Espo\Core\Controllers\RecordBase;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Forbidden;
use Espo\Tools\Attachment\FieldData;
use Espo\Tools\Attachment\Service;
use Espo\Tools\Attachment\UploadUrlService;
use Espo\Tools\Attachment\UploadService;
use stdClass;
class Attachment extends RecordBase
@@ -52,125 +46,4 @@ class Attachment extends RecordBase
return parent::getActionList($request, $response);
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws Error
*/
public function postActionGetAttachmentFromImageUrl(Request $request): stdClass
{
$data = $request->getParsedBody();
$url = $data->url ?? null;
$field = $data->field ?? null;
$parentType = $data->parentType ?? null;
$relatedType = $data->relatedType ?? null;
if (!$url || !$field) {
throw new BadRequest("No `url` or `field`.");
}
try {
$fieldData = new FieldData(
$field,
$parentType,
$relatedType
);
}
catch (Error $e) {
throw new BadRequest($e->getMessage());
}
return $this->injectableFactory
->create(UploadUrlService::class)
->uploadImage($url, $fieldData)
->getValueMap();
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws NotFound
*/
public function postActionGetCopiedAttachment(Request $request): stdClass
{
$data = $request->getParsedBody();
$id = $data->id ?? null;
$field = $data->field ?? null;
$parentType = $data->parentType ?? null;
$relatedType = $data->relatedType ?? null;
if (!$id || !$field) {
throw new BadRequest("No `id` or `field`.");
}
try {
$fieldData = new FieldData(
$field,
$parentType,
$relatedType
);
}
catch (Error $e) {
throw new BadRequest($e->getMessage());
}
return $this->getAttachmentService()
->copy($id, $fieldData)
->getValueMap();
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws NotFound
*/
public function getActionFile(Request $request, Response $response): void
{
$id = $request->getRouteParam('id');
if (!$id) {
throw new BadRequest();
}
$fileData = $this->getAttachmentService()->getFileData($id);
if ($fileData->getType()) {
$response->setHeader('Content-Type', $fileData->getType());
}
$response
->setHeader('Content-Disposition', 'attachment; filename="' . $fileData->getName() . '"')
->setHeader('Content-Length', (string) $fileData->getSize())
->setBody($fileData->getStream());
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws Error
* @throws NotFound
*/
public function postActionChunk(Request $request, Response $response): void
{
$id = $request->getRouteParam('id');
$body = $request->getBodyContents();
if (!$id || !$body) {
throw new BadRequest();
}
$this->injectableFactory
->create(UploadService::class)
->uploadChunk($id, $body);
$response->writeBody('true');
}
private function getAttachmentService(): Service
{
return $this->injectableFactory->create(Service::class);
}
}

View File

@@ -0,0 +1,44 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Controllers;
use Espo\Core\Controllers\RecordBase;
class AuthenticationProvider extends RecordBase
{
protected function checkAccess(): bool
{
if (!$this->user->isAdmin()) {
return false;
}
return true;
}
}

View File

@@ -32,26 +32,17 @@ namespace Espo\Controllers;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\{
Api\Request,
Api\Response,
Acl,
};
use Espo\Core\Acl;
use Espo\Core\Api\Request;
use Espo\Core\Api\Response;
use Espo\Tools\DataPrivacy\Erasor;
class DataPrivacy
{
private $erasor;
private $acl;
public function __construct(Erasor $erasor, Acl $acl)
public function __construct(private Erasor $erasor, private Acl $acl)
{
$this->erasor = $erasor;
$this->acl = $acl;
if ($this->acl->get('dataPrivacyPermission') === 'no') {
if ($this->acl->getPermissionLevel('dataPrivacyPermission') === Acl\Table::LEVEL_NO) {
throw new Forbidden();
}
}

View File

@@ -29,356 +29,7 @@
namespace Espo\Controllers;
use Espo\Core\Acl\Table;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Controllers\Record;
use Espo\Core\Api\Request;
use Espo\Core\Mail\SmtpParams;
use Espo\Entities\Email as EmailEntity;
use Espo\Tools\Attachment\FieldData;
use Espo\Tools\Email\SendService;
use Espo\Tools\Email\InboxService as InboxService;
use Espo\Tools\Email\Service;
use Espo\Tools\Email\TestSendData;
use Espo\Tools\EmailTemplate\InsertField\Service as InsertFieldService;
use stdClass;
class Email extends Record
{
/**
* @throws BadRequest
* @throws Forbidden
* @throws NotFound
*/
public function postActionGetCopiedAttachments(Request $request): stdClass
{
$data = $request->getParsedBody();
$id = $data->id ?? null;
$field = $data->field ?? null;
$parentType = $data->parentType ?? null;
$relatedType = $data->relatedType ?? null;
if (!$id || !$field) {
throw new BadRequest("No `id` or `field`.");
}
try {
$fieldData = new FieldData(
$field,
$parentType,
$relatedType
);
}
catch (Error $e) {
throw new BadRequest($e->getMessage());
}
$list = $this->injectableFactory
->create(Service::class)
->copyAttachments($id, $fieldData);
$ids = array_map(
fn ($item) => $item->getId(),
$list
);
$names = (object) [];
foreach ($list as $item) {
$names->{$item->getId()} = $item->getName();
}
return (object) [
'ids' => $ids,
'names' => $names,
];
}
/**
* @throws Forbidden
* @throws NotFound
* @throws Error
* @throws BadRequest
*/
public function postActionSendTestEmail(Request $request): bool
{
if (!$this->acl->checkScope(EmailEntity::ENTITY_TYPE)) {
throw new Forbidden();
}
$data = $request->getParsedBody();
$type = $data->type ?? null;
$id = $data->id ?? null;
$server = $data->server ?? null;
$port = $data->port ?? null;
$username = $data->username ?? null;
$password = $data->password ?? null;
$auth = $data->auth ?? null;
$authMechanism = $data->authMechanism ?? null;
$security = $data->security ?? null;
$userId = $data->userId ?? null;
$fromAddress = $data->fromAddress ?? null;
$fromName = $data->fromName ?? null;
$emailAddress = $data->emailAddress ?? null;
if (!is_string($server)) {
throw new BadRequest("`server`");
}
if (!is_int($port)) {
throw new BadRequest("`port`.");
}
if (!is_string($emailAddress)) {
throw new BadRequest("`emailAddress`.");
}
$smtpParams = SmtpParams
::create($server, $port)
->withSecurity($security)
->withFromName($fromName)
->withFromAddress($fromAddress)
->withAuth($auth);
if ($auth) {
$smtpParams = $smtpParams
->withUsername($username)
->withPassword($password)
->withAuthMechanism($authMechanism);
}
$data = new TestSendData($emailAddress, $type, $id, $userId);
$this->getSendService()->sendTestEmail($smtpParams, $data);
return true;
}
/**
* @throws BadRequest
*/
public function postActionMarkAsRead(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->markAsReadIdList($idList);
return true;
}
/**
* @throws BadRequest
*/
public function postActionMarkAsNotRead(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->markAsNotReadIdList($idList);
return true;
}
public function postActionMarkAllAsRead(): bool
{
$this->getInboxService()->markAllAsRead();
return true;
}
/**
* @throws BadRequest
*/
public function postActionMarkAsImportant(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->markAsImportantIdList($idList);
return true;
}
/**
* @throws BadRequest
*/
public function postActionMarkAsNotImportant(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->markAsNotImportantIdList($idList);
return true;
}
/**
* @throws BadRequest
*/
public function postActionMoveToTrash(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->moveToTrashIdList($idList);
return true;
}
/**
* @throws BadRequest
*/
public function postActionRetrieveFromTrash(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else {
if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
}
$this->getInboxService()->retrieveFromTrashIdList($idList);
return true;
}
public function getActionGetFoldersNotReadCounts(): stdClass
{
return (object) $this->getInboxService()->getFoldersNotReadCounts();
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws NotFound
*/
public function postActionMoveToFolder(Request $request): bool
{
$data = $request->getParsedBody();
if (!empty($data->ids)) {
$idList = $data->ids;
}
else if (!empty($data->id)) {
$idList = [$data->id];
}
else {
throw new BadRequest();
}
if (empty($data->folderId)) {
throw new BadRequest();
}
if (count($idList) === 1) {
$this->getInboxService()->moveToFolder($idList[0], $data->folderId);
return true;
}
$this->getInboxService()->moveToFolderIdList($idList, $data->folderId);
return true;
}
/**
* @throws Forbidden
*/
public function getActionGetInsertFieldData(Request $request): stdClass
{
if (!$this->acl->checkScope(EmailEntity::ENTITY_TYPE, Table::ACTION_CREATE)) {
throw new Forbidden();
}
return $this->injectableFactory
->create(InsertFieldService::class)
->getData(
$request->getQueryParam('parentType'),
$request->getQueryParam('parentId'),
$request->getQueryParam('to')
);
}
private function getInboxService(): InboxService
{
return $this->injectableFactory->create(InboxService::class);
}
private function getSendService(): SendService
{
return $this->injectableFactory->create(SendService::class);
}
}
{}

View File

@@ -29,52 +29,7 @@
namespace Espo\Controllers;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\BadRequest;
use Espo\Tools\Email\AddressService as Service;
use Espo\Core\Api\Request;
use Espo\Core\Controllers\RecordBase;
class EmailAddress extends RecordBase
{
private const ADDRESS_MAX_SIZE = 50;
/**
* @return array<int,array<string,mixed>>
* @throws Forbidden
* @throws BadRequest
*/
public function actionSearchInAddressBook(Request $request): array
{
if (!$this->acl->checkScope('Email')) {
throw new Forbidden();
}
if (!$this->acl->checkScope('Email', 'create')) {
throw new Forbidden();
}
$q = $request->getQueryParam('q');
if ($q === null) {
throw new BadRequest("No `q` parameter.");
}
$maxSize = intval($request->getQueryParam('maxSize'));
if (!$maxSize || $maxSize > self::ADDRESS_MAX_SIZE) {
$maxSize = (int) $this->config->get('recordsPerPage');
}
$onlyActual = $request->getQueryParam('onlyActual') === 'true';
return $this->getEmailAddressService()->searchInAddressBook($q, $maxSize, $onlyActual);
}
private function getEmailAddressService(): Service
{
return $this->injectableFactory->create(Service::class);
}
}
{}

View File

@@ -31,5 +31,4 @@ namespace Espo\Controllers;
class EmailFilter extends \Espo\Core\Controllers\Record
{
}

View File

@@ -29,48 +29,7 @@
namespace Espo\Controllers;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\ForbiddenSilent;
use Espo\Core\Exceptions\NotFound;
use Espo\Tools\EmailTemplate\Data;
use Espo\Tools\EmailTemplate\Service;
use Espo\Core\Api\Request;
use Espo\Core\Controllers\Record;
use stdClass;
class EmailTemplate extends Record
{
/**
* @throws BadRequest
* @throws NotFound
* @throws ForbiddenSilent
*/
public function actionParse(Request $request): stdClass
{
$id = $request->getQueryParam('id');
if ($id === null) {
throw new BadRequest("No `id`.");
}
$data = Data::create()
->withRelatedType($request->getQueryParam('relatedType'))
->withRelatedId($request->getQueryParam('relatedId'))
->withParentType($request->getQueryParam('parentType'))
->withParentId($request->getQueryParam('parentId'))
->withEmailAddress($request->getQueryParam('emailAddress'));
$result = $this->getEmailTemplateService()->process($id, $data);
return $result->getValueMap();
}
private function getEmailTemplateService(): Service
{
return $this->injectableFactory->create(Service::class);
}
}
{}

View File

@@ -31,5 +31,4 @@ namespace Espo\Controllers;
class EmailTemplateCategory extends \Espo\Core\Templates\Controllers\CategoryTree
{
}

View File

@@ -29,33 +29,35 @@
namespace Espo\Controllers;
use Espo\{
Entities\User,
Tools\EntityManager\EntityManager as EntityManagerTool,
};
use Espo\Core\Exceptions\Conflict;
use Espo\Core\Exceptions\Error;
use Espo\Entities\User;
use Espo\Tools\EntityManager\EntityManager as EntityManagerTool;
use Espo\Core\{
Exceptions\Forbidden,
Exceptions\BadRequest,
Api\Request,
};
use Espo\Core\Api\Request;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Forbidden;
class EntityManager
{
private $user;
private $entityManagerTool;
public function __construct(User $user, EntityManagerTool $entityManagerTool)
{
$this->user = $user;
$this->entityManagerTool = $entityManagerTool;
/**
* @throws Forbidden
*/
public function __construct(
private User $user,
private EntityManagerTool $entityManagerTool
) {
if (!$this->user->isAdmin()) {
throw new Forbidden();
}
}
/**
* @throws BadRequest
* @throws Error
* @throws Conflict
*/
public function postActionCreateEntity(Request $request): bool
{
$data = $request->getParsedBody();
@@ -137,6 +139,10 @@ class EntityManager
return true;
}
/**
* @throws BadRequest
* @throws Error
*/
public function postActionUpdateEntity(Request $request): bool
{
$data = $request->getParsedBody();
@@ -160,6 +166,11 @@ class EntityManager
return true;
}
/**
* @throws BadRequest
* @throws Forbidden
* @throws Error
*/
public function postActionRemoveEntity(Request $request): bool
{
$data = $request->getParsedBody();
@@ -183,6 +194,11 @@ class EntityManager
return true;
}
/**
* @throws BadRequest
* @throws Error
* @throws Conflict
*/
public function postActionCreateLink(Request $request): bool
{
$data = $request->getParsedBody();
@@ -361,6 +377,10 @@ class EntityManager
return true;
}
/**
* @throws BadRequest
* @throws Error
*/
public function postActionFormula(Request $request): bool
{
$data = $request->getParsedBody();

View File

@@ -32,12 +32,10 @@ namespace Espo\Controllers;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\{
Upgrades\ExtensionManager,
Controllers\RecordBase,
Api\Request,
Api\Response,
};
use Espo\Core\Api\Request;
use Espo\Core\Api\Response;
use Espo\Core\Controllers\RecordBase;
use Espo\Core\Upgrades\ExtensionManager;
use stdClass;

View File

@@ -29,36 +29,25 @@
namespace Espo\Controllers;
use Espo\{
Entities\User,
Tools\FieldManager\FieldManager as FieldManagerTool,
};
use Espo\Core\{
Exceptions\Conflict,
Exceptions\Error,
Exceptions\Forbidden,
Exceptions\BadRequest,
Api\Request,
DataManager};
use Espo\Entities\User;
use Espo\Tools\FieldManager\FieldManager as FieldManagerTool;
use Espo\Core\Api\Request;
use Espo\Core\DataManager;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Conflict;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
class FieldManager
{
private $user;
private $dataManager;
private $fieldManagerTool;
/**
* @throws Forbidden
*/
public function __construct(User $user, DataManager $dataManager, FieldManagerTool $fieldManagerTool)
{
$this->user = $user;
$this->dataManager = $dataManager;
$this->fieldManagerTool = $fieldManagerTool;
public function __construct(
private User $user,
private DataManager $dataManager,
private FieldManagerTool $fieldManagerTool
) {
$this->checkControllerAccess();
}
@@ -73,7 +62,7 @@ class FieldManager
}
/**
* @return array<string,mixed>
* @return array<string, mixed>
* @throws BadRequest
* @throws Error
*/
@@ -90,7 +79,7 @@ class FieldManager
}
/**
* @return array<string,mixed>
* @return array<string, mixed>
* @throws BadRequest
* @throws Conflict
* @throws Error
@@ -123,7 +112,7 @@ class FieldManager
}
/**
* @return array<string,mixed>
* @return array<string, mixed>
* @throws BadRequest
* @throws Error
*/
@@ -133,7 +122,7 @@ class FieldManager
}
/**
* @return array<string,mixed>
* @return array<string, mixed>
* @throws BadRequest
* @throws Error
*/
@@ -176,6 +165,7 @@ class FieldManager
$result = $this->fieldManagerTool->delete($scope, $name);
$this->dataManager->clearCache();
$this->dataManager->rebuildMetadata();
return $result;
@@ -189,14 +179,20 @@ class FieldManager
{
$data = $request->getParsedBody();
if (empty($data->scope) || empty($data->name)) {
$scope = $data->scope ?? null;
$name = $data->name ?? null;
if (!$scope || !$name) {
throw new BadRequest();
}
$this->fieldManagerTool->resetToDefault($data->scope, $data->name);
if (!is_string($scope) || !is_string($name)) {
throw new BadRequest();
}
$this->dataManager->clearCache();
$this->dataManager->rebuildMetadata();
$this->fieldManagerTool->resetToDefault($scope, $name);
$this->dataManager->rebuild([$scope]);
return true;
}

View File

@@ -43,7 +43,7 @@ class I18n
}
/**
* @return array<string,mixed>
* @return array<string, mixed>
*/
public function getActionRead(Request $request): array
{

Some files were not shown because too many files have changed in this diff Show More