mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-10 13:07:01 +00:00
Compare commits
2611 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd2204156e | ||
|
|
fe15eeeac7 | ||
|
|
280a1a9313 | ||
|
|
28227ddc2e | ||
|
|
b848261468 | ||
|
|
f1ff31829c | ||
|
|
0736285e24 | ||
|
|
a737711652 | ||
|
|
b5e8b89ed5 | ||
|
|
a51b45df90 | ||
|
|
5612055b85 | ||
|
|
e3aff78e89 | ||
|
|
84a7576772 | ||
|
|
69cd14f471 | ||
|
|
8c1494e17e | ||
|
|
50a6209f11 | ||
|
|
f0d508be6f | ||
|
|
e2b0aa65f8 | ||
|
|
930675672b | ||
|
|
b5ee03b142 | ||
|
|
a0d4fa5b82 | ||
|
|
317bbba8c9 | ||
|
|
3da95cce76 | ||
|
|
9a7cf5c35e | ||
|
|
b96ae74c14 | ||
|
|
7a420fb6f9 | ||
|
|
58d161210d | ||
|
|
41c7cf115d | ||
|
|
ba3bbfc097 | ||
|
|
7758e20224 | ||
|
|
a1cc2ee8c6 | ||
|
|
bdf397ad0f | ||
|
|
4dcae92ab7 | ||
|
|
1d4fedf7c7 | ||
|
|
24e6f2469f | ||
|
|
7b16d3541d | ||
|
|
3c9c3c9c8c | ||
|
|
f0413b7037 | ||
|
|
749f1a6a70 | ||
|
|
512a23ef64 | ||
|
|
23729c5b89 | ||
|
|
f31ee10cf7 | ||
|
|
21d34b091b | ||
|
|
fd19aa8b2e | ||
|
|
5af0b62e8e | ||
|
|
965cb33e34 | ||
|
|
aca19b3427 | ||
|
|
238baf89be | ||
|
|
50218a1146 | ||
|
|
d1280a8797 | ||
|
|
ca9358cf1a | ||
|
|
c3fa8f3131 | ||
|
|
4af110cd69 | ||
|
|
45d2d4306b | ||
|
|
385f01da8b | ||
|
|
85da160957 | ||
|
|
ff15f318c4 | ||
|
|
5769e1b58f | ||
|
|
028a7c728a | ||
|
|
9ec3889f96 | ||
|
|
3aa6502996 | ||
|
|
847f8713c9 | ||
|
|
7405476f61 | ||
|
|
985903e99b | ||
|
|
347f4e5566 | ||
|
|
085964dc58 | ||
|
|
6c0a1265ab | ||
|
|
655a499caa | ||
|
|
bcf6f33965 | ||
|
|
7c04febb3b | ||
|
|
4e7779ee48 | ||
|
|
4b17896ff1 | ||
|
|
caf20a5e61 | ||
|
|
896d42df43 | ||
|
|
1905be823d | ||
|
|
6347992b6e | ||
|
|
b695d7c148 | ||
|
|
9b75cdc2ac | ||
|
|
da80ed0130 | ||
|
|
e8a23de848 | ||
|
|
cb431a03df | ||
|
|
4979fb7326 | ||
|
|
aaae51bb37 | ||
|
|
4d860e3764 | ||
|
|
e73ba5c734 | ||
|
|
cca561f2c3 | ||
|
|
87c5089a8e | ||
|
|
a0819e8cdc | ||
|
|
ac505d9875 | ||
|
|
750f7ceb53 | ||
|
|
5be2a73801 | ||
|
|
5976fd5738 | ||
|
|
e6f09ed32a | ||
|
|
e2efb62a6a | ||
|
|
8ecfc75fac | ||
|
|
2c16a5bff7 | ||
|
|
47d049ab93 | ||
|
|
51ce0780fd | ||
|
|
a01e394a56 | ||
|
|
752b683494 | ||
|
|
2281d982f2 | ||
|
|
ad03cf92fc | ||
|
|
16ccf59d3f | ||
|
|
9e09f89927 | ||
|
|
53886ec684 | ||
|
|
fbc3e2cea9 | ||
|
|
2a7a4714ed | ||
|
|
19749aeca2 | ||
|
|
ee1dd28bc7 | ||
|
|
c1b0a3849d | ||
|
|
d721036226 | ||
|
|
9cce13af65 | ||
|
|
176abf90ad | ||
|
|
0bdeec10b6 | ||
|
|
29bd26a096 | ||
|
|
758e831cd5 | ||
|
|
95eea88a89 | ||
|
|
4c435b4d4b | ||
|
|
120f9fd07e | ||
|
|
7ca7a1ad18 | ||
|
|
f8dcd40905 | ||
|
|
039c67c6ca | ||
|
|
908d0ad3c4 | ||
|
|
1a70fdfd41 | ||
|
|
dc5c572a9f | ||
|
|
96be15c33b | ||
|
|
79793ebff6 | ||
|
|
d38c79c4ba | ||
|
|
ba02164d0b | ||
|
|
0cdbe89f5c | ||
|
|
46d8ec757f | ||
|
|
f4930b0a1f | ||
|
|
e03dc3b738 | ||
|
|
bfb7d88b79 | ||
|
|
2f3f2a0247 | ||
|
|
08f64eb209 | ||
|
|
15371a6a0f | ||
|
|
68ea55144d | ||
|
|
ec7e35e654 | ||
|
|
7e5a7546f2 | ||
|
|
86f67bd315 | ||
|
|
ca8cdd6008 | ||
|
|
5a60c5941a | ||
|
|
5487bd7598 | ||
|
|
ea8c4d348d | ||
|
|
a56a6b01f4 | ||
|
|
bfe91a37e8 | ||
|
|
ecd61eb4e9 | ||
|
|
ffd05882f2 | ||
|
|
f8eb7679fd | ||
|
|
68fa506f32 | ||
|
|
c1e4ca4850 | ||
|
|
31a507cd4a | ||
|
|
58a89146c9 | ||
|
|
d70461db9f | ||
|
|
bddd310ac7 | ||
|
|
f46bc47bba | ||
|
|
579e134303 | ||
|
|
b92fd15ece | ||
|
|
4ef307e8e7 | ||
|
|
58fca25b3e | ||
|
|
efaf1fab79 | ||
|
|
e6beedbffd | ||
|
|
d718151dbe | ||
|
|
cb79354078 | ||
|
|
94d2873669 | ||
|
|
46b269fa0e | ||
|
|
43a233a4ba | ||
|
|
7cc33bd684 | ||
|
|
0937c83746 | ||
|
|
0ae81328b4 | ||
|
|
68a7130e85 | ||
|
|
da41370c29 | ||
|
|
836ffff49f | ||
|
|
350819033d | ||
|
|
5c47b6c653 | ||
|
|
f37fd5e013 | ||
|
|
100b44791d | ||
|
|
cf7f8260c9 | ||
|
|
bc06e39f90 | ||
|
|
42a8f8b438 | ||
|
|
6b04536c3a | ||
|
|
4ff8514925 | ||
|
|
30b4b8d501 | ||
|
|
23d78e1e46 | ||
|
|
65ca47b878 | ||
|
|
a2ac9c2d4c | ||
|
|
87048ce9af | ||
|
|
846c8040a3 | ||
|
|
f993d676fc | ||
|
|
00d04e0157 | ||
|
|
461034f9cc | ||
|
|
16b61d9484 | ||
|
|
afbd3919b7 | ||
|
|
ec1887e726 | ||
|
|
b9fc41d5cd | ||
|
|
216e1061d2 | ||
|
|
934b7a9369 | ||
|
|
6b62841fba | ||
|
|
644f653bdd | ||
|
|
bdfe6b5e23 | ||
|
|
01e0d51c0a | ||
|
|
6acd18b4c6 | ||
|
|
9ac36cd5da | ||
|
|
cbc581ad9f | ||
|
|
9845ed2db3 | ||
|
|
87e95dc791 | ||
|
|
51ca68531a | ||
|
|
eb78b921a7 | ||
|
|
1d6bedcfad | ||
|
|
36ca2daee0 | ||
|
|
f000fb6f29 | ||
|
|
170ff67ea8 | ||
|
|
d196347b22 | ||
|
|
b2d7cfa187 | ||
|
|
2c3f6baaac | ||
|
|
0060f70586 | ||
|
|
22fd7cb6b3 | ||
|
|
9d7246832d | ||
|
|
03eb8db555 | ||
|
|
3f2364cd8d | ||
|
|
f1c0ccf97d | ||
|
|
ceddfd8486 | ||
|
|
eaed64fe6a | ||
|
|
69d88f9b76 | ||
|
|
1e51f1b97c | ||
|
|
ef7e620b8b | ||
|
|
99c2f30394 | ||
|
|
ccc231a06e | ||
|
|
b4aa1392d5 | ||
|
|
4aec7251a6 | ||
|
|
5ff9e42887 | ||
|
|
a9d4046337 | ||
|
|
b1e8266d89 | ||
|
|
1a4b891b05 | ||
|
|
0191188eba | ||
|
|
833cd4f5ee | ||
|
|
bea8f4d4bd | ||
|
|
d59874801d | ||
|
|
2ffae46291 | ||
|
|
48b79dfdb1 | ||
|
|
52bdfc128c | ||
|
|
c9adeecd1b | ||
|
|
4bfdbcc207 | ||
|
|
0a4b261529 | ||
|
|
dc6a7f241e | ||
|
|
da39015a7c | ||
|
|
8ba1907b45 | ||
|
|
eea3efeb95 | ||
|
|
991e3f8cc3 | ||
|
|
25a09f5ec3 | ||
|
|
86413517e6 | ||
|
|
747d581f9a | ||
|
|
1d4030b29e | ||
|
|
80fa7407d4 | ||
|
|
495e700373 | ||
|
|
5c583a697d | ||
|
|
24b935c789 | ||
|
|
df0da5e51b | ||
|
|
485dfd32fd | ||
|
|
51a6b304f2 | ||
|
|
93e467af79 | ||
|
|
c5eb6c560b | ||
|
|
dd1a74b4c0 | ||
|
|
5fa73b2581 | ||
|
|
f70e1bd38e | ||
|
|
5dd845327e | ||
|
|
bc84a9be51 | ||
|
|
39442377a3 | ||
|
|
b9126d2c0f | ||
|
|
1f982031ca | ||
|
|
3961dcaad4 | ||
|
|
a91c63c6a9 | ||
|
|
7f328927ba | ||
|
|
8491a54248 | ||
|
|
79bc6a9aea | ||
|
|
d899e8d3df | ||
|
|
3ef6de205f | ||
|
|
fa02291a1a | ||
|
|
5096870635 | ||
|
|
7cb086d5c9 | ||
|
|
9e9a72af91 | ||
|
|
62f2c9658a | ||
|
|
4015e2f254 | ||
|
|
aa51a58da5 | ||
|
|
a12ee989f6 | ||
|
|
ab137263dc | ||
|
|
77e02fd66f | ||
|
|
0d1466afac | ||
|
|
4f4db967f8 | ||
|
|
6beaa730ea | ||
|
|
31a84a6e53 | ||
|
|
761e7b7b72 | ||
|
|
b0547325ca | ||
|
|
914f90214a | ||
|
|
be2d936be9 | ||
|
|
1f48e3d005 | ||
|
|
50f7165963 | ||
|
|
55453b95ab | ||
|
|
27d7e6e522 | ||
|
|
abca847e5a | ||
|
|
6d28fab610 | ||
|
|
a8b315b35d | ||
|
|
206e3e787e | ||
|
|
26ab145380 | ||
|
|
5518d71bbe | ||
|
|
4fbfd1e123 | ||
|
|
099e0745f5 | ||
|
|
ef0c9e86a9 | ||
|
|
ca39deb818 | ||
|
|
0cc88a395f | ||
|
|
706cb66021 | ||
|
|
a33d49b151 | ||
|
|
71bb9d7d18 | ||
|
|
0ef26a7929 | ||
|
|
d77e56ec5d | ||
|
|
45f9e2af59 | ||
|
|
cc89b69f18 | ||
|
|
d39376398a | ||
|
|
1016b61835 | ||
|
|
5a2c027f17 | ||
|
|
c030f375bf | ||
|
|
8d7d5527a1 | ||
|
|
91915ccf44 | ||
|
|
d92bf08160 | ||
|
|
46f3846d36 | ||
|
|
841b0f4ebf | ||
|
|
5c4e4613e7 | ||
|
|
8b800d7757 | ||
|
|
670df99eda | ||
|
|
e3b42ab084 | ||
|
|
dcd0f6f56b | ||
|
|
f7cab7d42d | ||
|
|
3778e2640e | ||
|
|
b399a8dd78 | ||
|
|
6a45db8e1c | ||
|
|
6c89147b2c | ||
|
|
dff3321540 | ||
|
|
9592e68c30 | ||
|
|
5ebd680d64 | ||
|
|
603ac2b985 | ||
|
|
6efff8e9d0 | ||
|
|
a8a46976de | ||
|
|
cd3a2bbc80 | ||
|
|
bb2259232e | ||
|
|
fdc9a98c1d | ||
|
|
761df3c562 | ||
|
|
11bd9c7d8f | ||
|
|
bf24bfda43 | ||
|
|
389dda2866 | ||
|
|
86026f8f7e | ||
|
|
c0e82c6c00 | ||
|
|
57e733754a | ||
|
|
ceb67c5b95 | ||
|
|
a164c33829 | ||
|
|
120d090215 | ||
|
|
a5139255f2 | ||
|
|
f5d5c4e75e | ||
|
|
fca55da02f | ||
|
|
0a5a82fb38 | ||
|
|
b53378a1d3 | ||
|
|
ceb436971d | ||
|
|
9522446955 | ||
|
|
3eedeef605 | ||
|
|
07f49c56ff | ||
|
|
5031b17e8a | ||
|
|
42642de0e6 | ||
|
|
b4c5596b54 | ||
|
|
cbb5aaa6dd | ||
|
|
2383194f07 | ||
|
|
21cbf390fd | ||
|
|
db2c7f2c7b | ||
|
|
e7994caf72 | ||
|
|
f775f0467b | ||
|
|
fd5c7763bc | ||
|
|
d34c8d1918 | ||
|
|
40d62c4213 | ||
|
|
a12031f7bc | ||
|
|
15b04590af | ||
|
|
2e75c2815e | ||
|
|
8677229785 | ||
|
|
71193a9071 | ||
|
|
cefc0e9bdf | ||
|
|
cf41312a01 | ||
|
|
457b79f0a0 | ||
|
|
d3f4131353 | ||
|
|
b07ef24eea | ||
|
|
8fd430b784 | ||
|
|
593bf44b29 | ||
|
|
1578ed8d8f | ||
|
|
ef17859145 | ||
|
|
3e8d2f8037 | ||
|
|
9077c00386 | ||
|
|
7212e0ed20 | ||
|
|
db92247b65 | ||
|
|
daf86f89da | ||
|
|
4ffe89bb4a | ||
|
|
19e769d107 | ||
|
|
8cc4ffdd80 | ||
|
|
8f6b418f03 | ||
|
|
00e6b710f3 | ||
|
|
d5ee58cbbc | ||
|
|
3ffebd2d8d | ||
|
|
1fd96cc423 | ||
|
|
bcadb93f66 | ||
|
|
ba28639f11 | ||
|
|
60bca1635e | ||
|
|
908caa7009 | ||
|
|
896e1f7119 | ||
|
|
07b42b48a3 | ||
|
|
196488f92d | ||
|
|
5c811b1861 | ||
|
|
7300bec9c7 | ||
|
|
ffbfe1ca5a | ||
|
|
7150f49634 | ||
|
|
316ca559bd | ||
|
|
17c2204dd3 | ||
|
|
17728b76f1 | ||
|
|
b0920bf63f | ||
|
|
2731e6cb8e | ||
|
|
bbc3e9c196 | ||
|
|
4e4186ebf2 | ||
|
|
1e9648256f | ||
|
|
3166bc92b9 | ||
|
|
52c8b3c312 | ||
|
|
08c381cc90 | ||
|
|
919242910d | ||
|
|
03d68032bf | ||
|
|
5e4c076b87 | ||
|
|
b150d84932 | ||
|
|
f5a709fd56 | ||
|
|
b1cab62b95 | ||
|
|
b5bef88a8d | ||
|
|
0e8b9e950b | ||
|
|
3e021cd3aa | ||
|
|
98022fdb79 | ||
|
|
687187c69c | ||
|
|
17ca4fa69e | ||
|
|
3546ade6ab | ||
|
|
78c5ec8a0c | ||
|
|
d9e2acbf92 | ||
|
|
fb5034b276 | ||
|
|
1898ccbd6b | ||
|
|
a635bc246a | ||
|
|
642b63d68e | ||
|
|
d7ed77396c | ||
|
|
205ad80e51 | ||
|
|
8592a411ee | ||
|
|
61d78e8f76 | ||
|
|
bad19eea2e | ||
|
|
16ffca9590 | ||
|
|
846e3eb01a | ||
|
|
feeda48844 | ||
|
|
9e4c555ab1 | ||
|
|
dbf20bfff6 | ||
|
|
9449d8364b | ||
|
|
03131507bc | ||
|
|
0b0a1943d0 | ||
|
|
4d5899ef55 | ||
|
|
93ddee9eee | ||
|
|
90e435f495 | ||
|
|
7da39f4228 | ||
|
|
b7025bf834 | ||
|
|
bc4dbacafb | ||
|
|
80c2a69d39 | ||
|
|
36e59d3d61 | ||
|
|
37f8247bbf | ||
|
|
ead8f77267 | ||
|
|
b465d88531 | ||
|
|
a2e37e05a6 | ||
|
|
518e57e316 | ||
|
|
258d2f03f2 | ||
|
|
1b212b27d7 | ||
|
|
2e927fd4dc | ||
|
|
cbc58e2ebf | ||
|
|
a2fd0dc985 | ||
|
|
a89a399b87 | ||
|
|
bb018f6a0f | ||
|
|
6e01ac50c8 | ||
|
|
50c5f5974d | ||
|
|
fce940a291 | ||
|
|
e08459d1c6 | ||
|
|
5b6889d554 | ||
|
|
80babbca13 | ||
|
|
7208966e1d | ||
|
|
48c1a5d6d3 | ||
|
|
930f45b93a | ||
|
|
992fad8102 | ||
|
|
420662132c | ||
|
|
d54e77a63f | ||
|
|
0b60fbbb59 | ||
|
|
0f94a7b65e | ||
|
|
f8bbc0918c | ||
|
|
6e5b4b1483 | ||
|
|
15130fbe28 | ||
|
|
27f0d9fb86 | ||
|
|
ecf7dc54e0 | ||
|
|
0598e82196 | ||
|
|
32abc4b554 | ||
|
|
d499719c08 | ||
|
|
c105af939f | ||
|
|
444245d2e1 | ||
|
|
63aaa2fbb0 | ||
|
|
3da9c3da8d | ||
|
|
381524203b | ||
|
|
347a8aa660 | ||
|
|
4a83eb125d | ||
|
|
bfddc4ba90 | ||
|
|
932e5ce461 | ||
|
|
fb45af1048 | ||
|
|
5aa154459d | ||
|
|
41139f52c8 | ||
|
|
e5a0774e3e | ||
|
|
0f020bb3ba | ||
|
|
c3d1c773e0 | ||
|
|
38dd599b1e | ||
|
|
701cc2a6d7 | ||
|
|
fc9e06d7aa | ||
|
|
ba10c9278f | ||
|
|
2a0b645a2d | ||
|
|
c324b63917 | ||
|
|
da425df98f | ||
|
|
005356d6c3 | ||
|
|
0d1cc3dac9 | ||
|
|
19ae21d6b3 | ||
|
|
4d1a2ae4df | ||
|
|
a7d8d9b0e0 | ||
|
|
98922f0b84 | ||
|
|
5784c79f9f | ||
|
|
b027b36b54 | ||
|
|
91100974c3 | ||
|
|
1f6300e3a4 | ||
|
|
94b15991ac | ||
|
|
3b976b6d26 | ||
|
|
90a18de806 | ||
|
|
0e5ff9f64a | ||
|
|
3fed1a5ae8 | ||
|
|
3b414d1077 | ||
|
|
4cb67cd4df | ||
|
|
be632b485d | ||
|
|
7edf109743 | ||
|
|
ad8ee0e8ed | ||
|
|
9b9f1e84d5 | ||
|
|
fba89354b2 | ||
|
|
45b3ec5cde | ||
|
|
095f82df1c | ||
|
|
008a37701f | ||
|
|
f563194445 | ||
|
|
38360e7e78 | ||
|
|
c30b907aa0 | ||
|
|
7ec559ea42 | ||
|
|
91aeacbf35 | ||
|
|
223304bc63 | ||
|
|
a4910e5a84 | ||
|
|
34f5d9d5b1 | ||
|
|
be62327509 | ||
|
|
9832bb54f9 | ||
|
|
09b0d68786 | ||
|
|
99da14b29b | ||
|
|
e4102aa1f7 | ||
|
|
00f63b87a3 | ||
|
|
692940047e | ||
|
|
cdf8a43b28 | ||
|
|
d24ad99f26 | ||
|
|
b9b62e9f85 | ||
|
|
e3d53056d1 | ||
|
|
75e8cf538a | ||
|
|
80c2944f0e | ||
|
|
b3f58b8002 | ||
|
|
83634706c2 | ||
|
|
44b96270a3 | ||
|
|
ecffd310b7 | ||
|
|
8d2238e04a | ||
|
|
d6f0bc063e | ||
|
|
4bec0b4795 | ||
|
|
a90182a7b1 | ||
|
|
cf44d4f154 | ||
|
|
231720a9a0 | ||
|
|
26ab4abdec | ||
|
|
daab13b78a | ||
|
|
27946bcbac | ||
|
|
ee636131f5 | ||
|
|
71f5205c28 | ||
|
|
f9b46b3b95 | ||
|
|
5d6e1319c0 | ||
|
|
cdbf680788 | ||
|
|
8118e27bd8 | ||
|
|
5006e2e4fa | ||
|
|
6b85fb95a2 | ||
|
|
395fda2c5a | ||
|
|
9408a1637d | ||
|
|
09de0e3664 | ||
|
|
e8b3582040 | ||
|
|
3bff5e3fb7 | ||
|
|
e886293495 | ||
|
|
56d57c3fee | ||
|
|
03ade6eabc | ||
|
|
732ed8924d | ||
|
|
87051573d8 | ||
|
|
bd66449507 | ||
|
|
e899a82840 | ||
|
|
aba0c21f71 | ||
|
|
03838cfae8 | ||
|
|
61772b8e40 | ||
|
|
b445de322c | ||
|
|
db2b8b63be | ||
|
|
d355db6bb1 | ||
|
|
a529edc4b2 | ||
|
|
d1effdae81 | ||
|
|
a7b959a1d9 | ||
|
|
951f026f8f | ||
|
|
1c8506eee4 | ||
|
|
22f309e02a | ||
|
|
4d9d9e4569 | ||
|
|
9e1cbc5fc0 | ||
|
|
6ba2733492 | ||
|
|
35d0ebe974 | ||
|
|
5e8efcd269 | ||
|
|
2440eb5e95 | ||
|
|
b8d2f9de30 | ||
|
|
7a2ff40776 | ||
|
|
56fff07662 | ||
|
|
434b4f880f | ||
|
|
f596d12e02 | ||
|
|
c4be84af32 | ||
|
|
a2b2118f9f | ||
|
|
7fee372f3d | ||
|
|
e3fe496321 | ||
|
|
5c890d3e0e | ||
|
|
496d132c23 | ||
|
|
68fb2d45e1 | ||
|
|
e44b0d2c22 | ||
|
|
5e87a410c8 | ||
|
|
6f34b040cf | ||
|
|
0d0ad8b581 | ||
|
|
a3eac057fc | ||
|
|
489b3a7629 | ||
|
|
45aff4a7b7 | ||
|
|
4653caef47 | ||
|
|
1d9b988206 | ||
|
|
ebedd6d722 | ||
|
|
b0311d1610 | ||
|
|
158573f63e | ||
|
|
93172f42b7 | ||
|
|
b3476fe3dd | ||
|
|
1f85781c68 | ||
|
|
595548acf0 | ||
|
|
a32fffb36d | ||
|
|
3de5961c86 | ||
|
|
1b4727917b | ||
|
|
499cf36edf | ||
|
|
bb1856a47e | ||
|
|
0226a6a4f7 | ||
|
|
6c9a542b9c | ||
|
|
59ae933886 | ||
|
|
b22464c02f | ||
|
|
4615781af8 | ||
|
|
ce0efea447 | ||
|
|
378a2c6902 | ||
|
|
ab3fc73a18 | ||
|
|
b3c56acd15 | ||
|
|
2c9b60dbec | ||
|
|
620a18cd72 | ||
|
|
ba832b8ad9 | ||
|
|
bcfffd3527 | ||
|
|
022da56bf4 | ||
|
|
12549e2587 | ||
|
|
57ab075d2f | ||
|
|
1510322708 | ||
|
|
22c06c88dd | ||
|
|
7a4b20269d | ||
|
|
79d76d8147 | ||
|
|
2bf2e4ef3d | ||
|
|
61ec16ae12 | ||
|
|
8415307221 | ||
|
|
6da466f9c4 | ||
|
|
210ac2ef2a | ||
|
|
988f8090f2 | ||
|
|
e2db825fc2 | ||
|
|
cc9ed3f365 | ||
|
|
0763b71396 | ||
|
|
af2158f647 | ||
|
|
4ad636a767 | ||
|
|
dffb484fff | ||
|
|
6582917daf | ||
|
|
7bd109eca6 | ||
|
|
c0d85864ce | ||
|
|
7007d58609 | ||
|
|
23a54a0fa4 | ||
|
|
491a66ac4c | ||
|
|
e5c3bfb528 | ||
|
|
f807bdee42 | ||
|
|
67b3462361 | ||
|
|
cd1eccd998 | ||
|
|
63b108b18b | ||
|
|
3907e2d84a | ||
|
|
4deeac9513 | ||
|
|
4c11bf663b | ||
|
|
d8649cb305 | ||
|
|
eff2a022bf | ||
|
|
ad61b457d8 | ||
|
|
22c3c92792 | ||
|
|
5919016aad | ||
|
|
14c12a2528 | ||
|
|
bca1f08f05 | ||
|
|
2ce656731d | ||
|
|
6d7fb4939d | ||
|
|
3cb8deab2c | ||
|
|
b501007d44 | ||
|
|
70f7312f20 | ||
|
|
b7b5b1b3cb | ||
|
|
44001d9764 | ||
|
|
5dcfbf00d2 | ||
|
|
8ca52259cd | ||
|
|
f4753f773f | ||
|
|
0f3f9a827b | ||
|
|
a90745aded | ||
|
|
96a1ab6ad6 | ||
|
|
f49b6a072c | ||
|
|
146ca6ae2a | ||
|
|
b775e16c1f | ||
|
|
043df4bc73 | ||
|
|
7d660f5127 | ||
|
|
71064cd6ee | ||
|
|
93f2f962e2 | ||
|
|
8eb7f932fc | ||
|
|
d2fb6edde1 | ||
|
|
ed59886897 | ||
|
|
07b6c64640 | ||
|
|
420e5fa3a5 | ||
|
|
3e12428e54 | ||
|
|
4d2a2e9b20 | ||
|
|
5650a00ab1 | ||
|
|
2eb42a3313 | ||
|
|
84d4d4f11b | ||
|
|
b6a9182838 | ||
|
|
a6593f574e | ||
|
|
d277df1e49 | ||
|
|
5721f6d737 | ||
|
|
a07b7530df | ||
|
|
bff4e859cd | ||
|
|
0944d47c47 | ||
|
|
d725cce8a7 | ||
|
|
a730f47ceb | ||
|
|
8e3d743023 | ||
|
|
cdb2b8a8a8 | ||
|
|
a453be93be | ||
|
|
3cef36da3e | ||
|
|
691343c9b2 | ||
|
|
2453fe9ea5 | ||
|
|
c0594b80e9 | ||
|
|
5239df2b95 | ||
|
|
0f1ac3af10 | ||
|
|
d5f42a46b3 | ||
|
|
0ae6fdbac2 | ||
|
|
f214aaba2a | ||
|
|
67a4208b3b | ||
|
|
5991bb948b | ||
|
|
50bfa1ae99 | ||
|
|
409f19bb29 | ||
|
|
c631dd7a0f | ||
|
|
db74afcfb4 | ||
|
|
ac6bdcc30a | ||
|
|
2556f89637 | ||
|
|
3ec25d5a97 | ||
|
|
c9bdd8231b | ||
|
|
9d372155fb | ||
|
|
4ebdcf3637 | ||
|
|
150e41a26d | ||
|
|
79c4a8351d | ||
|
|
0f6c340793 | ||
|
|
c7fe7ac014 | ||
|
|
a0939c714c | ||
|
|
d57098dd50 | ||
|
|
4b521d1481 | ||
|
|
919cea0703 | ||
|
|
6aa372c955 | ||
|
|
0e873fea52 | ||
|
|
44003e8130 | ||
|
|
2a4bd851ab | ||
|
|
cb5fdfba85 | ||
|
|
8973959910 | ||
|
|
383f411739 | ||
|
|
c500b30484 | ||
|
|
91fec4ff95 | ||
|
|
5266e8eeba | ||
|
|
d96bf13526 | ||
|
|
bf017ccc8a | ||
|
|
c1ca41942f | ||
|
|
8c8e44b6f5 | ||
|
|
f95824404a | ||
|
|
4eecc5462b | ||
|
|
3a96cbae9b | ||
|
|
77f3d81f27 | ||
|
|
7343e08abb | ||
|
|
3b7b6e9ed7 | ||
|
|
70a9fd95a2 | ||
|
|
c0e64583e5 | ||
|
|
211f6bdc42 | ||
|
|
f07440f9ef | ||
|
|
7f37cd40eb | ||
|
|
b0d7b33dbc | ||
|
|
35905aad1b | ||
|
|
62b27475fb | ||
|
|
0985df234f | ||
|
|
a05650a41a | ||
|
|
0c0744714e | ||
|
|
cd60933525 | ||
|
|
2d3deafcc6 | ||
|
|
25508b932e | ||
|
|
05d3610f5f | ||
|
|
5b0ef914c2 | ||
|
|
35f2ccecf5 | ||
|
|
122d759687 | ||
|
|
a2c94c692a | ||
|
|
e197c6e491 | ||
|
|
62ff80c1bf | ||
|
|
3a7cccbda2 | ||
|
|
3bab92239a | ||
|
|
cc0b12097d | ||
|
|
fe09d91bf0 | ||
|
|
593ed7c5e0 | ||
|
|
e161b0da19 | ||
|
|
31a2ef63ec | ||
|
|
facc26a795 | ||
|
|
fb4a4f2340 | ||
|
|
42cab04edd | ||
|
|
247521ba37 | ||
|
|
9f932462a8 | ||
|
|
3f7c42a05e | ||
|
|
3ca502ba6e | ||
|
|
8afe22f637 | ||
|
|
a615eed985 | ||
|
|
df56679c4e | ||
|
|
23b2e87127 | ||
|
|
9391c68ad0 | ||
|
|
8a15278af2 | ||
|
|
8f2c12cba7 | ||
|
|
842c028fb5 | ||
|
|
27aae16634 | ||
|
|
0206da6d4f | ||
|
|
687f308b40 | ||
|
|
20eced4373 | ||
|
|
7d0c793e47 | ||
|
|
ead21ea2ee | ||
|
|
45ef1a4de5 | ||
|
|
28b866830e | ||
|
|
4d68e35f3b | ||
|
|
12a2069fcf | ||
|
|
b87d2459cc | ||
|
|
7c1c25577c | ||
|
|
9d6e0ba54b | ||
|
|
bd3c6867b5 | ||
|
|
28c4b8ea05 | ||
|
|
7a90e30243 | ||
|
|
f482c41e6c | ||
|
|
06ffafba10 | ||
|
|
2a07124d52 | ||
|
|
65247b1c69 | ||
|
|
10e4b7e5b6 | ||
|
|
ff3e6c34ba | ||
|
|
19700cfa00 | ||
|
|
d0de9e5bb9 | ||
|
|
9861653378 | ||
|
|
0a4525b75e | ||
|
|
1c45cadcf8 | ||
|
|
83ced0d58f | ||
|
|
6ee224ffbc | ||
|
|
a060f0732b | ||
|
|
4e2a824b1d | ||
|
|
85c4848614 | ||
|
|
a5ca838b7a | ||
|
|
1127f4b28c | ||
|
|
e68ff3c391 | ||
|
|
c257da0e70 | ||
|
|
7669ac90ae | ||
|
|
5e7ddcad1c | ||
|
|
1cf773216d | ||
|
|
da3283f2ba | ||
|
|
18d6a6767b | ||
|
|
f8fd222e25 | ||
|
|
fd7819f76a | ||
|
|
48cfedb777 | ||
|
|
9220ad8baa | ||
|
|
6207c8f547 | ||
|
|
b9e1660f92 | ||
|
|
8863e7da9b | ||
|
|
3b1462ac1a | ||
|
|
937503ab8b | ||
|
|
b3edfba0da | ||
|
|
01a1d26a52 | ||
|
|
4662fc47e9 | ||
|
|
5b543d778d | ||
|
|
798f56650d | ||
|
|
864c96fe56 | ||
|
|
4d5eecd680 | ||
|
|
db2216adb7 | ||
|
|
ae056f4a22 | ||
|
|
5178c2fbd0 | ||
|
|
4bedaef9a8 | ||
|
|
42d4de77ae | ||
|
|
3e0a8f0af1 | ||
|
|
33e29e20a2 | ||
|
|
d2a1e8f771 | ||
|
|
3a68ebcbf4 | ||
|
|
f496f386ee | ||
|
|
9e641e65ed | ||
|
|
d34bc6d7d2 | ||
|
|
7581169f87 | ||
|
|
7c53701df5 | ||
|
|
d273523c46 | ||
|
|
df6745ff79 | ||
|
|
9327b418bf | ||
|
|
5430fed1d1 | ||
|
|
10285cf3d3 | ||
|
|
c8bed9af32 | ||
|
|
7499703d77 | ||
|
|
4e1f421dc1 | ||
|
|
4ab2a0749c | ||
|
|
530ac9da18 | ||
|
|
4069d38978 | ||
|
|
4070b38190 | ||
|
|
718f3ddc9f | ||
|
|
e4be18ac51 | ||
|
|
fa63270530 | ||
|
|
54286984e9 | ||
|
|
523e4d2900 | ||
|
|
79af0d2cc7 | ||
|
|
4152ee10ea | ||
|
|
c41b92d15a | ||
|
|
5af9679751 | ||
|
|
c51fcf0cb6 | ||
|
|
41d4735502 | ||
|
|
7c3964c6f5 | ||
|
|
df744ba263 | ||
|
|
380b3dde0a | ||
|
|
4c696c8b21 | ||
|
|
95f9206880 | ||
|
|
e00557885f | ||
|
|
9aaab7d726 | ||
|
|
ab9f78d33f | ||
|
|
ac57f6a39a | ||
|
|
49077225c6 | ||
|
|
f3a13739c0 | ||
|
|
ae4d37498a | ||
|
|
25a607952c | ||
|
|
51cfbb0779 | ||
|
|
15c97e5d12 | ||
|
|
4847bc019a | ||
|
|
094f6e2f50 | ||
|
|
6cc19a52f1 | ||
|
|
f0237005c0 | ||
|
|
3aa31a830c | ||
|
|
c61513cf84 | ||
|
|
d10b6dd9b3 | ||
|
|
b466f91f8a | ||
|
|
7081440121 | ||
|
|
5042f58e30 | ||
|
|
beb51081d3 | ||
|
|
1997da4343 | ||
|
|
0b3f3e67dd | ||
|
|
e9d7b92a6e | ||
|
|
334d5609b0 | ||
|
|
6e31c591bd | ||
|
|
d125d8f067 | ||
|
|
49b55236d0 | ||
|
|
093001bf95 | ||
|
|
3445f87e0c | ||
|
|
8d3ba52501 | ||
|
|
82a7590a2a | ||
|
|
773df7aedd | ||
|
|
424ca82b15 | ||
|
|
e5df6ad7bf | ||
|
|
d81f8f7bed | ||
|
|
7203b652fa | ||
|
|
5d5268c2c7 | ||
|
|
b568e96407 | ||
|
|
1dda881422 | ||
|
|
17d2791d40 | ||
|
|
9469b66c61 | ||
|
|
bbc16b942e | ||
|
|
2cb235f49c | ||
|
|
e2a7a439d2 | ||
|
|
2c19ebf570 | ||
|
|
19d799ac5e | ||
|
|
e89a0955ea | ||
|
|
fc6dfd1994 | ||
|
|
3fa33b6706 | ||
|
|
939daa616b | ||
|
|
fd22f50de2 | ||
|
|
48ca9259af | ||
|
|
c49d3d4c30 | ||
|
|
246b0c2a37 | ||
|
|
33f446401b | ||
|
|
9c677463f2 | ||
|
|
786e267e93 | ||
|
|
c782743a24 | ||
|
|
b2c4c76fba | ||
|
|
5a6660b60d | ||
|
|
f5d324eb48 | ||
|
|
901e0967fc | ||
|
|
1cfacc3813 | ||
|
|
8f1c7d5d54 | ||
|
|
3427c1b0bd | ||
|
|
4a12d44971 | ||
|
|
d833d43a8b | ||
|
|
64a3b851b6 | ||
|
|
2a0ceceb2f | ||
|
|
7250e0e5c4 | ||
|
|
40161fdc3c | ||
|
|
cb815d7dea | ||
|
|
fffe4aacc1 | ||
|
|
985c12c918 | ||
|
|
87bbf61c66 | ||
|
|
8f204de057 | ||
|
|
419b08070a | ||
|
|
ba1d4d7b72 | ||
|
|
a48b5df28e | ||
|
|
07bbc42df5 | ||
|
|
14e77571c0 | ||
|
|
71a35878c1 | ||
|
|
7dc74f0767 | ||
|
|
784d12f3ca | ||
|
|
cdf9700ff0 | ||
|
|
05f926b33b | ||
|
|
b05f2acc34 | ||
|
|
67b52d1f42 | ||
|
|
6391c3ca08 | ||
|
|
fc59a1efa1 | ||
|
|
e215e39e5d | ||
|
|
33e1f48717 | ||
|
|
94f61e5aff | ||
|
|
41b25a43ba | ||
|
|
09e617ee78 | ||
|
|
f5f8b2f66a | ||
|
|
45b9b41557 | ||
|
|
e0a1b983e3 | ||
|
|
4d2b339112 | ||
|
|
b1a66e4a20 | ||
|
|
1e44f82b38 | ||
|
|
487f428c7f | ||
|
|
f5fa51854d | ||
|
|
3f15295293 | ||
|
|
de72c2b055 | ||
|
|
8f93507fec | ||
|
|
2afaf8b446 | ||
|
|
33e0a1b228 | ||
|
|
4b7dd1fd22 | ||
|
|
6f7ef14482 | ||
|
|
097a115595 | ||
|
|
cd78458d19 | ||
|
|
b69d706cc4 | ||
|
|
8286d7b621 | ||
|
|
d899c55f4f | ||
|
|
0a954e171d | ||
|
|
89d2c38257 | ||
|
|
d7829e7801 | ||
|
|
3d4f6055e4 | ||
|
|
383ae3fe3e | ||
|
|
47cbd18c88 | ||
|
|
d5779878c7 | ||
|
|
c65cabffd5 | ||
|
|
fe90a62239 | ||
|
|
13ae33266f | ||
|
|
399b689bcd | ||
|
|
1219e7be12 | ||
|
|
10f67ab360 | ||
|
|
ce1f755612 | ||
|
|
fa943d1166 | ||
|
|
dc09f91e35 | ||
|
|
34b8fa2728 | ||
|
|
02f7bebf67 | ||
|
|
4ffc384764 | ||
|
|
e1ef2b34ea | ||
|
|
d5a83a8819 | ||
|
|
661f499f67 | ||
|
|
a073beeea7 | ||
|
|
07f6bf7a7a | ||
|
|
0cfbb269f2 | ||
|
|
f3791e5fb4 | ||
|
|
37d8b0d3bd | ||
|
|
4ae383033a | ||
|
|
ea71675701 | ||
|
|
1178d01baa | ||
|
|
ace53f9494 | ||
|
|
3c17ff2da9 | ||
|
|
163991a36b | ||
|
|
291721c1d0 | ||
|
|
d96301d544 | ||
|
|
54d9674055 | ||
|
|
4a5a07649a | ||
|
|
cfdb65fad8 | ||
|
|
16544a4a70 | ||
|
|
02939d0840 | ||
|
|
bf331c7020 | ||
|
|
e80b55572b | ||
|
|
51c29f0a6e | ||
|
|
056191db82 | ||
|
|
9ace150efa | ||
|
|
79ae89d172 | ||
|
|
bb703e2060 | ||
|
|
972d9019e1 | ||
|
|
c99566410a | ||
|
|
9c56a14fb0 | ||
|
|
b95e58317b | ||
|
|
6fd9d6e15c | ||
|
|
518b9fa2ba | ||
|
|
c113b7bd88 | ||
|
|
fb0a302f62 | ||
|
|
43127379cd | ||
|
|
c5bc7136c7 | ||
|
|
18ba671417 | ||
|
|
6141bfd1fb | ||
|
|
4e4b51c4f1 | ||
|
|
83ac300aa3 | ||
|
|
f641a3c9c6 | ||
|
|
18a4782bf1 | ||
|
|
f1fddb7325 | ||
|
|
9c864af409 | ||
|
|
7cd332228a | ||
|
|
54c534736f | ||
|
|
6f07862572 | ||
|
|
54863ca6a4 | ||
|
|
70499e504c | ||
|
|
697565f95c | ||
|
|
94f1501c96 | ||
|
|
145b0e2c7b | ||
|
|
7057b3ba82 | ||
|
|
f6eecce135 | ||
|
|
1f0d105685 | ||
|
|
7caf841edd | ||
|
|
7cd82b1e03 | ||
|
|
2c8a21fc04 | ||
|
|
102ec389b9 | ||
|
|
f07895eeb0 | ||
|
|
a1570c7666 | ||
|
|
ef260784ac | ||
|
|
bc7be925e2 | ||
|
|
9091e49650 | ||
|
|
5a8dd95565 | ||
|
|
23df87a8c3 | ||
|
|
3781d10cb6 | ||
|
|
f1d505330c | ||
|
|
fc9fbd25fe | ||
|
|
b3e5003e0c | ||
|
|
be9fd29023 | ||
|
|
22bb9cfe09 | ||
|
|
02238b4000 | ||
|
|
2f9bf085fa | ||
|
|
11010f274f | ||
|
|
9f2c57c3f1 | ||
|
|
41d815103c | ||
|
|
967c48f6d7 | ||
|
|
c4d0d0fba7 | ||
|
|
9a720e9c82 | ||
|
|
c41522ab67 | ||
|
|
501a4b3415 | ||
|
|
7af59ac7ec | ||
|
|
c16a4707b5 | ||
|
|
0a86ea65ed | ||
|
|
273ab1fe54 | ||
|
|
1b9622e6dd | ||
|
|
7209184636 | ||
|
|
b4c0b264b9 | ||
|
|
2e13e758b8 | ||
|
|
5359eb85e1 | ||
|
|
e42e758150 | ||
|
|
340fd9a324 | ||
|
|
1e277e5681 | ||
|
|
2534176b8d | ||
|
|
4f1c547f77 | ||
|
|
4698b2a0e7 | ||
|
|
cb76c9762c | ||
|
|
496890357a | ||
|
|
fc7dba6c91 | ||
|
|
67efbdc6e9 | ||
|
|
d660137e7e | ||
|
|
15ae14d4a1 | ||
|
|
111524b6c6 | ||
|
|
ce806c5aa8 | ||
|
|
b244f613ee | ||
|
|
ad5cb35260 | ||
|
|
c0ca2174b6 | ||
|
|
c3c1398a2d | ||
|
|
1fbdd2edf4 | ||
|
|
a64a66912f | ||
|
|
61bbb23e7a | ||
|
|
e8d62ecc22 | ||
|
|
7db64e9375 | ||
|
|
0a320cb3b3 | ||
|
|
50d38d127c | ||
|
|
1ad42423bf | ||
|
|
273c9b2f18 | ||
|
|
90260bbed5 | ||
|
|
833804c7b4 | ||
|
|
206f4bc2bb | ||
|
|
5280bdab86 | ||
|
|
ce0113cd6c | ||
|
|
24885853fd | ||
|
|
1f4ce20c8b | ||
|
|
5629682a9a | ||
|
|
826e335611 | ||
|
|
06c0a425cd | ||
|
|
dc9b4bbb20 | ||
|
|
4e951bcb98 | ||
|
|
428cafeb7d | ||
|
|
e145e461fa | ||
|
|
7bfd268793 | ||
|
|
2bc2d4ed26 | ||
|
|
185d006a61 | ||
|
|
42068c8a95 | ||
|
|
cb4e86886a | ||
|
|
02f6b1850c | ||
|
|
a667380d7a | ||
|
|
21be67f025 | ||
|
|
7d3fbcc7d0 | ||
|
|
cbbfc2227c | ||
|
|
9add3fa538 | ||
|
|
ef13bffcb9 | ||
|
|
a40c9d2b11 | ||
|
|
ddaa4c056d | ||
|
|
8f0b34c2de | ||
|
|
5ff145ff12 | ||
|
|
6e8a3fa05d | ||
|
|
2d3816e3ae | ||
|
|
4c9441a690 | ||
|
|
035523b426 | ||
|
|
93179a21b2 | ||
|
|
53534cf3d5 | ||
|
|
8bb6c4012a | ||
|
|
57960111f7 | ||
|
|
165e6322fc | ||
|
|
2afc157c24 | ||
|
|
9822bb94a1 | ||
|
|
bf72c8a4cc | ||
|
|
f6c8281c9e | ||
|
|
dcc2b2cb31 | ||
|
|
e9d3127932 | ||
|
|
c5d6b7d053 | ||
|
|
9bb0950c12 | ||
|
|
b2d6bd58e6 | ||
|
|
4fdcdec802 | ||
|
|
0873b17894 | ||
|
|
48957d33b6 | ||
|
|
48675f1875 | ||
|
|
ef4377c77b | ||
|
|
4394e0fca1 | ||
|
|
fc7b15042c | ||
|
|
bbaa119617 | ||
|
|
88f4797f0b | ||
|
|
fa35e32578 | ||
|
|
c40cbc6cc2 | ||
|
|
8fcd6c2ff9 | ||
|
|
30c6a713d6 | ||
|
|
029a18ff1a | ||
|
|
45049ae176 | ||
|
|
01f59521af | ||
|
|
0f3cd9dd24 | ||
|
|
ba4619df21 | ||
|
|
f7aa5aaf0b | ||
|
|
d3f0553c65 | ||
|
|
601d7729bc | ||
|
|
ac464b4036 | ||
|
|
5f220bc364 | ||
|
|
962ea50c44 | ||
|
|
742fda24c6 | ||
|
|
e0c10f3564 | ||
|
|
5a94143fd7 | ||
|
|
c5ba226fa0 | ||
|
|
be8dff3de7 | ||
|
|
0582fd680d | ||
|
|
c93a5e5299 | ||
|
|
c5229f1100 | ||
|
|
d78023f388 | ||
|
|
f15b63fd66 | ||
|
|
0ff236edbc | ||
|
|
9d23f3bdd0 | ||
|
|
dd74aac117 | ||
|
|
d49b713ccd | ||
|
|
d6431cbcc4 | ||
|
|
392748db57 | ||
|
|
70cc8fb9e3 | ||
|
|
bbabe672d8 | ||
|
|
447732bf9c | ||
|
|
29f60b5199 | ||
|
|
94fa7b17ff | ||
|
|
b5ec93e571 | ||
|
|
132e762c7e | ||
|
|
8ef94890a9 | ||
|
|
b6c9ef990f | ||
|
|
b19ce60e74 | ||
|
|
632e1ecb5c | ||
|
|
fa3ec522ca | ||
|
|
4615cea8a6 | ||
|
|
3c5dc1672a | ||
|
|
768c68df49 | ||
|
|
c44731bd97 | ||
|
|
9450cf9447 | ||
|
|
1cfb60d65b | ||
|
|
64519d6310 | ||
|
|
3d9b5852f8 | ||
|
|
dc6109c530 | ||
|
|
7fe1e27667 | ||
|
|
e24209438c | ||
|
|
ee2a3c9bea | ||
|
|
5861aa11c1 | ||
|
|
0041c11aae | ||
|
|
ed8def4ece | ||
|
|
7f08cc9cf0 | ||
|
|
981e477bd0 | ||
|
|
01bf39764a | ||
|
|
b4a2ad646b | ||
|
|
79d557542b | ||
|
|
26d411c94d | ||
|
|
8d3ae2ef00 | ||
|
|
f28854b7f2 | ||
|
|
5a24771d3c | ||
|
|
84830d6aef | ||
|
|
134cd53f45 | ||
|
|
717b9db4af | ||
|
|
87c313c933 | ||
|
|
928320c1bd | ||
|
|
bba4ad55da | ||
|
|
23604fba25 | ||
|
|
112c51d6e3 | ||
|
|
9339a15d18 | ||
|
|
a4b65ba0c7 | ||
|
|
00dfe2599e | ||
|
|
dcf6ec5612 | ||
|
|
0acd47fba0 | ||
|
|
4e718ff879 | ||
|
|
1205462620 | ||
|
|
75344a4ed2 | ||
|
|
6dae15155a | ||
|
|
338922099d | ||
|
|
0c840de187 | ||
|
|
16755831bc | ||
|
|
4c64b7e456 | ||
|
|
28a56c0bd7 | ||
|
|
894f99aa66 | ||
|
|
450d785a58 | ||
|
|
a26be8e7f0 | ||
|
|
d2f982fccb | ||
|
|
4b38f81384 | ||
|
|
20bc336036 | ||
|
|
cec4585538 | ||
|
|
8b4635ffaa | ||
|
|
3dc53c5436 | ||
|
|
7265b3c4b6 | ||
|
|
49033dec1a | ||
|
|
9b632f582f | ||
|
|
a989c8a6d1 | ||
|
|
e5c0427e68 | ||
|
|
c5811749cb | ||
|
|
5e925865a7 | ||
|
|
175f837f3d | ||
|
|
b28d3816c0 | ||
|
|
3ad66acb20 | ||
|
|
958b44af15 | ||
|
|
99b20f6724 | ||
|
|
4eec64e811 | ||
|
|
052548fda7 | ||
|
|
98e7218cf5 | ||
|
|
374c3786df | ||
|
|
a9a3f4381a | ||
|
|
b845ad6d3c | ||
|
|
7c8d3caba6 | ||
|
|
fcddc472e1 | ||
|
|
1c18348475 | ||
|
|
c6c74bd7b9 | ||
|
|
0775edd29e | ||
|
|
52017e5281 | ||
|
|
af3aecc3f8 | ||
|
|
eaf6b511d0 | ||
|
|
e13d0248ae | ||
|
|
e3d563a556 | ||
|
|
e2078bba84 | ||
|
|
017af8a383 | ||
|
|
0739e9f655 | ||
|
|
6f2904eb9a | ||
|
|
4003977ce3 | ||
|
|
d058bb7c3b | ||
|
|
139dfc5b81 | ||
|
|
152a5b5a7b | ||
|
|
ad54fa2ace | ||
|
|
d2e15f52c3 | ||
|
|
f670f382cd | ||
|
|
1ebedaf791 | ||
|
|
2879f426e0 | ||
|
|
d7c2cd8d2a | ||
|
|
78814dedd3 | ||
|
|
4865cf2202 | ||
|
|
239c533137 | ||
|
|
55bf893228 | ||
|
|
349cb32c5f | ||
|
|
1545305d43 | ||
|
|
0f84c6eaaa | ||
|
|
df94b38019 | ||
|
|
e8451f9648 | ||
|
|
b42ed51c5e | ||
|
|
9ed9ccbe4a | ||
|
|
b4d0343992 | ||
|
|
4b0604a183 | ||
|
|
8d50ae1f46 | ||
|
|
6ed4b60ebb | ||
|
|
86e0c502ae | ||
|
|
c1936cf46b | ||
|
|
973910b837 | ||
|
|
590918ac6d | ||
|
|
b9e1efbe00 | ||
|
|
2ca6870c6a | ||
|
|
ca3bedeeb4 | ||
|
|
f85d56ac4d | ||
|
|
9a522f7922 | ||
|
|
f453077796 | ||
|
|
387029c5a6 | ||
|
|
f3b74696c0 | ||
|
|
f946adb6d1 | ||
|
|
dc3174747b | ||
|
|
837ad89502 | ||
|
|
58ffd93961 | ||
|
|
579c392a09 | ||
|
|
81fd1f522f | ||
|
|
e30dcac465 | ||
|
|
ee54cf2ebb | ||
|
|
f47ead51ca | ||
|
|
ab425e0492 | ||
|
|
95134b9ab8 | ||
|
|
7ccac9aa79 | ||
|
|
69f221a424 | ||
|
|
3c6eabaef8 | ||
|
|
76361d1ca9 | ||
|
|
de69cf7ceb | ||
|
|
3fd894df50 | ||
|
|
ddbed22a6f | ||
|
|
f51140f361 | ||
|
|
1876667db1 | ||
|
|
2587c2e372 | ||
|
|
4f6dfe3132 | ||
|
|
58dbd7868a | ||
|
|
3d1245bee6 | ||
|
|
2df012fb97 | ||
|
|
83d5f74e19 | ||
|
|
4dfac05fcb | ||
|
|
3548e3e8cd | ||
|
|
862ebe7d48 | ||
|
|
a56acf553c | ||
|
|
0658f5b7fa | ||
|
|
972e154a75 | ||
|
|
70b0bedf9b | ||
|
|
d843f719c8 | ||
|
|
edf8d8a463 | ||
|
|
8c3e61c6a0 | ||
|
|
6de1d45246 | ||
|
|
5488870267 | ||
|
|
a3845187b3 | ||
|
|
2955a61a5c | ||
|
|
0f11730181 | ||
|
|
75255d80cd | ||
|
|
2d88f5966c | ||
|
|
2984b755d5 | ||
|
|
7362db833b | ||
|
|
7b9bbd5be4 | ||
|
|
11d4687794 | ||
|
|
ef7c94f4e0 | ||
|
|
676e516f73 | ||
|
|
d83d3982cd | ||
|
|
a24bf2d1d7 | ||
|
|
db46faef29 | ||
|
|
64e7c1081b | ||
|
|
56bfd6a069 | ||
|
|
18ac071c5d | ||
|
|
b44790c15f | ||
|
|
e04f0eb98b | ||
|
|
2278a1217b | ||
|
|
183205b8d4 | ||
|
|
435bb7b65b | ||
|
|
52159093dd | ||
|
|
c7056efe69 | ||
|
|
1b69ffe9e0 | ||
|
|
04203312bf | ||
|
|
57bb2a3978 | ||
|
|
c32cea8f8a | ||
|
|
6ba62abd88 | ||
|
|
a31bf4e48e | ||
|
|
fab113db25 | ||
|
|
2858fd4fa8 | ||
|
|
49f12ac82f | ||
|
|
bf943cc706 | ||
|
|
09d8c550b5 | ||
|
|
dadcee8fe2 | ||
|
|
9dacaf7ddf | ||
|
|
622cf46858 | ||
|
|
0c6f8bb52d | ||
|
|
cccf05db39 | ||
|
|
f4ca5290ce | ||
|
|
2380b6aa76 | ||
|
|
215ccb70bc | ||
|
|
3d5376889f | ||
|
|
6053e3be64 | ||
|
|
51f6d27edf | ||
|
|
e46a2089dd | ||
|
|
d5dd918fde | ||
|
|
bf855c8b4c | ||
|
|
4d273b34f7 | ||
|
|
eb82a8afda | ||
|
|
73c4204ee9 | ||
|
|
8fbbd0e714 | ||
|
|
438daf82b4 | ||
|
|
7066098957 | ||
|
|
4e2b1cf4ce | ||
|
|
8e36b55e40 | ||
|
|
e8df572503 | ||
|
|
3e9556e1ef | ||
|
|
ceef3e690d | ||
|
|
3e6bc02256 | ||
|
|
6cc1d7f721 | ||
|
|
53dba06764 | ||
|
|
e514a34e60 | ||
|
|
3efe76dc71 | ||
|
|
571e7e3333 | ||
|
|
6b4d955d7c | ||
|
|
da0b4ca25d | ||
|
|
3b093f5da3 | ||
|
|
570c02ae55 | ||
|
|
81ff4f2c8a | ||
|
|
34b0402bc1 | ||
|
|
469b75624d | ||
|
|
59e239118c | ||
|
|
10957b5fdf | ||
|
|
bc9f66008d | ||
|
|
76b798d6e2 | ||
|
|
7717a15fc2 | ||
|
|
e0ef0a38a5 | ||
|
|
b21eea1568 | ||
|
|
ac73f8d6b6 | ||
|
|
7d95969f03 | ||
|
|
f67b06be88 | ||
|
|
fa5effe1a9 | ||
|
|
1f4dcb5a38 | ||
|
|
949149ea4d | ||
|
|
8ff262456b | ||
|
|
03cf443b14 | ||
|
|
2681fdabec | ||
|
|
678c9779ce | ||
|
|
1728f5d9f0 | ||
|
|
b71312b8eb | ||
|
|
ebe27c499e | ||
|
|
fbc164df8c | ||
|
|
d419da1cac | ||
|
|
67e6e29994 | ||
|
|
3059e60096 | ||
|
|
8a4a0f6bdc | ||
|
|
a1ea97950e | ||
|
|
2d58361620 | ||
|
|
a98262338a | ||
|
|
47cd8b71f7 | ||
|
|
36d6a72317 | ||
|
|
1da5f7e223 | ||
|
|
29398de678 | ||
|
|
d95d562843 | ||
|
|
cb51839eb9 | ||
|
|
ec31075fae | ||
|
|
b30a845a65 | ||
|
|
9667c2fc5a | ||
|
|
7df4084d45 | ||
|
|
d91c9f45c3 | ||
|
|
840b3940cd | ||
|
|
8a1e875020 | ||
|
|
8c43d3f378 | ||
|
|
d67ebbe683 | ||
|
|
16d9845027 | ||
|
|
5591b49c8d | ||
|
|
e67d140af0 | ||
|
|
d8252fc769 | ||
|
|
dfb50ab7ee | ||
|
|
fcc2271e83 | ||
|
|
ae25a48d4e | ||
|
|
b703c6a0ae | ||
|
|
c8ae67aba8 | ||
|
|
9e68c32f96 | ||
|
|
5887480b29 | ||
|
|
edabd603b3 | ||
|
|
1131af8283 | ||
|
|
59e69ac1cc | ||
|
|
25281d0c6f | ||
|
|
0ab3da1512 | ||
|
|
80d4799073 | ||
|
|
71353042c3 | ||
|
|
b5c3fb16cb | ||
|
|
3e3159f03b | ||
|
|
97a2044f5e | ||
|
|
fd1093180f | ||
|
|
68f3d6c056 | ||
|
|
6002e73a59 | ||
|
|
1e0fd60d4e | ||
|
|
f0d5cda1c5 | ||
|
|
04f8630d96 | ||
|
|
440db9ba7e | ||
|
|
44fca49e3f | ||
|
|
061220263c | ||
|
|
428f8a68bf | ||
|
|
03f3e4595e | ||
|
|
21fe26d042 | ||
|
|
38f79e9244 | ||
|
|
2ff4ec81ac | ||
|
|
3d24f63fd7 | ||
|
|
e8c66db876 | ||
|
|
f38811ae9d | ||
|
|
74693c5f6e | ||
|
|
3f2560655e | ||
|
|
bac596ff5b | ||
|
|
b7561b6cfc | ||
|
|
afb41ebc05 | ||
|
|
4961f4859e | ||
|
|
0b18e1ae88 | ||
|
|
217fcaaddc | ||
|
|
f77c23f781 | ||
|
|
639c7bb876 | ||
|
|
b9a5498279 | ||
|
|
3a8e98bb82 | ||
|
|
f2e5e66383 | ||
|
|
2a52d3c52e | ||
|
|
7332d0aa37 | ||
|
|
1e7f248d28 | ||
|
|
a381eb3d5a | ||
|
|
70f2d82963 | ||
|
|
2dc0a6bc95 | ||
|
|
b37a458a1d | ||
|
|
e2257c5046 | ||
|
|
e3ee433b49 | ||
|
|
16e4b2ae40 | ||
|
|
0a513fe088 | ||
|
|
f0cd18e711 | ||
|
|
9559e9fff3 | ||
|
|
e6c869a438 | ||
|
|
f701a142c8 | ||
|
|
f02cfc5a1a | ||
|
|
14e5446696 | ||
|
|
61dc029867 | ||
|
|
9f00055454 | ||
|
|
bf4a01971d | ||
|
|
5b1d060e5a | ||
|
|
8582f74e3e | ||
|
|
fcfeacdd82 | ||
|
|
78902caf30 | ||
|
|
03d5a8357a | ||
|
|
c8f6f1b4f2 | ||
|
|
519df8c33b | ||
|
|
14205b4145 | ||
|
|
cf6eadcc8c | ||
|
|
ab5e9c8344 | ||
|
|
c1f9a86dd3 | ||
|
|
5204a34031 | ||
|
|
4c980e64ac | ||
|
|
ad772b7706 | ||
|
|
471299bd21 | ||
|
|
fc945fbab9 | ||
|
|
defc97dc35 | ||
|
|
e239cb551d | ||
|
|
bceecbf377 | ||
|
|
6bdbfe4aa0 | ||
|
|
243fab3a05 | ||
|
|
24470ffe11 | ||
|
|
cb04731319 | ||
|
|
16db12231a | ||
|
|
9e6385c00a | ||
|
|
5d79dfa6be | ||
|
|
6ccc65a85a | ||
|
|
58d2a2460b | ||
|
|
df887cba61 | ||
|
|
e68ad67070 | ||
|
|
8c9a4f9d3b | ||
|
|
d853f0e7f9 | ||
|
|
5e60f65711 | ||
|
|
ad72465a04 | ||
|
|
df75bc04f8 | ||
|
|
442c5870c4 | ||
|
|
08495a3cb2 | ||
|
|
06de76ed58 | ||
|
|
23f3ca2c5c | ||
|
|
4939c281aa | ||
|
|
02d15211fa | ||
|
|
be6f7671c8 | ||
|
|
76cd1b9cad | ||
|
|
57cfa6f5a0 | ||
|
|
aa5bcf97d2 | ||
|
|
fbf05d5263 | ||
|
|
f54a8002a7 | ||
|
|
c25b10bb78 | ||
|
|
703279a2f8 | ||
|
|
beae99c71b | ||
|
|
7478a323ab | ||
|
|
31a273446b | ||
|
|
e1e51eb124 | ||
|
|
95327fd3a3 | ||
|
|
533eed11f0 | ||
|
|
eb68a43544 | ||
|
|
7bd1156cda | ||
|
|
0c7e33b2f1 | ||
|
|
a9623ff698 | ||
|
|
44d97b64b9 | ||
|
|
e4778dea36 | ||
|
|
c3421b42c7 | ||
|
|
10bbe516d7 | ||
|
|
771e33109d | ||
|
|
ec81d5a964 | ||
|
|
ee1628dbdf | ||
|
|
a1c2c9efbd | ||
|
|
f2070332e9 | ||
|
|
5079ece2dc | ||
|
|
6a791713ea | ||
|
|
41c9568d80 | ||
|
|
698f3d2821 | ||
|
|
a86ea5d12f | ||
|
|
fea9837f30 | ||
|
|
72a11e51a2 | ||
|
|
b9e1406f5b | ||
|
|
564b425b8f | ||
|
|
532dd78aa8 | ||
|
|
5f969c703f | ||
|
|
675b0a39fc | ||
|
|
0a62472840 | ||
|
|
faa8545fcf | ||
|
|
7d98a01e9a | ||
|
|
d74d3b282d | ||
|
|
747e9438c9 | ||
|
|
b6ae809b56 | ||
|
|
c999ae9da4 | ||
|
|
61eff01008 | ||
|
|
f2ee9afa88 | ||
|
|
dc5ac7b3a3 | ||
|
|
612fbf8f38 | ||
|
|
f97a8728fd | ||
|
|
1c1ddaf3d0 | ||
|
|
30316222f3 | ||
|
|
d53e6b767c | ||
|
|
661a1b5839 | ||
|
|
cb2485ae3d | ||
|
|
fa70bf3ff8 | ||
|
|
a32419d07d | ||
|
|
c2e806e318 | ||
|
|
ba8bbc462d | ||
|
|
c4a04d3dca | ||
|
|
1135458d60 | ||
|
|
3d2aa17cf2 | ||
|
|
3baf1f17bf | ||
|
|
f8ecbb7806 | ||
|
|
8f3f2a20c1 | ||
|
|
7935644115 | ||
|
|
dde3eca10e | ||
|
|
ae60a08baa | ||
|
|
676e4a2cd4 | ||
|
|
7f66d4690e | ||
|
|
40fccc57ed | ||
|
|
df44cc0779 | ||
|
|
d29e2f3994 | ||
|
|
3c6b485321 | ||
|
|
4e08c0f3cf | ||
|
|
c9c45ec8d1 | ||
|
|
af4d1e650c | ||
|
|
3412cb6e45 | ||
|
|
9cbf9f3942 | ||
|
|
837e5764b8 | ||
|
|
491c27cd74 | ||
|
|
bddb517583 | ||
|
|
843cc89547 | ||
|
|
4324b8dfc5 | ||
|
|
078a65a8bf | ||
|
|
17aa37f17b | ||
|
|
d30d951494 | ||
|
|
7bc76bdee4 | ||
|
|
4fc1a87ead | ||
|
|
4b8e157098 | ||
|
|
8fef756172 | ||
|
|
7aab27a60f | ||
|
|
2ebcc52358 | ||
|
|
7e83bad920 | ||
|
|
052ea72e87 | ||
|
|
37dd04746b | ||
|
|
c0a815f36e | ||
|
|
8fa1e3dd79 | ||
|
|
61c9bdea92 | ||
|
|
d804ca40f4 | ||
|
|
aa3d09a55c | ||
|
|
5a65ee5254 | ||
|
|
a50c7d34ff | ||
|
|
b98ab87ae7 | ||
|
|
f90f1ec7c0 | ||
|
|
b8edecc092 | ||
|
|
3b73e3d49d | ||
|
|
580afb5a21 | ||
|
|
a673756664 | ||
|
|
0499639473 | ||
|
|
69dd14682c | ||
|
|
d9fa110156 | ||
|
|
3f9fc67ab4 | ||
|
|
43c82fb028 | ||
|
|
01c0fa9563 | ||
|
|
ffce78808e | ||
|
|
e4d5ffb281 | ||
|
|
b8422e7299 | ||
|
|
d7641455d4 | ||
|
|
b6e56ae42c | ||
|
|
52cfa061c4 | ||
|
|
9208debb1a | ||
|
|
5da4e9f4a8 | ||
|
|
f30bfb20ef | ||
|
|
798eee940c | ||
|
|
9c44356d5a | ||
|
|
e241ad349a | ||
|
|
25f5b82cff | ||
|
|
5776f56f7b | ||
|
|
20da15c931 | ||
|
|
0b68dd0e85 | ||
|
|
4e49e69c16 | ||
|
|
8c775896b2 | ||
|
|
9af1168004 | ||
|
|
c1986623ed | ||
|
|
700a39f4c5 | ||
|
|
738cae727e | ||
|
|
08536f0850 | ||
|
|
ddca72e8bd | ||
|
|
3ddbf3aca7 | ||
|
|
52ed21cae5 | ||
|
|
f7dd5d92ac | ||
|
|
4d3e1c713a | ||
|
|
b54f6310f3 | ||
|
|
008bdfdad5 | ||
|
|
ffa6c115e1 | ||
|
|
ae3d59fc47 | ||
|
|
3207aeb741 | ||
|
|
b3949aa3cc | ||
|
|
6e9d29937d | ||
|
|
96dca60a2b | ||
|
|
8d3a7f2526 | ||
|
|
ac9f51a0f3 | ||
|
|
8ffd06025e | ||
|
|
576f424bc0 | ||
|
|
ec5c92e369 | ||
|
|
6a97b3dee5 | ||
|
|
70070daf1c | ||
|
|
482e4097d8 | ||
|
|
f774b4bbcf | ||
|
|
47938a1072 | ||
|
|
93449c9320 | ||
|
|
e93310b9bf | ||
|
|
9a26889fc7 | ||
|
|
106fdc72c4 | ||
|
|
6224d8fbbe | ||
|
|
b1a195c67e | ||
|
|
607fbb609c | ||
|
|
13e186576b | ||
|
|
d30041dfe7 | ||
|
|
dc14024dd7 | ||
|
|
bd95bc12ba | ||
|
|
0b67883de8 | ||
|
|
64e1d6b27e | ||
|
|
7a840f1a6e | ||
|
|
35ac4e91f6 | ||
|
|
9a03074283 | ||
|
|
0ed68957db | ||
|
|
44d4e4f78f | ||
|
|
4506f06b01 | ||
|
|
813e3227ad | ||
|
|
3bbccf2c3c | ||
|
|
810677014c | ||
|
|
f81ef16012 | ||
|
|
c33a9ea975 | ||
|
|
f672231eec | ||
|
|
9876189c64 | ||
|
|
2f84ac6fee | ||
|
|
692904dc5e | ||
|
|
c02aceeead | ||
|
|
ee24b58a2c | ||
|
|
29d1cda756 | ||
|
|
343df3f97c | ||
|
|
089eeb2956 | ||
|
|
da2e2dbf20 | ||
|
|
8501a0b818 | ||
|
|
59a9f73872 | ||
|
|
b3438ccc86 | ||
|
|
72a57edaa3 | ||
|
|
b19a63f69a | ||
|
|
71a600e308 | ||
|
|
ebb9758d28 | ||
|
|
e9e25f8800 | ||
|
|
b42226c490 | ||
|
|
15965cd1b1 | ||
|
|
8fef564297 | ||
|
|
81f01996db | ||
|
|
00c378ad94 | ||
|
|
85eefe9a54 | ||
|
|
43cbc44941 | ||
|
|
f7540e7e36 | ||
|
|
c0a8c02c26 | ||
|
|
c054712828 | ||
|
|
f20616e6b7 | ||
|
|
e518c146f0 | ||
|
|
602115266a | ||
|
|
4e074af139 | ||
|
|
cceaf2bc02 | ||
|
|
acb49d2b69 | ||
|
|
4d84924da0 | ||
|
|
cc94913e16 | ||
|
|
13459bd136 | ||
|
|
b285b1c17f | ||
|
|
05c18658a0 | ||
|
|
f1a52f55d9 | ||
|
|
ea05052677 | ||
|
|
13311c374f | ||
|
|
daa288c1cc | ||
|
|
38b613ac5f | ||
|
|
7429f454eb | ||
|
|
3c119fe3e8 | ||
|
|
428525e1bd | ||
|
|
e07dbf374c | ||
|
|
f1306dfbee | ||
|
|
db4663cbf9 | ||
|
|
3760275937 | ||
|
|
b4afeac71f | ||
|
|
b19c543988 | ||
|
|
0a5ce00878 | ||
|
|
bfe256c578 | ||
|
|
af31c84982 | ||
|
|
67a2ad241a | ||
|
|
8a9449e240 | ||
|
|
95ef59be68 | ||
|
|
8463fb402e | ||
|
|
0f4391bdd1 | ||
|
|
2738019c3f | ||
|
|
ce3e76aa3d | ||
|
|
9d76b6c5cc | ||
|
|
6e023222de | ||
|
|
6b62fc7963 | ||
|
|
d38962868b | ||
|
|
3a0ee7de94 | ||
|
|
dff21145d0 | ||
|
|
81bf80d8b0 | ||
|
|
d2e1b556ba | ||
|
|
97b263cf57 | ||
|
|
fa140f09fc | ||
|
|
2cb824c1e1 | ||
|
|
9dc5c60100 | ||
|
|
8212810276 | ||
|
|
44d772a32f | ||
|
|
fbe3e1b44f | ||
|
|
d56fe9f9b0 | ||
|
|
9d3d347fb7 | ||
|
|
30fcab6626 | ||
|
|
44f25f7497 | ||
|
|
53c4a74074 | ||
|
|
a126c8f06d | ||
|
|
2ed81ef9be | ||
|
|
3a844767f0 | ||
|
|
3667b72634 | ||
|
|
3f8d272eee | ||
|
|
a15daa87c5 | ||
|
|
d6092fc3eb | ||
|
|
4d2c7bd776 | ||
|
|
78947d51dc | ||
|
|
8d7e482219 | ||
|
|
14d313686c | ||
|
|
b79bd9a30e | ||
|
|
891885fcb3 | ||
|
|
e1986612d5 | ||
|
|
4c9435594d | ||
|
|
cc353f5956 | ||
|
|
a90971b762 | ||
|
|
f32edcde74 | ||
|
|
177a7d3054 | ||
|
|
c693146e15 | ||
|
|
296358e473 | ||
|
|
06d5628180 | ||
|
|
9085bbff96 | ||
|
|
0171ce64e4 | ||
|
|
222ff4a6de | ||
|
|
1c46f2436c | ||
|
|
65654fdef2 | ||
|
|
9035d68d96 | ||
|
|
41b2d2bce7 | ||
|
|
b67c2dc625 | ||
|
|
ec0d738e9f | ||
|
|
028da06b34 | ||
|
|
dd5037cb07 | ||
|
|
5406c0156a | ||
|
|
2f97583289 | ||
|
|
fcde65eaee | ||
|
|
8fccdae675 | ||
|
|
50cb0528c6 | ||
|
|
3cf0c2f804 | ||
|
|
fad9e8516e | ||
|
|
7b3d4739aa | ||
|
|
e9f7046a05 | ||
|
|
9ce7239308 | ||
|
|
acc5a88a27 | ||
|
|
1cc99231ae | ||
|
|
39e0784714 | ||
|
|
9f0569cd0b | ||
|
|
d455ef3e33 | ||
|
|
691918cfc8 | ||
|
|
df294eee15 | ||
|
|
3a94ea35f6 | ||
|
|
4f711d8a34 | ||
|
|
c5ec653215 | ||
|
|
937b83d776 | ||
|
|
8b585a06e7 | ||
|
|
a53f88cbaf | ||
|
|
604a9212ca | ||
|
|
09d7e8abde | ||
|
|
1ddfcff441 | ||
|
|
08eb168f06 | ||
|
|
f0f6fd6887 | ||
|
|
892df7bd0c | ||
|
|
1a672a8aa3 | ||
|
|
8ec9a8ae22 | ||
|
|
defa18724c | ||
|
|
f56f965d06 | ||
|
|
1ea488024b | ||
|
|
4f85734de5 | ||
|
|
a3b6e6f161 | ||
|
|
ff1e851143 | ||
|
|
95f19bde45 | ||
|
|
457110fa62 | ||
|
|
23195e03b8 | ||
|
|
c9feaa7074 | ||
|
|
6ec5df9309 | ||
|
|
892e5fab1f | ||
|
|
15424a2617 | ||
|
|
5188c0f473 | ||
|
|
c91552339c | ||
|
|
8565b74510 | ||
|
|
7524bc3bc3 | ||
|
|
038d0e038b | ||
|
|
077e1a697b | ||
|
|
f5053bbc22 | ||
|
|
baf61c0bdb | ||
|
|
e3dcfb9136 | ||
|
|
e4c71fb3e4 | ||
|
|
44e947ac8a | ||
|
|
fc7e2400cf | ||
|
|
e30e164ba3 | ||
|
|
007e013514 | ||
|
|
10b5d2c4f7 | ||
|
|
ef9b15d924 | ||
|
|
a44bc68e81 | ||
|
|
ec75d17bcf | ||
|
|
ad5f9a3762 | ||
|
|
a720065a45 | ||
|
|
6342e0b243 | ||
|
|
e9814504db | ||
|
|
145cf9820a | ||
|
|
d7fae910fb | ||
|
|
d15474c243 | ||
|
|
805f377459 | ||
|
|
bf320261f9 | ||
|
|
fb94597409 | ||
|
|
93e4bd8cd0 | ||
|
|
dfa839526c | ||
|
|
0d1f138459 | ||
|
|
ace47d6515 | ||
|
|
87c1808b7e | ||
|
|
95627f3617 | ||
|
|
9c20ac68f5 | ||
|
|
ed1665d625 | ||
|
|
c6de70f57f | ||
|
|
28dcfd714e | ||
|
|
1ed6099878 | ||
|
|
5e9c2fc255 | ||
|
|
f9a4e3c9fc | ||
|
|
9d7582caa6 | ||
|
|
f9d47de8f2 | ||
|
|
e057b64055 | ||
|
|
5968e3d065 | ||
|
|
b22bb295af | ||
|
|
fb3ecd4cf7 | ||
|
|
65b4454f2c | ||
|
|
3e5f178c4d | ||
|
|
35f87f6361 | ||
|
|
c2141dc034 | ||
|
|
6e460c5584 | ||
|
|
3a523a514c | ||
|
|
e1e654c6b7 | ||
|
|
161009c4ac | ||
|
|
6cb2649981 | ||
|
|
6089e2e267 | ||
|
|
ac6bf02b2d | ||
|
|
365bbaf2ad | ||
|
|
f320ef4721 | ||
|
|
87a34f2fbb | ||
|
|
defdd904c8 | ||
|
|
3f91c33eae | ||
|
|
2e3642671f | ||
|
|
02e2f42481 | ||
|
|
168f37dc8a | ||
|
|
38aeda6d83 | ||
|
|
eb29b626d0 | ||
|
|
e50839b7cc | ||
|
|
082086ffa3 | ||
|
|
7327b995e1 | ||
|
|
a6fb23302e | ||
|
|
055518da79 | ||
|
|
6d903a526b | ||
|
|
8d0c230c30 | ||
|
|
440e71d983 | ||
|
|
328cc89e39 | ||
|
|
e4fd5d7293 | ||
|
|
77d8fbbfc5 | ||
|
|
fd4f484bab | ||
|
|
e116c52ea9 | ||
|
|
46fbd93d9b | ||
|
|
bd1805750b | ||
|
|
114663836c | ||
|
|
82c5e88c4a | ||
|
|
a0ec26a755 | ||
|
|
a29386c7a1 | ||
|
|
0ea25b46f7 | ||
|
|
63b471780d | ||
|
|
25065a66aa | ||
|
|
60c64fcb6c | ||
|
|
e5f8a83c7f | ||
|
|
39811e7a2e | ||
|
|
04cb611183 | ||
|
|
f15a73200f | ||
|
|
a6f3c879a5 | ||
|
|
811e5479f4 | ||
|
|
13af95f600 | ||
|
|
b6743725e0 | ||
|
|
d3579218f2 | ||
|
|
ff003d9603 | ||
|
|
805b27074c | ||
|
|
22e34da132 | ||
|
|
71119b8d81 | ||
|
|
ef2886ffc7 | ||
|
|
770b85ebd2 | ||
|
|
f75f992a59 | ||
|
|
113f1fac6a | ||
|
|
de58da6dab | ||
|
|
256eeb863c | ||
|
|
7420f2ff98 | ||
|
|
b2b968f915 | ||
|
|
12d89d8c4a | ||
|
|
476e64c389 | ||
|
|
e183f39dfd | ||
|
|
f9e34ce9d5 | ||
|
|
6bdd976209 | ||
|
|
efd64ecded | ||
|
|
50db978fa2 | ||
|
|
de410bf75f | ||
|
|
2ff7825b34 | ||
|
|
9b1ae75a00 | ||
|
|
e7f0911f8b | ||
|
|
c004beab02 | ||
|
|
fa758c51ee | ||
|
|
1aa2282321 | ||
|
|
9094c44b07 | ||
|
|
c46036761c | ||
|
|
5d2f3cd2a7 | ||
|
|
76f1902cae | ||
|
|
5801c329b2 | ||
|
|
302833eb22 | ||
|
|
f30b25e23f | ||
|
|
211e8c438a | ||
|
|
4a33ed8fc2 | ||
|
|
556ea8754c | ||
|
|
d2fdd37084 | ||
|
|
12e2f146bf | ||
|
|
eae701012a | ||
|
|
c4ae2c5c1b | ||
|
|
fb52bf3984 | ||
|
|
6c0ae235f0 | ||
|
|
399f867016 | ||
|
|
bb947ac0a9 | ||
|
|
30813f5efc | ||
|
|
411e6720e1 | ||
|
|
1255dc03b2 | ||
|
|
61e060b8ef | ||
|
|
18b009f6af | ||
|
|
d4b246e37f | ||
|
|
4da052279e | ||
|
|
12a9afe2fe | ||
|
|
e2a0314742 | ||
|
|
bdd4df9dd7 | ||
|
|
491a28c03e | ||
|
|
dc389e0f41 | ||
|
|
121f9b547c | ||
|
|
6c03a00f57 | ||
|
|
58ec18f47d | ||
|
|
973a92886b | ||
|
|
4497c4be66 | ||
|
|
33ec8d0041 | ||
|
|
215867ae21 | ||
|
|
4711c0f785 | ||
|
|
ad1dece946 | ||
|
|
dc202f987a | ||
|
|
12fbee8597 | ||
|
|
856621a8a7 | ||
|
|
2c4bda882f | ||
|
|
7f524153a6 | ||
|
|
6652f8cb65 | ||
|
|
b00dfb6135 | ||
|
|
93960dd1b8 | ||
|
|
d105045b75 | ||
|
|
49d21bbba8 | ||
|
|
b1f05c38b3 | ||
|
|
9f7ed802ea | ||
|
|
9b7313ce95 | ||
|
|
d42896a19c | ||
|
|
2729b8ece8 | ||
|
|
85ed99a1dc | ||
|
|
aa7959b91c | ||
|
|
781d9dd440 | ||
|
|
483a346faa | ||
|
|
6e9f368a0a | ||
|
|
84a3688525 | ||
|
|
3c08986889 | ||
|
|
477828beb9 | ||
|
|
fadc6c46ba | ||
|
|
3111166f89 | ||
|
|
f7c8b62f6c | ||
|
|
e6edc6ae03 | ||
|
|
3bc0799091 | ||
|
|
1285955e32 | ||
|
|
5fdc8cb32c | ||
|
|
8538a77db7 | ||
|
|
329b84f7b5 | ||
|
|
4dcb7acd58 | ||
|
|
d91f9cf29f | ||
|
|
1a04dec97b | ||
|
|
c6f95a9030 | ||
|
|
62d2157fd8 | ||
|
|
d0c61ea5fa | ||
|
|
b9c7d108e5 | ||
|
|
20a8597b45 | ||
|
|
9a1ada97ec | ||
|
|
0ebe32228d | ||
|
|
ad5da12154 | ||
|
|
cdd2e0dd1d | ||
|
|
3fe10212d5 | ||
|
|
97e97a6cfc | ||
|
|
9cb8d9d65e | ||
|
|
eadf3b46e0 | ||
|
|
5d97a16d75 | ||
|
|
e13ca70143 | ||
|
|
732493d663 | ||
|
|
569284ef60 | ||
|
|
85a1891b8c | ||
|
|
6a67344643 | ||
|
|
0bff0a7878 | ||
|
|
925d26f02b | ||
|
|
45539289fd | ||
|
|
4cbcddf3c0 | ||
|
|
304d63c6a2 | ||
|
|
ec784b4a98 | ||
|
|
1b899f2228 | ||
|
|
a8d437720b | ||
|
|
fc7c9e1c0a | ||
|
|
514607a731 | ||
|
|
9344e08d7b | ||
|
|
13cec0dd31 | ||
|
|
b80e890fd6 | ||
|
|
e54c07325e | ||
|
|
3107705e25 | ||
|
|
62db7b8382 | ||
|
|
8e8fefef36 | ||
|
|
0c178ec71f | ||
|
|
3c9c3cb709 | ||
|
|
2ebfd108ea | ||
|
|
31df3927c5 | ||
|
|
c1b7e06308 | ||
|
|
8368eb4541 | ||
|
|
ce995a9380 | ||
|
|
110d773e3c | ||
|
|
6965591e7b | ||
|
|
4b47cfda57 | ||
|
|
e7db4d6b67 | ||
|
|
c8a63044af | ||
|
|
622b27448f | ||
|
|
e2814141d4 | ||
|
|
1a0f70c56b | ||
|
|
e86ec32dd7 | ||
|
|
4667a14080 | ||
|
|
c8bd2ec1a1 | ||
|
|
933625011c | ||
|
|
c032541f69 | ||
|
|
78b9bf9823 | ||
|
|
3cf94bb728 | ||
|
|
ae1ee69d25 | ||
|
|
bf6bb93829 | ||
|
|
61ef7dfc75 | ||
|
|
82948e56d2 | ||
|
|
2338c5a4fa | ||
|
|
63b60999f8 | ||
|
|
5857a3aed7 | ||
|
|
364d41737f | ||
|
|
31c69477f4 | ||
|
|
d1e9477fb4 | ||
|
|
f325b778a9 | ||
|
|
a7270f7510 | ||
|
|
5da493713f | ||
|
|
ca0a7689be | ||
|
|
6efe19d50c | ||
|
|
08ce7c9186 | ||
|
|
cd25f0c723 | ||
|
|
fd6554658b | ||
|
|
8abc8ab0e4 | ||
|
|
7a16e7743e | ||
|
|
aac3cf2b69 | ||
|
|
c30a5e437f | ||
|
|
473c63267f | ||
|
|
318d8f8ccc | ||
|
|
ee24ab8f6e | ||
|
|
e89ca133cd | ||
|
|
c1292e5a52 | ||
|
|
a236b1f9da | ||
|
|
c9c7794e73 | ||
|
|
29c5717e79 | ||
|
|
ccc8e704b4 | ||
|
|
5991afc1f0 | ||
|
|
58329fd61f | ||
|
|
b7ed8ec246 | ||
|
|
c975ab7b05 | ||
|
|
fdf11d144f | ||
|
|
99f1821215 | ||
|
|
3d14646548 | ||
|
|
b826b1928e | ||
|
|
b6038285f4 | ||
|
|
0f8621d923 | ||
|
|
2d9e9a5e93 | ||
|
|
abeb5fc0e3 | ||
|
|
47e61cecdd | ||
|
|
17aaf08717 | ||
|
|
89e849d851 | ||
|
|
42098f477a | ||
|
|
e44ee9ca03 | ||
|
|
e7831ac960 | ||
|
|
8a48b71a0f | ||
|
|
2e4d50c7b5 | ||
|
|
df501e42b9 | ||
|
|
1d14d37c1d | ||
|
|
0d728ed4ce | ||
|
|
4e2ff445e0 | ||
|
|
f3818803fd | ||
|
|
329668322f | ||
|
|
0ffd0c1530 | ||
|
|
7b7c6fbfae | ||
|
|
b946228ee2 | ||
|
|
61177901e8 | ||
|
|
bb4f8b0d78 | ||
|
|
1a4e701f98 | ||
|
|
968ee917fc | ||
|
|
bbc01c0be9 | ||
|
|
3387b41841 | ||
|
|
d36a578708 | ||
|
|
36d42ab8ba | ||
|
|
ba71f10dee | ||
|
|
7bb1857d0c | ||
|
|
999ce51178 | ||
|
|
a2ebf69551 | ||
|
|
9ef3ba9342 | ||
|
|
88e82a511b | ||
|
|
495c49f277 | ||
|
|
0459091a52 | ||
|
|
ba67529d62 | ||
|
|
9bd16c0b5c | ||
|
|
a0c76052cc | ||
|
|
c4861c5efa | ||
|
|
6b8f46bf81 | ||
|
|
1a71f43c54 | ||
|
|
b4d732656f | ||
|
|
6a335269f4 | ||
|
|
c51f2fa401 | ||
|
|
69072cf0ca | ||
|
|
b023964aec | ||
|
|
59321dbd56 | ||
|
|
f1c282451b | ||
|
|
ff0c34c0b8 | ||
|
|
4380175c8b | ||
|
|
439598d7ee | ||
|
|
08fa24b095 | ||
|
|
c836548fc7 | ||
|
|
f109146379 | ||
|
|
8ff46bba74 | ||
|
|
af7f4e3bc4 | ||
|
|
06f1305f23 | ||
|
|
ddc299fa08 | ||
|
|
43df9d25f0 | ||
|
|
250ac0e8ba | ||
|
|
29d960878c | ||
|
|
8e6634ff0f | ||
|
|
15b5cf9750 | ||
|
|
c001c4b5bd | ||
|
|
43723697f7 | ||
|
|
99d6a0ab32 | ||
|
|
c2809ca091 | ||
|
|
108432c268 | ||
|
|
aa0db4b665 | ||
|
|
cda62b8a3e | ||
|
|
970242e860 | ||
|
|
9c741da4e8 | ||
|
|
2dfd43c8ba | ||
|
|
5536687d90 | ||
|
|
34c421733e | ||
|
|
b0b29443a5 | ||
|
|
a637dcd28d | ||
|
|
b6b3ec04be | ||
|
|
6586f51791 | ||
|
|
dff2e344a4 | ||
|
|
92e4e81788 | ||
|
|
aa9ee7e1af | ||
|
|
2d3f2f4b36 | ||
|
|
73fe4d68f1 | ||
|
|
d244602818 | ||
|
|
67d9c6ed4e | ||
|
|
55f8932495 | ||
|
|
24617f4a41 | ||
|
|
5d47009e07 | ||
|
|
c46acc1ad4 | ||
|
|
20051a835b | ||
|
|
2ae0f36241 | ||
|
|
873e33a04f | ||
|
|
e33c5d7cbc | ||
|
|
b729ec1a85 | ||
|
|
9b18ecf072 | ||
|
|
88c4ae5721 | ||
|
|
d2b94955d1 | ||
|
|
dbcc00fe1a | ||
|
|
b56ae68854 | ||
|
|
312ea7d962 | ||
|
|
ceb3b562e6 | ||
|
|
b211009e91 | ||
|
|
eec372c6df | ||
|
|
011e83fac6 | ||
|
|
70fa577e10 | ||
|
|
dd8e55c2ac | ||
|
|
b8f3f53d56 | ||
|
|
d5623dabb6 | ||
|
|
db50687a1e | ||
|
|
00fcd5a9b6 | ||
|
|
272fd58481 | ||
|
|
ecbde48f63 | ||
|
|
3dda43c70a | ||
|
|
39827e449b | ||
|
|
44d0c78077 | ||
|
|
34029c6f6f | ||
|
|
929b8c2d50 | ||
|
|
b71a64c214 | ||
|
|
66c5d408c6 | ||
|
|
ab1dbd0d5c | ||
|
|
cc307e3217 | ||
|
|
e3c45a5039 | ||
|
|
6754efc486 | ||
|
|
1e5d9d314b | ||
|
|
cea6aaf7ff | ||
|
|
c1f019e71c | ||
|
|
c00b511c17 | ||
|
|
51c6067c17 | ||
|
|
c032e74e58 | ||
|
|
412d40d041 | ||
|
|
2cc69a0725 | ||
|
|
89b3b6da61 | ||
|
|
77a7fffcb2 | ||
|
|
30a9c8c90e | ||
|
|
abd52c7a42 | ||
|
|
9bb164246e | ||
|
|
87d0e18696 | ||
|
|
e8f5864dd9 | ||
|
|
51d7b3f413 | ||
|
|
fb3de84aa4 | ||
|
|
4a2aa91b6d | ||
|
|
a4edac59c6 | ||
|
|
19af59b301 | ||
|
|
d1b27dfd9d | ||
|
|
274fb0f380 | ||
|
|
8e70567688 | ||
|
|
7cbc24feb8 | ||
|
|
2bdcf3919e | ||
|
|
8214f4ba20 | ||
|
|
d0a5fc24b1 | ||
|
|
c8084c670a | ||
|
|
82a9779b09 | ||
|
|
fdb887e43a | ||
|
|
7761244eec | ||
|
|
6580334bdd | ||
|
|
e2f7a22457 | ||
|
|
494382f5cb | ||
|
|
2ff248a4c4 | ||
|
|
7ed15a2dbc | ||
|
|
3d1725054a | ||
|
|
d6e37f9f13 | ||
|
|
2c78bef505 | ||
|
|
d60b9706b3 | ||
|
|
d20996d788 | ||
|
|
0010976803 | ||
|
|
bd422323ee | ||
|
|
6a66d99017 | ||
|
|
f1d87da9b6 | ||
|
|
ac8674a8b3 | ||
|
|
c2af7914e3 | ||
|
|
102db4c937 | ||
|
|
1f7d92b209 | ||
|
|
555cc74312 | ||
|
|
761319c13d | ||
|
|
828e867ac9 | ||
|
|
6a7b4f107e | ||
|
|
c0df364b4f | ||
|
|
71c72136f6 | ||
|
|
ec5f8fc4f5 | ||
|
|
f5e6ed914d | ||
|
|
2e7bc894f1 | ||
|
|
18537b9cdb | ||
|
|
ed5cb715da | ||
|
|
32cf86ede5 | ||
|
|
97f320c9a7 | ||
|
|
7c6dd75a23 | ||
|
|
6a59355514 | ||
|
|
91c3413c57 | ||
|
|
717f5f6e2e | ||
|
|
f48efae82d | ||
|
|
5f372ebee3 | ||
|
|
5b27fad3aa | ||
|
|
6149a951bd | ||
|
|
2529205359 | ||
|
|
81b71a7676 | ||
|
|
29c80f7845 | ||
|
|
05372fc4a4 | ||
|
|
50e433aba0 | ||
|
|
ac4797a943 | ||
|
|
3c7baa7237 | ||
|
|
3f9d6e48b5 | ||
|
|
79adfe70a4 | ||
|
|
ae8b616fed | ||
|
|
0b8b2db41e | ||
|
|
63183b33f1 | ||
|
|
de09d1dbd2 | ||
|
|
b59e318444 | ||
|
|
0a65da2fc4 | ||
|
|
e46be54688 | ||
|
|
e4f8a51df8 | ||
|
|
a51f48f060 | ||
|
|
32df0c1730 | ||
|
|
530c8818b7 | ||
|
|
6c99f73596 | ||
|
|
61acaaa054 | ||
|
|
25b695bc32 | ||
|
|
0f41cb5ad4 | ||
|
|
40e57e3a54 | ||
|
|
113b05ed05 | ||
|
|
824ce88914 | ||
|
|
a1e243714e | ||
|
|
1c0ed64f67 | ||
|
|
1f1cd1b6d7 | ||
|
|
e81725eb16 | ||
|
|
ee4220e1ce | ||
|
|
a733c6c68d | ||
|
|
d7c7619218 | ||
|
|
77066ba7e5 | ||
|
|
35c5919c44 | ||
|
|
fcdd286965 | ||
|
|
e84fa1d636 | ||
|
|
bfe9bad905 | ||
|
|
459b6bc6fe | ||
|
|
332211fb13 | ||
|
|
e5d42cf0eb | ||
|
|
424df8d4fe | ||
|
|
2f4422f719 | ||
|
|
831611af1e | ||
|
|
c302d362a4 | ||
|
|
69d4b1096f | ||
|
|
2514a89286 | ||
|
|
2034055148 | ||
|
|
3a3b1007b9 | ||
|
|
09a83b36ff | ||
|
|
32cc59228d | ||
|
|
31b2413953 | ||
|
|
c8eb643818 | ||
|
|
11b251003e | ||
|
|
28bb0e99cb | ||
|
|
5c9c686317 | ||
|
|
098425bdbf | ||
|
|
5189f6b392 | ||
|
|
f487479b1d | ||
|
|
03224cc4f6 | ||
|
|
482754eddb | ||
|
|
7fcf6874e3 | ||
|
|
a3e0eee8d4 | ||
|
|
b7ffb06f9c | ||
|
|
35a209bcb6 | ||
|
|
c3a2a15608 | ||
|
|
9acdfe5dcf | ||
|
|
9ec8056d89 | ||
|
|
b9c2cc2c4f | ||
|
|
675a2811d4 | ||
|
|
b1df5f533b | ||
|
|
a61cf3f889 | ||
|
|
ace09646c6 | ||
|
|
d2113c4379 | ||
|
|
9e60778075 | ||
|
|
4e78e4019f | ||
|
|
823d13af34 | ||
|
|
4007870bfb | ||
|
|
5d92f98548 | ||
|
|
cbbff69003 | ||
|
|
f40240d8cb | ||
|
|
9671599fc9 | ||
|
|
e1be421410 | ||
|
|
f4a80ed856 | ||
|
|
39610bce24 | ||
|
|
18e0044373 | ||
|
|
a9759a20c2 | ||
|
|
f5b9673044 |
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a bug report
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
...
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**EspoCRM version**
|
||||
Specify the EspoCRM version (or versions) on which the bug occurs.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
4
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
contact_links:
|
||||
- name: EspoCRM forum
|
||||
url: https://forum.espocrm.com/
|
||||
about: Please use our forum to ask questions not related to product development
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for EspoCRM
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
0
SECURITY.md → .github/SECURITY.md
vendored
0
SECURITY.md → .github/SECURITY.md
vendored
64
.github/workflows/test-integration.yml
vendored
Normal file
64
.github/workflows/test-integration.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Test Integration
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test on PHP ${{ matrix.php-versions }}
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
TEST_DATABASE_HOST: '127.0.0.1'
|
||||
TEST_DATABASE_PORT: '8888'
|
||||
TEST_DATABASE_NAME: integration_test
|
||||
TEST_DATABASE_USER: root
|
||||
TEST_DATABASE_PASSWORD: password
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
env:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: false
|
||||
MYSQ_USER: root
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
MYSQL_DATABASE: integration_test
|
||||
ports:
|
||||
- '8888:3306'
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.1']
|
||||
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: Start MySQL service
|
||||
run: sudo systemctl start mysql
|
||||
|
||||
- name: Create DB table
|
||||
run: mysql -h 127.0.0.1 --port 8888 -u root -ppassword -e 'CREATE DATABASE IF NOT EXISTS integration_test;'
|
||||
|
||||
- name: NPM install
|
||||
run: npm install
|
||||
|
||||
- name: Build
|
||||
run: grunt test
|
||||
|
||||
- name: Integration testing
|
||||
run: vendor/bin/phpunit tests/integration
|
||||
48
.github/workflows/test.yml
vendored
Normal file
48
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'fix'
|
||||
paths:
|
||||
- '**.php'
|
||||
- '**.json'
|
||||
- '**.yml'
|
||||
- 'composer.lock'
|
||||
- 'phpstan.neon'
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.php'
|
||||
- '**.json'
|
||||
- '**.yml'
|
||||
- 'composer.lock'
|
||||
- 'phpstan.neon'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test on PHP ${{ matrix.php-versions }}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0', '8.1']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- 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: Composer install
|
||||
run: composer install
|
||||
|
||||
- name: Static analysis
|
||||
run: vendor/bin/phpstan
|
||||
|
||||
- name: Unit testing
|
||||
run: vendor/bin/phpunit tests/unit
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
/data/preferences/*
|
||||
/data/.backup/*
|
||||
/data/config.php
|
||||
/data/config-internal.php
|
||||
/data/tmp/*
|
||||
/build
|
||||
/node_modules
|
||||
@@ -18,4 +19,11 @@
|
||||
/composer.phar
|
||||
/vendor/
|
||||
/custom/Espo/Custom/*
|
||||
/custom/Espo/Modules/*
|
||||
!/custom/Espo/Custom/.htaccess
|
||||
!/custom/Espo/Modules/.htaccess
|
||||
/install/config.php
|
||||
|
||||
client/css/espo/*
|
||||
client/lib/*
|
||||
client/modules/crm/lib/*
|
||||
|
||||
50
.htaccess
50
.htaccess
@@ -1,24 +1,44 @@
|
||||
<ifModule mod_headers.c>
|
||||
Header always set Access-Control-Allow-Methods "POST, GET, PUT, PATCH, DELETE"
|
||||
Header always set Access-Control-Allow-Methods "POST, GET, PUT, PATCH, DELETE"
|
||||
</ifModule>
|
||||
|
||||
DirectoryIndex index.php index.html
|
||||
DirectoryIndex index.php
|
||||
|
||||
Options -Indexes
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteEngine On
|
||||
|
||||
# PROTECTED DIRECTORIES
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^/?(api|client)/ - [F]
|
||||
# Forbid access. Not actual as redirect to `public` is applied.
|
||||
# An extra security measure if redirect not fired.
|
||||
RewriteRule ^/?data/ - [F]
|
||||
RewriteRule ^/?application/ - [F]
|
||||
RewriteRule ^/?custom/ - [F]
|
||||
RewriteRule ^/?vendor/ - [F]
|
||||
RewriteRule /?web\.config - [F]
|
||||
|
||||
RewriteRule ^/?data/ - [F]
|
||||
RewriteRule ^/?application/ - [F]
|
||||
RewriteRule ^/?custom/ - [F]
|
||||
RewriteRule ^/?vendor/ - [F]
|
||||
RewriteRule ^/?client/?$ - [F]
|
||||
#END PROTECTED DIRECTORIES
|
||||
# Forbid `public` dir.
|
||||
RewriteCond %{ENV:REDIRECT_STATUS} !=200
|
||||
RewriteRule ^/?public/? - [F,L]
|
||||
|
||||
RewriteRule .* - [E=HTTP_ESPO_CGI_AUTH:%{HTTP:Authorization}]
|
||||
# Skip redirect for `client` dir.
|
||||
RewriteRule ^client/ - [L]
|
||||
|
||||
RewriteRule /?web\.config - [F]
|
||||
</IfModule>
|
||||
# {#dev}
|
||||
# Skip redirect for `node_modules` dir. Actual only for dev environment.
|
||||
RewriteRule ^node_modules/ - [L]
|
||||
# {/dev}
|
||||
|
||||
# Store base path.
|
||||
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
|
||||
RewriteRule ^(.*)$ - [E=BASE:%1]
|
||||
|
||||
# Add trailing slash.
|
||||
RewriteCond %{DOCUMENT_ROOT}/%{ENV:BASE}/public/$1 -d
|
||||
RewriteRule ^(.*?[^/])$ %{REQUEST_URI}/ [L,R=301,NE]
|
||||
|
||||
# Rewrite to `public` dir.
|
||||
RewriteRule ^((?!public/).*)$ %{ENV:BASE}/public/$1 [L,NC]
|
||||
|
||||
RewriteRule .* - [E=HTTP_ESPO_CGI_AUTH:%{HTTP:Authorization}]
|
||||
</IfModule>
|
||||
|
||||
532
Gruntfile.js
532
Gruntfile.js
@@ -2,7 +2,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -19,113 +19,68 @@
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* * `grunt` - full build
|
||||
* * `grunt dev` - build only items needed for development (takes less time)
|
||||
* * `grunt offline` - build but skip *composer install*
|
||||
* * `grant release` - full build plus upgrade packages`
|
||||
* * `grant test` - build for test running
|
||||
* * `grant run-tests` - build and run unit and integratino tests
|
||||
*/
|
||||
/**
|
||||
* * `grunt` - full build;
|
||||
* * `grunt dev` - build only items needed for development (takes less time);
|
||||
* * `grunt offline` - build but skip *composer install*;
|
||||
* * `grunt internal` - build only libs and css;
|
||||
* * `grunt release` - full build plus upgrade packages`;
|
||||
* * `grunt test` - build for tests running;
|
||||
* * `grunt run-tests` - build and run unit and integration tests.
|
||||
*/
|
||||
|
||||
module.exports = function (grunt) {
|
||||
const fs = require('fs');
|
||||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
var jsFilesToMinify = [
|
||||
'client/lib/jquery-2.1.4.min.js',
|
||||
'client/lib/underscore-min.js',
|
||||
'client/lib/es6-promise.min.js',
|
||||
'client/lib/backbone-min.js',
|
||||
'client/lib/handlebars.js',
|
||||
'client/lib/base64.js',
|
||||
'client/lib/jquery-ui.min.js',
|
||||
'client/lib/jquery.ui.touch-punch.min.js',
|
||||
'client/lib/moment.min.js',
|
||||
'client/lib/moment-timezone.min.js',
|
||||
'client/lib/moment-timezone-data.js',
|
||||
'client/lib/jquery.timepicker.min.js',
|
||||
'client/lib/jquery.autocomplete.js',
|
||||
'client/lib/bootstrap.min.js',
|
||||
'client/lib/bootstrap-datepicker.js',
|
||||
'client/lib/bull.js',
|
||||
'client/lib/marked.min.js',
|
||||
'client/lib/autobahn.js',
|
||||
'client/lib/gridstack.all.js',
|
||||
module.exports = grunt => {
|
||||
|
||||
'client/src/namespace.js',
|
||||
'client/src/exceptions.js',
|
||||
'client/src/loader.js',
|
||||
'client/src/utils.js',
|
||||
const pkg = grunt.file.readJSON('package.json');
|
||||
const bundleConfig = require('./frontend/bundle-config.json');
|
||||
|
||||
'client/src/acl.js',
|
||||
'client/src/model.js',
|
||||
'client/src/model-offline.js',
|
||||
'client/src/ajax.js',
|
||||
'client/src/controller.js',
|
||||
let jsFilesToBundle = getBundleLibList().concat(bundleConfig.jsFiles);
|
||||
let jsFilesToCopy = getCopyLibDataList();
|
||||
|
||||
'client/src/ui.js',
|
||||
'client/src/acl-manager.js',
|
||||
'client/src/cache.js',
|
||||
'client/src/storage.js',
|
||||
'client/src/models/settings.js',
|
||||
'client/src/language.js',
|
||||
'client/src/metadata.js',
|
||||
'client/src/field-manager.js',
|
||||
'client/src/models/user.js',
|
||||
'client/src/models/preferences.js',
|
||||
'client/src/model-factory.js',
|
||||
'client/src/collection-factory.js',
|
||||
'client/src/pre-loader.js',
|
||||
'client/src/controllers/base.js',
|
||||
'client/src/router.js',
|
||||
'client/src/date-time.js',
|
||||
'client/src/layout-manager.js',
|
||||
'client/src/theme-manager.js',
|
||||
'client/src/session-storage.js',
|
||||
'client/src/view-helper.js',
|
||||
'client/src/page-title.js',
|
||||
let libFilesToMinify = jsFilesToCopy
|
||||
.filter(item => item.minify)
|
||||
.reduce((map, item) => (
|
||||
map[item.dest] = item.dest,
|
||||
map
|
||||
), {});
|
||||
|
||||
'client/src/app.js'
|
||||
];
|
||||
let currentPath = path.dirname(fs.realpathSync(__filename));
|
||||
|
||||
function camelCaseToHyphen (string){
|
||||
if (string == null) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
let themeList = [];
|
||||
|
||||
var fs = require('fs');
|
||||
var cp = require('child_process');
|
||||
var path = require('path');
|
||||
|
||||
var currentPath = path.dirname(fs.realpathSync(__filename));
|
||||
|
||||
var themeList = [];
|
||||
fs.readdirSync('application/Espo/Resources/metadata/themes').forEach(function (file) {
|
||||
fs.readdirSync('application/Espo/Resources/metadata/themes').forEach(file => {
|
||||
themeList.push(file.substr(0, file.length - 5));
|
||||
});
|
||||
|
||||
var cssminFilesData = {};
|
||||
var lessData = {};
|
||||
themeList.forEach(function (theme) {
|
||||
var name = camelCaseToHyphen(theme);
|
||||
var files = {};
|
||||
let cssminFilesData = {};
|
||||
|
||||
let lessData = {};
|
||||
|
||||
themeList.forEach(theme => {
|
||||
let name = camelCaseToHyphen(theme);
|
||||
|
||||
let files = {};
|
||||
|
||||
files['client/css/espo/'+name+'.css'] = 'frontend/less/'+name+'/main.less';
|
||||
files['client/css/espo/'+name+'-iframe.css'] = 'frontend/less/'+name+'/iframe/main.less';
|
||||
|
||||
cssminFilesData['client/css/espo/'+name+'.css'] = 'client/css/espo/'+name+'.css';
|
||||
cssminFilesData['client/css/espo/'+name+'-iframe.css'] = 'client/css/espo/'+name+'-iframe.css';
|
||||
var o = {
|
||||
|
||||
let o = {
|
||||
options: {
|
||||
yuicompress: true,
|
||||
},
|
||||
files: files
|
||||
files: files,
|
||||
};
|
||||
|
||||
lessData[theme] = o;
|
||||
});
|
||||
|
||||
var pkg = grunt.file.readJSON('package.json');
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
|
||||
@@ -135,44 +90,71 @@ module.exports = function (grunt) {
|
||||
mode: 0755,
|
||||
create: [
|
||||
'build/tmp',
|
||||
]
|
||||
},
|
||||
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
clean: {
|
||||
start: ['build/EspoCRM-*'],
|
||||
start: [
|
||||
'build/EspoCRM-*',
|
||||
'client/lib/*',
|
||||
'client/modules/crm/lib/*',
|
||||
'client/css/espo/*',
|
||||
],
|
||||
final: ['build/tmp'],
|
||||
release: ['build/EspoCRM-' + pkg.version],
|
||||
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/*',
|
||||
'build/tmp/client/custom/*',
|
||||
'!build/tmp/client/custom/modules',
|
||||
'build/tmp/client/custom/modules/*',
|
||||
'!build/tmp/client/custom/modules/dummy.txt',
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
less: lessData,
|
||||
|
||||
cssmin: {
|
||||
themes: {
|
||||
files: cssminFilesData
|
||||
}
|
||||
files: cssminFilesData,
|
||||
},
|
||||
},
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
mangle: false,
|
||||
mangle: true,
|
||||
sourceMap: true,
|
||||
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
|
||||
output: {
|
||||
comments: /^!/,
|
||||
},
|
||||
},
|
||||
bundle: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
|
||||
},
|
||||
files: {
|
||||
'client/lib/espo.min.js': jsFilesToBundle,
|
||||
},
|
||||
},
|
||||
lib: {
|
||||
files: libFilesToMinify,
|
||||
},
|
||||
'build/tmp/client/espo.min.js': jsFilesToMinify.map(function (item) {
|
||||
return '' + item;
|
||||
})
|
||||
},
|
||||
|
||||
copy: {
|
||||
options: {
|
||||
mode: true,
|
||||
},
|
||||
frontendFolders: {
|
||||
frontend: {
|
||||
expand: true,
|
||||
cwd: 'client',
|
||||
src: [
|
||||
@@ -184,29 +166,26 @@ module.exports = function (grunt) {
|
||||
'img/**',
|
||||
'css/**',
|
||||
'sounds/**',
|
||||
'custom/**'
|
||||
'custom/**',
|
||||
'lib/**',
|
||||
],
|
||||
dest: 'build/tmp/client',
|
||||
},
|
||||
frontendLib: {
|
||||
expand: true,
|
||||
dot: true,
|
||||
cwd: 'client/lib',
|
||||
src: '**',
|
||||
dest: 'build/tmp/client/lib/',
|
||||
files: jsFilesToCopy,
|
||||
},
|
||||
backend: {
|
||||
expand: true,
|
||||
dot: true,
|
||||
src: [
|
||||
'api/**',
|
||||
'application/**',
|
||||
'custom/**',
|
||||
'data/.data',
|
||||
'install/**',
|
||||
'portal/**',
|
||||
'vendor/**',
|
||||
'html/**',
|
||||
'public/**',
|
||||
'install/**',
|
||||
'bin/**',
|
||||
'bootstrap.php',
|
||||
'cron.php',
|
||||
'daemon.php',
|
||||
@@ -217,7 +196,6 @@ module.exports = function (grunt) {
|
||||
'extension.php',
|
||||
'websocket.php',
|
||||
'command.php',
|
||||
'oauth-callback.php',
|
||||
'index.php',
|
||||
'LICENSE.txt',
|
||||
'.htaccess',
|
||||
@@ -233,120 +211,205 @@ module.exports = function (grunt) {
|
||||
dest: 'build/EspoCRM-<%= pkg.version %>/',
|
||||
},
|
||||
},
|
||||
chmod: {
|
||||
php: {
|
||||
options: {
|
||||
mode: '644'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.php',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.json',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.config',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/.htaccess',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.js',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.css',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.tpl',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.html',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.txt',
|
||||
]
|
||||
},
|
||||
folders: {
|
||||
options: {
|
||||
mode: '755'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/install',
|
||||
'build/EspoCRM-<%= pkg.version %>/portal',
|
||||
'build/EspoCRM-<%= pkg.version %>/api',
|
||||
'build/EspoCRM-<%= pkg.version %>/api/v1',
|
||||
'build/EspoCRM-<%= pkg.version %>/api/v1/portal-access',
|
||||
'build/EspoCRM-<%= pkg.version %>',
|
||||
]
|
||||
},
|
||||
foldersWritable: {
|
||||
options: {
|
||||
mode: '775'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/data',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom/Espo',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom/Espo/Custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/modules',
|
||||
'build/EspoCRM-<%= pkg.version %>/application/Espo/Modules',
|
||||
]
|
||||
},
|
||||
},
|
||||
|
||||
replace: {
|
||||
version: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: 'version',
|
||||
replacement: '<%= pkg.version %>'
|
||||
replacement: '<%= pkg.version %>',
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
src: 'build/tmp/application/Espo/Resources/defaults/config.php',
|
||||
dest: 'build/tmp/application/Espo/Resources/defaults/config.php'
|
||||
dest: 'build/tmp/application/Espo/Resources/defaults/config.php',
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
dev: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /\# \{\#dev\}(.*)\{\/dev\}/gs,
|
||||
replacement: '',
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
src: 'build/tmp/.htaccess',
|
||||
dest: 'build/tmp/.htaccess',
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
grunt.registerTask("chmod-folders", function() {
|
||||
cp.execSync("find . -type d -exec chmod 755 {} + ", {stdio: 'ignore', cwd: 'build/EspoCRM-' + pkg.version});
|
||||
grunt.registerTask('chmod-folders', () => {
|
||||
cp.execSync(
|
||||
"find . -type d -exec chmod 755 {} +",
|
||||
{
|
||||
cwd: 'build/EspoCRM-' + pkg.version,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
grunt.registerTask("composer", function() {
|
||||
cp.execSync("composer install --ignore-platform-reqs --no-dev", {stdio: 'ignore'});
|
||||
grunt.registerTask('chmod-multiple', () => {
|
||||
let dirPath = 'build/EspoCRM-' + pkg.version;
|
||||
|
||||
let fileList = [
|
||||
{
|
||||
name: '*.php',
|
||||
},
|
||||
{
|
||||
name: '*.json',
|
||||
},
|
||||
{
|
||||
name: '*.config',
|
||||
},
|
||||
{
|
||||
name: '.htaccess',
|
||||
},
|
||||
{
|
||||
name: '*.html',
|
||||
},
|
||||
{
|
||||
name: '*.txt',
|
||||
},
|
||||
{
|
||||
name: '*.js',
|
||||
folder: 'client',
|
||||
},
|
||||
{
|
||||
name: '*.css',
|
||||
folder: 'client',
|
||||
},
|
||||
{
|
||||
name: '*.tpl',
|
||||
folder: 'client',
|
||||
},
|
||||
];
|
||||
|
||||
let dirReadableList = [
|
||||
'public/install',
|
||||
'public/portal',
|
||||
'public/api',
|
||||
'public/api/v1',
|
||||
'public/api/v1/portal-access',
|
||||
'.',
|
||||
];
|
||||
|
||||
let dirWritableList = [
|
||||
'data',
|
||||
'custom',
|
||||
'custom/Espo',
|
||||
'custom/Espo/Custom',
|
||||
'client/custom',
|
||||
'client/modules',
|
||||
'application/Espo/Modules',
|
||||
];
|
||||
|
||||
fileList.forEach(item => {
|
||||
let path = item.folder || '.';
|
||||
let name = item.name;
|
||||
|
||||
cp.execSync(
|
||||
`find ${path} -type f -iname "${name}" -exec chmod 644 {} +`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
dirReadableList.forEach(item => {
|
||||
cp.execSync(
|
||||
`chmod 755 ${item}`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
dirWritableList.forEach(item => {
|
||||
cp.execSync(
|
||||
`chmod 775 ${item}`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
cp.execSync(
|
||||
`find bin -type f -exec chmod 754 {} +`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
grunt.registerTask("composer-dev", function() {
|
||||
cp.execSync("composer install --ignore-platform-reqs", {stdio: 'ignore'});
|
||||
grunt.registerTask('composer-install', () => {
|
||||
cp.execSync("composer install --no-dev", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.registerTask("upgrade", function() {
|
||||
grunt.registerTask('composer-install-dev', () => {
|
||||
cp.execSync("composer install", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.registerTask('upgrade', () => {
|
||||
cp.execSync("node diff --all --vendor", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("unit-tests-run", function() {
|
||||
grunt.registerTask('unit-tests-run', () => {
|
||||
cp.execSync("vendor/bin/phpunit ./tests/unit", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("integration-tests-run", function() {
|
||||
grunt.registerTask('integration-tests-run', () => {
|
||||
cp.execSync("vendor/bin/phpunit ./tests/integration", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("zip", function() {
|
||||
var fs = require('fs');
|
||||
grunt.registerTask('set-config-params', () => {
|
||||
cp.execSync("composer run-script setConfigParams", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
var resolve = this.async();
|
||||
grunt.registerTask('zip', () => {
|
||||
const archiver = require('archiver');
|
||||
|
||||
var folder = 'EspoCRM-' + pkg.version;
|
||||
let resolve = this.async();
|
||||
|
||||
var zipPath = 'build/' + folder +'.zip';
|
||||
if (fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
|
||||
let folder = 'EspoCRM-' + pkg.version;
|
||||
|
||||
var archiver = require('archiver');
|
||||
var archive = archiver('zip');
|
||||
let zipPath = 'build/' + folder +'.zip';
|
||||
|
||||
archive.on('error', function (err) {
|
||||
if (fs.existsSync(zipPath)) {
|
||||
fs.unlinkSync(zipPath);
|
||||
}
|
||||
|
||||
let archive = archiver('zip');
|
||||
|
||||
archive.on('error', err => {
|
||||
grunt.fail.warn(err);
|
||||
});
|
||||
var zipOutput = fs.createWriteStream(zipPath);
|
||||
zipOutput.on('close', function () {
|
||||
|
||||
let zipOutput = fs.createWriteStream(zipPath);
|
||||
|
||||
zipOutput.on('close', () => {
|
||||
console.log("EspoCRM package has been built.");
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
archive.directory(currentPath + '/build/' + folder, folder).pipe(zipOutput);
|
||||
archive
|
||||
.directory(currentPath + '/build/' + folder, folder)
|
||||
.pipe(zipOutput)
|
||||
.finalize();
|
||||
});
|
||||
|
||||
archive.finalize();
|
||||
grunt.registerTask('npm-install', () => {
|
||||
cp.execSync("npm ci", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
@@ -356,34 +419,42 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-replace');
|
||||
grunt.loadNpmTasks('grunt-chmod');
|
||||
|
||||
grunt.registerTask('internal', [
|
||||
'less',
|
||||
'cssmin',
|
||||
'uglify:bundle',
|
||||
'copy:frontendLib',
|
||||
'uglify:lib',
|
||||
]);
|
||||
|
||||
grunt.registerTask('offline', [
|
||||
'clean:start',
|
||||
'mkdir:tmp',
|
||||
'less',
|
||||
'cssmin',
|
||||
'uglify',
|
||||
'copy:frontendFolders',
|
||||
'copy:frontendLib',
|
||||
'internal',
|
||||
'copy:frontend',
|
||||
'copy:backend',
|
||||
'replace',
|
||||
'clean:beforeFinal',
|
||||
'copy:final',
|
||||
'chmod-folders',
|
||||
'chmod:php',
|
||||
'chmod:folders',
|
||||
'chmod:foldersWritable',
|
||||
'chmod-multiple',
|
||||
'clean:final',
|
||||
]);
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'composer',
|
||||
grunt.registerTask('build', [
|
||||
'composer-install',
|
||||
'npm-install',
|
||||
'set-config-params',
|
||||
'offline',
|
||||
]);
|
||||
|
||||
grunt.registerTask('default', [
|
||||
'build',
|
||||
]);
|
||||
|
||||
grunt.registerTask('release', [
|
||||
'default',
|
||||
'build',
|
||||
'upgrade',
|
||||
'zip',
|
||||
'clean:release',
|
||||
@@ -396,7 +467,7 @@ module.exports = function (grunt) {
|
||||
]);
|
||||
|
||||
grunt.registerTask('run-unit-tests', [
|
||||
'composer-dev',
|
||||
'composer-install-dev',
|
||||
'unit-tests-run',
|
||||
]);
|
||||
|
||||
@@ -406,12 +477,87 @@ module.exports = function (grunt) {
|
||||
]);
|
||||
|
||||
grunt.registerTask('dev', [
|
||||
'composer-dev',
|
||||
'composer-install-dev',
|
||||
'less',
|
||||
]);
|
||||
|
||||
grunt.registerTask('test', [
|
||||
'composer-dev',
|
||||
'composer-install-dev',
|
||||
'npm-install',
|
||||
'offline',
|
||||
]);
|
||||
};
|
||||
|
||||
function getBundleLibList() {
|
||||
const libs = require('./frontend/libs.json');
|
||||
|
||||
let list = [];
|
||||
|
||||
libs.forEach(item => {
|
||||
if (!item.bundle) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.files) {
|
||||
item.files.forEach(item => {
|
||||
list.push(item.src);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item.src) {
|
||||
throw new Error("No lib src.");
|
||||
}
|
||||
|
||||
list.push(item.src);
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function getCopyLibDataList() {
|
||||
const libs = require('./frontend/libs.json');
|
||||
|
||||
let list = [];
|
||||
|
||||
libs.forEach(item => {
|
||||
if (item.bundle) {
|
||||
return;
|
||||
}
|
||||
|
||||
let minify = item.minify;
|
||||
|
||||
if (item.files) {
|
||||
item.files.forEach(item => {
|
||||
list.push({
|
||||
src: item.src,
|
||||
dest: item.dest || 'client/lib/' + item.src.split('/').pop(),
|
||||
minify: minify,
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item.src) {
|
||||
throw new Error("No lib src.");
|
||||
}
|
||||
|
||||
list.push({
|
||||
src: item.src,
|
||||
dest: item.dest || 'client/lib/' + item.src.split('/').pop(),
|
||||
minify: minify,
|
||||
});
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function camelCaseToHyphen(string){
|
||||
if (string === null) {
|
||||
return string;
|
||||
}
|
||||
|
||||
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
|
||||
18
README.md
18
README.md
@@ -1,6 +1,8 @@
|
||||
## 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)
|
||||
|
||||
[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.
|
||||
|
||||
@@ -8,22 +10,22 @@ It's a web application with a frontend designed as a single page application and
|
||||
|
||||
### Requirements
|
||||
|
||||
* PHP 7.2 and later (with pdo, json, gd, openssl, zip, imap, mbstring, curl extensions);
|
||||
* PHP 7.4 and later (with pdo, json, gd, openssl, zip, imap, mbstring, curl extensions);
|
||||
* MySQL 5.7 (and later), or MariaDB 10.1 (and later).
|
||||
|
||||
For more information about server configuration see [this article](https://docs.espocrm.com/administration/server-configuration/).
|
||||
|
||||
### Documentation
|
||||
|
||||
Documentation for administrators, users and developers is available [here](https://docs.espocrm.com).
|
||||
The documentation for administrators, users and developers is available [here](https://docs.espocrm.com).
|
||||
|
||||
### How to report a bug
|
||||
### Bug reporting
|
||||
|
||||
Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our [forum](http://forum.espocrm.com/forum/bug-reports).
|
||||
|
||||
### How to install a stable version
|
||||
### Installing the stable version
|
||||
|
||||
[Download](https://www.espocrm.com/download/) the latest version. See the [instructions](https://docs.espocrm.com/administration/installation/) about installation.
|
||||
See the [instructions](https://docs.espocrm.com/administration/installation/) about installation.
|
||||
|
||||
### Development
|
||||
|
||||
@@ -31,13 +33,13 @@ Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our
|
||||
* [Running tests](https://docs.espocrm.com/development/tests)
|
||||
* [Making translation](https://docs.espocrm.com/development/translation)
|
||||
|
||||
### How to contribute
|
||||
### 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.
|
||||
|
||||
Branches:
|
||||
|
||||
* *hotfix/** – upcoming maintenance release; fixes should be pushed to this branch;
|
||||
* *fix* – 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.
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Attachment extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
$hasParent = false;
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
} else if ($entity->get('relatedId') && $entity->get('relatedType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('relatedType'), $entity->get('relatedId'));
|
||||
}
|
||||
|
||||
if ($hasParent) {
|
||||
if ($parent) {
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
if ($parent->get('parentId') && $parent->get('parentType')) {
|
||||
$parentOfParent = $this->getEntityManager()->getEntity($parent->get('parentType'), $parent->get('parentId'));
|
||||
if ($parentOfParent && $this->getAclManager()->checkEntity($user, $parentOfParent)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Email extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
protected $ownerUserIdAttribute = 'usersIds';
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($data)) {
|
||||
if ($data->read === false || $data->read === 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$entity->has('usersIds')) {
|
||||
$entity->loadLinkMultipleField('users');
|
||||
}
|
||||
$userIdList = $entity->get('usersIds');
|
||||
if (is_array($userIdList) && in_array($user->id, $userIdList)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->hasLinkMultipleId('assignedUsers', $user->id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->delete === 'own') {
|
||||
if ($user->id === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$assignedUserIdList = $entity->getLinkMultipleIdList('assignedUsers');
|
||||
if (count($assignedUserIdList) === 1 && $entity->hasLinkMultipleId('assignedUsers', $user->id)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'delete')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->edit !== 'no' || $data->create !== 'no') {
|
||||
if ($entity->get('createdById') === $user->id) {
|
||||
if ($entity->get('status') !== 'Sent' && $entity->get('status') !== 'Archived') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailAddress extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('EmailAddress');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameAddressList = $repository->getEntityListByAddressId($id, $excludeEntity);
|
||||
foreach ($entityWithSameAddressList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
if (
|
||||
$e->getEntityType() === 'User' &&
|
||||
$e->isPortal() &&
|
||||
$excludeEntity->getEntityType() === 'Contact' &&
|
||||
$e->get('contactId') === $excludeEntity->id
|
||||
) {
|
||||
$isFobidden = false;
|
||||
}
|
||||
if ($isFobidden) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Note extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
protected $deleteThresholdPeriod = '1 month';
|
||||
|
||||
protected $editThresholdPeriod = '7 days';
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($entity->get('type') === 'Post' && $user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
if ($parent) {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent, 'stream')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'edit')) {
|
||||
if ($this->checkIsOwner($user, $entity)) {
|
||||
$createdAt = $entity->get('createdAt');
|
||||
if ($createdAt) {
|
||||
$noteEditThresholdPeriod = '-' . $this->getConfig()->get('noteEditThresholdPeriod', $this->editThresholdPeriod);
|
||||
$dt = new \DateTime();
|
||||
$dt->modify($noteEditThresholdPeriod);
|
||||
try {
|
||||
if ($dt->format('U') > (new \DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'delete')) {
|
||||
if ($this->checkIsOwner($user, $entity)) {
|
||||
$createdAt = $entity->get('createdAt');
|
||||
if ($createdAt) {
|
||||
$deleteThresholdPeriod = '-' . $this->getConfig()->get('noteDeleteThresholdPeriod', $this->deleteThresholdPeriod);
|
||||
$dt = new \DateTime();
|
||||
$dt->modify($deleteThresholdPeriod);
|
||||
try {
|
||||
if ($dt->format('U') > (new \DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PhoneNumber extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('PhoneNumber');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameNumberList = $repository->getEntityListByPhoneNumberId($id, $excludeEntity);
|
||||
foreach ($entityWithSameNumberList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
if (
|
||||
$e->getEntityType() === 'User' &&
|
||||
$e->isPortal() &&
|
||||
$excludeEntity->getEntityType() === 'Contact' &&
|
||||
$e->get('contactId') === $excludeEntity->id
|
||||
) {
|
||||
$isFobidden = false;
|
||||
}
|
||||
if ($isFobidden) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Webhook extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
return $user->id === $entity->get('userId') && $user->isApi();
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\AclPortal;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class Attachment extends \Espo\Core\AclPortal\Base
|
||||
{
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
$hasParent = false;
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
} else if ($entity->get('relatedId') && $entity->get('relatedType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('relatedType'), $entity->get('relatedId'));
|
||||
}
|
||||
|
||||
if ($hasParent) {
|
||||
if ($parent) {
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
if ($parent->get('parentId') && $parent->get('parentType')) {
|
||||
$parentOfParent = $this->getEntityManager()->getEntity($parent->get('parentType'), $parent->get('parentId'));
|
||||
if ($parentOfParent && $this->getAclManager()->checkEntity($user, $parentOfParent)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 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\AclPortal;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class EmailAddress extends \Espo\Core\AclPortal\Base
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('EmailAddress');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameAddressList = $repository->getEntityListByAddressId($id, $excludeEntity);
|
||||
foreach ($entityWithSameAddressList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\ActionHistoryRecord;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\ActionHistoryRecord>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $entity->get('userId') === $user->getId();
|
||||
}
|
||||
}
|
||||
171
application/Espo/Classes/Acl/Attachment/AccessChecker.php
Normal file
171
application/Espo/Classes/Acl/Attachment/AccessChecker.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Attachment;
|
||||
|
||||
use Espo\Entities\{
|
||||
User,
|
||||
Note,
|
||||
Attachment,
|
||||
};
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
ORM\EntityManager,
|
||||
AclManager,
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<Attachment>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(
|
||||
DefaultAccessChecker $defaultAccessChecker,
|
||||
AclManager $aclManager,
|
||||
EntityManager $entityManager
|
||||
) {
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var Attachment $entity */
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
// Allow the logo.
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
|
||||
$parentType = $entity->get('parentType');
|
||||
$parentId = $entity->get('parentId');
|
||||
|
||||
$relatedType = $entity->get('relatedType');
|
||||
$relatedId = $entity->get('relatedId');
|
||||
|
||||
if ($parentId && $parentType) {
|
||||
$parent = $this->entityManager->getEntityById($parentType, $parentId);
|
||||
}
|
||||
else if ($relatedId && $relatedType) {
|
||||
$parent = $this->entityManager->getEntityById($relatedType, $relatedId);
|
||||
}
|
||||
|
||||
if (!$parent) {
|
||||
if ($this->defaultAccessChecker->checkEntityRead($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
/** @var Note $parent */
|
||||
$result = $this->checkEntityReadNoteParent($user, $parent);
|
||||
|
||||
if ($result !== null) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
else if ($this->aclManager->checkEntity($user, $parent)) {
|
||||
if (
|
||||
$entity->getTargetField() &&
|
||||
in_array(
|
||||
$entity->getTargetField(),
|
||||
$this->aclManager->getScopeForbiddenFieldList($user, $parent->getEntityType())
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->defaultAccessChecker->checkEntityRead($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkEntityReadNoteParent(User $user, Note $note): ?bool
|
||||
{
|
||||
if ($note->getTargetType() === Note::TARGET_TEAMS) {
|
||||
$intersect = array_intersect(
|
||||
$note->getLinkMultipleIdList('teams') ?? [],
|
||||
$user->getLinkMultipleIdList('teams') ?? []
|
||||
);
|
||||
|
||||
if (count($intersect)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($note->getTargetType() === Note::TARGET_USERS) {
|
||||
$isRelated = $this->entityManager
|
||||
->getRDBRepository('Note')
|
||||
->getRelation($note, 'users')
|
||||
->isRelated($user);
|
||||
|
||||
if ($isRelated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$note->getParentId() || !$note->getParentType()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $this->entityManager->getEntity($note->getParentType(), $note->getParentId());
|
||||
|
||||
if ($parent && $this->aclManager->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
55
application/Espo/Classes/Acl/Attachment/OwnershipChecker.php
Normal file
55
application/Espo/Classes/Acl/Attachment/OwnershipChecker.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Attachment;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Attachment>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
private const ATTR_CREATED_BY_ID = 'createdById';
|
||||
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($user->getId() === $entity->get(self::ATTR_CREATED_BY_ID)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
59
application/Espo/Classes/Acl/AuthToken/AccessChecker.php
Normal file
59
application/Espo/Classes/Acl/AuthToken/AccessChecker.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\AuthToken;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\AuthToken>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker)
|
||||
{
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
}
|
||||
|
||||
public function checkCreate(User $user, ScopeData $data): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
171
application/Espo/Classes/Acl/Email/AccessChecker.php
Normal file
171
application/Espo/Classes/Acl/Email/AccessChecker.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Email;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\Entities\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\Table,
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDSChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDSChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDSChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker)
|
||||
{
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
if ($this->defaultAccessChecker->checkEntityRead($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->isFalse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->getRead() === Table::LEVEL_NO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$entity->has('usersIds')) {
|
||||
$entity->loadLinkMultipleField('users');
|
||||
}
|
||||
|
||||
$userIdList = $entity->get('usersIds');
|
||||
|
||||
if (is_array($userIdList) && in_array($user->getId(), $userIdList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->isFalse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->getDelete() === Table::LEVEL_OWN) {
|
||||
if ($user->getId() === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var string[] */
|
||||
$assignedUserIdList = $entity->getLinkMultipleIdList('assignedUsers');
|
||||
|
||||
if (
|
||||
count($assignedUserIdList) === 1 &&
|
||||
$entity->hasLinkMultipleId('assignedUsers', $user->getId())
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->defaultAccessChecker->checkEntityDelete($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->getEdit() === Table::LEVEL_NO && $data->getCreate() === Table::LEVEL_NO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->get('createdById') !== $user->getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->get('status') !== 'Sent' && $entity->get('status') !== 'Archived') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
if (
|
||||
$entity->getStatus() === Email::STATUS_DRAFT &&
|
||||
$entity->getCreatedBy() &&
|
||||
$entity->getCreatedBy()->getId() === $user->getId()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityEdit($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEdit(User $user, ScopeData $data): bool
|
||||
{
|
||||
if ($data->getCreate() === Table::LEVEL_YES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEdit($user, $data);
|
||||
}
|
||||
|
||||
public function checkDelete(User $user, ScopeData $data): bool
|
||||
{
|
||||
if ($data->getCreate() === Table::LEVEL_YES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkDelete($user, $data);
|
||||
}
|
||||
}
|
||||
51
application/Espo/Classes/Acl/Email/AssignmentChecker.php
Normal file
51
application/Espo/Classes/Acl/Email/AssignmentChecker.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Email;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\DefaultAssignmentChecker,
|
||||
};
|
||||
|
||||
class AssignmentChecker extends DefaultAssignmentChecker
|
||||
{
|
||||
protected function isPermittedAssignedUser(User $user, Entity $entity): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isPermittedAssignedUsers(User $user, Entity $entity): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,46 +27,53 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\AclPortal;
|
||||
namespace Espo\Classes\Acl\Email;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Entities\Email;
|
||||
|
||||
class Email extends \Espo\Core\AclPortal\Base
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\DefaultOwnershipChecker,
|
||||
Acl\OwnershipOwnChecker,
|
||||
Acl\OwnershipTeamChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Email>
|
||||
* @implements OwnershipTeamChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker, OwnershipTeamChecker
|
||||
{
|
||||
protected $ownerUserIdAttribute = 'usersIds';
|
||||
private $defaultOwnershipChecker;
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
public function __construct(DefaultOwnershipChecker $defaultOwnershipChecker)
|
||||
{
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
$this->defaultOwnershipChecker = $defaultOwnershipChecker;
|
||||
}
|
||||
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
if ($user->getId() === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($data)) {
|
||||
if ($data->read === false || $data->read === 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$entity->has('usersIds')) {
|
||||
$entity->loadLinkMultipleField('users');
|
||||
}
|
||||
$userIdList = $entity->get('usersIds');
|
||||
if (is_array($userIdList) && in_array($user->id, $userIdList)) {
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->hasLinkMultipleId('assignedUsers', $user->getId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
public function checkTeam(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $this->defaultOwnershipChecker->checkTeam($user, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,57 +27,56 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Authentication\TwoFactor\Methods;
|
||||
namespace Espo\Classes\Acl\EmailFilter;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use StdClass;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
class Totp implements CodeVerify
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\EmailFilter>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
protected $entityManager;
|
||||
protected $totp;
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager, TotpUtils $totp)
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->totp = $totp;
|
||||
}
|
||||
|
||||
public function verifyCode(User $user, string $code) : bool
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$userData = $this->entityManager
|
||||
->getRepository('UserData')
|
||||
->getByUserId($user->id);
|
||||
|
||||
if (!$userData) {
|
||||
if (!$entity->has('parentId') || !$entity->has('parentType')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$userData->get('auth2FA')) {
|
||||
$parentType = $entity->get('parentType');
|
||||
$parentId = $entity->get('parentId');
|
||||
|
||||
if (!$parentType || !$parentId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($userData->get('auth2FAMethod') != 'Totp') {
|
||||
$parent = $this->entityManager->getEntity($parentType, $parentId);
|
||||
|
||||
if (!$parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$secret = $userData->get('auth2FATotpSecret');
|
||||
|
||||
if (!$secret) {
|
||||
return false;
|
||||
if ($parent->getEntityType() === 'User') {
|
||||
return $parent->getId() === $user->getId();
|
||||
}
|
||||
|
||||
return $this->totp->verifyCode($secret, $code);
|
||||
}
|
||||
if ($parent->has('assignedUserId') && $parent->get('assignedUserId') === $user->getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLoginData(User $user) : StdClass
|
||||
{
|
||||
return (object) [
|
||||
'message' => 'enterTotpCode',
|
||||
];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
88
application/Espo/Classes/Acl/Import/AccessChecker.php
Normal file
88
application/Espo/Classes/Acl/Import/AccessChecker.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Import;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\AccessEntityReadChecker,
|
||||
Acl\AccessEntityDeleteChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityReadChecker<\Espo\Entities\Import>
|
||||
* @implements AccessEntityDeleteChecker<\Espo\Entities\Import>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityReadChecker, AccessEntityDeleteChecker
|
||||
{
|
||||
public function check(User $user, ScopeData $data): bool
|
||||
{
|
||||
return $data->isTrue();
|
||||
}
|
||||
|
||||
public function checkRead(User $user, ScopeData $data): bool
|
||||
{
|
||||
return $data->isTrue();
|
||||
}
|
||||
|
||||
public function checkDelete(User $user, ScopeData $data): bool
|
||||
{
|
||||
return $data->isTrue();
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
175
application/Espo/Classes/Acl/Note/AccessChecker.php
Normal file
175
application/Espo/Classes/Acl/Note/AccessChecker.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Note;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
AclManager,
|
||||
ORM\EntityManager,
|
||||
Utils\Config,
|
||||
};
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\Note>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private const EDIT_PERIOD = '7 days';
|
||||
|
||||
private const DELETE_PERIOD = '1 month';
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private $config;
|
||||
|
||||
public function __construct(
|
||||
DefaultAccessChecker $defaultAccessChecker,
|
||||
AclManager $aclManager,
|
||||
EntityManager $entityManager,
|
||||
Config $config
|
||||
) {
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
$parentId = $entity->get('parentId');
|
||||
$parentType = $entity->get('parentType');
|
||||
|
||||
if (!$parentId || !$parentType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = $this->entityManager->getEntity($parentType, $parentId);
|
||||
|
||||
if ($parent && $this->aclManager->checkEntityStream($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->defaultAccessChecker->checkEntityEdit($user, $entity, $data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->aclManager->checkOwnershipOwn($user, $entity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$createdAt = $entity->get('createdAt');
|
||||
|
||||
if (!$createdAt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$noteEditThresholdPeriod =
|
||||
'-' . $this->config->get('noteEditThresholdPeriod', self::EDIT_PERIOD);
|
||||
|
||||
$dt = new DateTime();
|
||||
|
||||
$dt->modify($noteEditThresholdPeriod);
|
||||
|
||||
try {
|
||||
if ($dt->format('U') > (new DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->defaultAccessChecker->checkEntityDelete($user, $entity, $data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->aclManager->checkOwnershipOwn($user, $entity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$createdAt = $entity->get('createdAt');
|
||||
|
||||
if (!$createdAt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$deleteThresholdPeriod =
|
||||
'-' . $this->config->get('noteDeleteThresholdPeriod', self::DELETE_PERIOD);
|
||||
|
||||
$dt = new DateTime();
|
||||
|
||||
$dt->modify($deleteThresholdPeriod);
|
||||
|
||||
try {
|
||||
if ($dt->format('U') > (new DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
53
application/Espo/Classes/Acl/Note/OwnershipChecker.php
Normal file
53
application/Espo/Classes/Acl/Note/OwnershipChecker.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Note;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Note>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($entity->get('type') === 'Post' && $user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,23 +27,27 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\AclPortal;
|
||||
namespace Espo\Classes\Acl\Notification;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\AclPortal\Acl;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
class Account extends Acl
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Notification>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkInAccount(User $user, Entity $entity)
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$accountIdList = $user->getLinkMultipleIdList('accounts');
|
||||
if (count($accountIdList)) {
|
||||
if (in_array($entity->id, $accountIdList)) {
|
||||
return true;
|
||||
}
|
||||
if ($user->getId() === $entity->get('userId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
66
application/Espo/Classes/Acl/Portal/AccessChecker.php
Normal file
66
application/Espo/Classes/Acl/Portal/AccessChecker.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Portal;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
Acl\Table,
|
||||
AclManager,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\Portal>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker, AclManager $aclManager)
|
||||
{
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
}
|
||||
|
||||
public function check(User $user, ScopeData $data): bool
|
||||
{
|
||||
$level = $this->aclManager->getPermissionLevel($user, 'portal');
|
||||
|
||||
return $level === Table::LEVEL_YES;
|
||||
}
|
||||
}
|
||||
92
application/Espo/Classes/Acl/ScheduledJob/AccessChecker.php
Normal file
92
application/Espo/Classes/Acl/ScheduledJob/AccessChecker.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\ScheduledJob;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\ScheduledJob>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker)
|
||||
{
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->get('isInternal')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->get('isInternal')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityRead($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->get('isInternal')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityEdit($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->get('isInternal')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityDelete($user, $entity, $data);
|
||||
}
|
||||
}
|
||||
52
application/Espo/Classes/Acl/Team/OwnershipChecker.php
Normal file
52
application/Espo/Classes/Acl/Team/OwnershipChecker.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Team;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Team>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
/** @var string[] */
|
||||
$userTeamIdList = $user->getLinkMultipleIdList('teams');
|
||||
|
||||
return in_array($entity->getId(), $userTeamIdList);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,72 +27,116 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
namespace Espo\Classes\Acl\User;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Entities\User as EntityUser;
|
||||
|
||||
class User extends \Espo\Core\Acl\Acl
|
||||
use Espo\Core\{
|
||||
Acl\Table,
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDSChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
AclManager,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDSChecker<User>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDSChecker
|
||||
{
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker, AclManager $aclManager)
|
||||
{
|
||||
return $user->id === $entity->id;
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
}
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if (!$user->isAdmin() && $entity->isPortal()) {
|
||||
if ($this->getAclManager()->get($user, 'portalPermission') === 'yes') {
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isPortal()) {
|
||||
if ($this->aclManager->getPermissionLevel($user, 'portal') === Table::LEVEL_YES) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'read');
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'create');
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityRead($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->id === 'system') {
|
||||
return false;
|
||||
}
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return parent::checkEntityDelete($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->id === 'system') {
|
||||
return false;
|
||||
}
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
if (!$user->isAdmin()) {
|
||||
if ($user->id !== $entity->id) {
|
||||
if ($user->getId() !== $entity->getId()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'edit');
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityEdit($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityDelete($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityStream(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
return $this->aclManager->checkUserPermission($user, $entity, 'user');
|
||||
}
|
||||
}
|
||||
67
application/Espo/Classes/Acl/User/OwnershipChecker.php
Normal file
67
application/Espo/Classes/Acl/User/OwnershipChecker.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\User;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
Acl\OwnershipTeamChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\User>
|
||||
* @implements OwnershipTeamChecker<\Espo\Entities\User>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker, OwnershipTeamChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $user->getId() === $entity->getId();
|
||||
}
|
||||
|
||||
public function checkTeam(User $user, Entity $entity): bool
|
||||
{
|
||||
assert($entity instanceof CoreEntity);
|
||||
|
||||
$intersect = array_intersect(
|
||||
$user->getLinkMultipleIdList('teams') ?? [],
|
||||
$entity->getLinkMultipleIdList('teams') ?? []
|
||||
);
|
||||
|
||||
if (count($intersect)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
110
application/Espo/Classes/Acl/Webhook/AccessChecker.php
Normal file
110
application/Espo/Classes/Acl/Webhook/AccessChecker.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Webhook;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\Webhook>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker)
|
||||
{
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
}
|
||||
|
||||
public function check(User $user, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$user->isApi()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->isFalse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
return $this->checkEntityInternal($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
return $this->checkEntityInternal($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
return $this->checkEntityInternal($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
return $this->checkEntityInternal($user, $entity, $data);
|
||||
}
|
||||
|
||||
private function checkEntityInternal(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->isFalse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user->isApi() && $user->getId() === $entity->get('userId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
46
application/Espo/Classes/Acl/Webhook/OwnershipChecker.php
Normal file
46
application/Espo/Classes/Acl/Webhook/OwnershipChecker.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Acl\Webhook;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\Acl\OwnershipOwnChecker;
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Webhook>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $user->getId() === $entity->get('userId') && $user->isApi();
|
||||
}
|
||||
}
|
||||
177
application/Espo/Classes/AclPortal/Attachment/AccessChecker.php
Normal file
177
application/Espo/Classes/AclPortal/Attachment/AccessChecker.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Attachment;
|
||||
|
||||
use Espo\Entities\{
|
||||
User,
|
||||
Note,
|
||||
Attachment,
|
||||
};
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
ORM\EntityManager,
|
||||
Portal\AclManager,
|
||||
Acl\ScopeData,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Portal\Acl\DefaultAccessChecker,
|
||||
Portal\Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<Attachment>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(
|
||||
DefaultAccessChecker $defaultAccessChecker,
|
||||
AclManager $aclManager,
|
||||
EntityManager $entityManager
|
||||
) {
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var Attachment $entity */
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
// Allow the logo.
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
|
||||
$parentType = $entity->get('parentType');
|
||||
$parentId = $entity->get('parentId');
|
||||
|
||||
$relatedType = $entity->get('relatedType');
|
||||
$relatedId = $entity->get('relatedId');
|
||||
|
||||
if ($parentId && $parentType) {
|
||||
$parent = $this->entityManager->getEntityById($parentType, $parentId);
|
||||
}
|
||||
else if ($relatedId && $relatedType) {
|
||||
$parent = $this->entityManager->getEntityById($relatedType, $relatedId);
|
||||
}
|
||||
|
||||
if (!$parent) {
|
||||
if ($entity->get('createdById') === $user->getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
/** @var Note $parent */
|
||||
$result = $this->checkEntityReadNoteParent($user, $parent);
|
||||
|
||||
if ($result !== null) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
else if ($this->aclManager->checkEntity($user, $parent)) {
|
||||
if (
|
||||
$entity->getTargetField() &&
|
||||
in_array(
|
||||
$entity->getTargetField(),
|
||||
$this->aclManager->getScopeForbiddenFieldList($user, $parent->getEntityType())
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->defaultAccessChecker->checkEntityRead($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkEntityReadNoteParent(User $user, Note $note): ?bool
|
||||
{
|
||||
if ($note->isInternal()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($note->getTargetType() === Note::TARGET_PORTALS) {
|
||||
$intersect = array_intersect(
|
||||
$note->getLinkMultipleIdList('portals') ?? [],
|
||||
$user->getLinkMultipleIdList('portals') ?? []
|
||||
);
|
||||
|
||||
if (count($intersect)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($note->getTargetType() === Note::TARGET_USERS) {
|
||||
$isRelated = $this->entityManager
|
||||
->getRDBRepository('Note')
|
||||
->getRelation($note, 'users')
|
||||
->isRelated($user);
|
||||
|
||||
if ($isRelated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$note->getParentId() || !$note->getParentType()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $this->entityManager->getEntity($note->getParentType(), $note->getParentId());
|
||||
|
||||
if ($parent && $this->aclManager->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Attachment;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Attachment>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
private const ATTR_CREATED_BY_ID = 'createdById';
|
||||
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($user->getId() === $entity->get(self::ATTR_CREATED_BY_ID)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
85
application/Espo/Classes/AclPortal/Email/AccessChecker.php
Normal file
85
application/Espo/Classes/AclPortal/Email/AccessChecker.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Email;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\Table,
|
||||
Acl\ScopeData,
|
||||
Acl\AccessEntityCREDSChecker,
|
||||
Portal\Acl\DefaultAccessChecker,
|
||||
Portal\Acl\Traits\DefaultAccessCheckerDependency,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDSChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDSChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
public function __construct(
|
||||
DefaultAccessChecker $defaultAccessChecker
|
||||
) {
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($this->defaultAccessChecker->checkEntityRead($user, $entity, $data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->isFalse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->getRead() === Table::LEVEL_NO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert($entity instanceof CoreEntity);
|
||||
|
||||
$userIdList = $entity->getLinkMultipleIdLIst('users');
|
||||
|
||||
if (is_array($userIdList) && in_array($user->getId(), $userIdList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,23 +27,27 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\AclPortal;
|
||||
namespace Espo\Classes\AclPortal\Email;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\AclPortal\Acl;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
class Contact extends Acl
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkIsOwnContact(User $user, Entity $entity)
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$contactId = $user->get('contactId');
|
||||
if ($contactId) {
|
||||
if ($entity->id === $contactId) {
|
||||
return true;
|
||||
}
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
192
application/Espo/Classes/AclPortal/Note/AccessChecker.php
Normal file
192
application/Espo/Classes/AclPortal/Note/AccessChecker.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Note;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Portal\AclManager,
|
||||
Acl\ScopeData,
|
||||
Acl\AccessEntityCREDChecker,
|
||||
Portal\Acl\DefaultAccessChecker,
|
||||
Portal\Acl\Traits\DefaultAccessCheckerDependency,
|
||||
ORM\EntityManager,
|
||||
Utils\Config,
|
||||
};
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDChecker<\Espo\Entities\Note>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDChecker
|
||||
{
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private const EDIT_PERIOD = '7 days';
|
||||
|
||||
private const DELETE_PERIOD = '1 month';
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private $config;
|
||||
|
||||
public function __construct(
|
||||
DefaultAccessChecker $defaultAccessChecker,
|
||||
AclManager $aclManager,
|
||||
EntityManager $entityManager,
|
||||
Config $config
|
||||
) {
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
$parentId = $entity->get('parentId');
|
||||
$parentType = $entity->get('parentType');
|
||||
|
||||
if (!$parentId || !$parentType) {
|
||||
return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data);
|
||||
}
|
||||
|
||||
$parent = $this->entityManager->getEntity($parentType, $parentId);
|
||||
|
||||
if ($parent && $this->aclManager->checkEntityStream($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->get('type') !== 'Post') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->get('type') === 'Post' && $entity->get('targetType')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$entity->get('parentId') || !$entity->get('parentType')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parent = $this->entityManager->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
|
||||
if ($parent) {
|
||||
if ($this->aclManager->checkEntityStream($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if (!$this->defaultAccessChecker->checkEntityEdit($user, $entity, $data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->aclManager->checkOwnershipOwn($user, $entity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$createdAt = $entity->get('createdAt');
|
||||
|
||||
if (!$createdAt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$noteEditThresholdPeriod =
|
||||
'-' . $this->config->get('noteEditThresholdPeriod', self::EDIT_PERIOD);
|
||||
|
||||
$dt = new DateTime();
|
||||
|
||||
$dt->modify($noteEditThresholdPeriod);
|
||||
|
||||
try {
|
||||
if ($dt->format('U') > (new DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if (!$this->defaultAccessChecker->checkEntityDelete($user, $entity, $data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->aclManager->checkOwnershipOwn($user, $entity)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$createdAt = $entity->get('createdAt');
|
||||
|
||||
if (!$createdAt) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$deleteThresholdPeriod =
|
||||
'-' . $this->config->get('noteDeleteThresholdPeriod', self::DELETE_PERIOD);
|
||||
|
||||
$dt = new DateTime();
|
||||
|
||||
$dt->modify($deleteThresholdPeriod);
|
||||
|
||||
try {
|
||||
if ($dt->format('U') > (new DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
53
application/Espo/Classes/AclPortal/Note/OwnershipChecker.php
Normal file
53
application/Espo/Classes/AclPortal/Note/OwnershipChecker.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Note;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Note>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($entity->get('type') === 'Post' && $user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\Notification;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Notification>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($user->getId() === $entity->get('userId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
49
application/Espo/Classes/AclPortal/User/OwnershipChecker.php
Normal file
49
application/Espo/Classes/AclPortal/User/OwnershipChecker.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AclPortal\User;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\User>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $user->getId() === $entity->getId();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter1 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter2 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter3 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter4 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -30,28 +30,26 @@
|
||||
namespace Espo\Classes\AppInfo;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Module,
|
||||
Binding\EspoBindingLoader,
|
||||
Binding\Binding as BindingItem,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Binding
|
||||
{
|
||||
protected $fileManager;
|
||||
private $module;
|
||||
|
||||
public function __construct(FileManager $fileManager)
|
||||
public function __construct(Module $module)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
public function process(array $options, array $flagList) : ?string
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$bindingLoader = new EspoBindingLoader(
|
||||
new Module($this->fileManager)
|
||||
);
|
||||
$bindingLoader = new EspoBindingLoader($this->module);
|
||||
|
||||
$data = $bindingLoader->load();
|
||||
|
||||
@@ -71,14 +69,14 @@ class Binding
|
||||
$keyList = $data->getContextKeyList($context);
|
||||
|
||||
foreach ($keyList as $key) {
|
||||
$result .= $this->printItem($key, $data->getContext($context, $key), true);
|
||||
$result .= $this->printItem($key, $data->getContext($context, $key));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function printItem(string $key, BindingItem $binding) : string
|
||||
private function printItem(string $key, BindingItem $binding): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
@@ -94,6 +92,7 @@ class Binding
|
||||
BindingItem::CONTAINER_SERVICE => 'Service',
|
||||
BindingItem::VALUE => 'Value',
|
||||
BindingItem::CALLBACK => 'Callback',
|
||||
BindingItem::FACTORY_CLASS_NAME => 'Factory',
|
||||
][$type];
|
||||
|
||||
$result .= $tab . "Type: {$typeString}\n";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -32,12 +32,14 @@ namespace Espo\Classes\AppInfo;
|
||||
use Espo\Core\{
|
||||
Container as ContainerService,
|
||||
Utils\Metadata,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Container
|
||||
{
|
||||
protected $container;
|
||||
protected $metadata;
|
||||
private $container;
|
||||
|
||||
private $metadata;
|
||||
|
||||
public function __construct(ContainerService $container, Metadata $metadata)
|
||||
{
|
||||
@@ -45,9 +47,9 @@ class Container
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function process(array $options, array $flagList) : ?string
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$nameOnly = in_array('nameOnly', $flagList);
|
||||
$nameOnly = $params->hasFlag('nameOnly');
|
||||
|
||||
$result = '';
|
||||
|
||||
@@ -61,10 +63,11 @@ class Container
|
||||
'user',
|
||||
];
|
||||
|
||||
/** @var string[] */
|
||||
$fileList = scandir('application/Espo/Core/Loaders');
|
||||
|
||||
if (file_exists('custom/Espo/Custom/Core/Loaders')) {
|
||||
$fileList = array_merge($fileList, scandir('custom/Espo/Custom/Core/Loaders'));
|
||||
$fileList = array_merge($fileList, scandir('custom/Espo/Custom/Core/Loaders') ?: []);
|
||||
}
|
||||
|
||||
foreach ($fileList as $file) {
|
||||
|
||||
68
application/Espo/Classes/AppInfo/Jobs.php
Normal file
68
application/Espo/Classes/AppInfo/Jobs.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AppInfo;
|
||||
|
||||
use Espo\Core\Console\Command\Params;
|
||||
use Espo\Core\Utils\ClassFinder;
|
||||
use Espo\Core\Job\MetadataProvider;
|
||||
|
||||
class Jobs
|
||||
{
|
||||
private $classFinder;
|
||||
|
||||
private $metadataProvider;
|
||||
|
||||
public function __construct(ClassFinder $classFinder, MetadataProvider $metadataProvider)
|
||||
{
|
||||
$this->classFinder = $classFinder;
|
||||
$this->metadataProvider = $metadataProvider;
|
||||
}
|
||||
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$result = "Available jobs:\n\n";
|
||||
|
||||
$list = array_map(
|
||||
function ($item) {
|
||||
return ' ' . $item;
|
||||
},
|
||||
array_unique(
|
||||
array_merge(
|
||||
array_keys($this->classFinder->getMap('Jobs')),
|
||||
$this->metadataProvider->getScheduledJobNameList()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
asort($list);
|
||||
|
||||
return $result . implode("\n", $list) . "\n";
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,7 +31,7 @@ namespace Espo\Classes\AppParams;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl,
|
||||
Select\SelectManagerFactory,
|
||||
Select\SelectBuilderFactory,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
@@ -40,18 +40,23 @@ use Espo\Core\{
|
||||
*/
|
||||
class TemplateEntityTypeList
|
||||
{
|
||||
protected $acl;
|
||||
protected $selectManagerFactory;
|
||||
protected $entityManager;
|
||||
private $acl;
|
||||
|
||||
public function __construct(Acl $acl, SelectManagerFactory $selectManagerFactory, EntityManager $entityManager)
|
||||
private $selectBuilderFactory;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Acl $acl, SelectBuilderFactory $selectBuilderFactory, EntityManager $entityManager)
|
||||
{
|
||||
$this->acl = $acl;
|
||||
$this->selectManagerFactory = $selectManagerFactory;
|
||||
$this->selectBuilderFactory = $selectBuilderFactory;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function get()
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
if (!$this->acl->checkScope('Template')) {
|
||||
return [];
|
||||
@@ -59,17 +64,21 @@ class TemplateEntityTypeList
|
||||
|
||||
$list = [];
|
||||
|
||||
$selectManager = $this->selectManagerFactory->create('Template');
|
||||
|
||||
$selectParams = $selectManager->getEmptySelectParams();
|
||||
$selectManager->applyAccess($selectParams);
|
||||
|
||||
$templateList = $this->entityManager->getRepository('Template')
|
||||
$query = $this->selectBuilderFactory
|
||||
->create()
|
||||
->from('Template')
|
||||
->withAccessControlFilter()
|
||||
->buildQueryBuilder()
|
||||
->select(['entityType'])
|
||||
->groupBy(['entityType'])
|
||||
->find($selectParams);
|
||||
->group(['entityType'])
|
||||
->build();
|
||||
|
||||
foreach ($templateList as $template) {
|
||||
$templateCollection = $this->entityManager
|
||||
->getRDBRepository('Template')
|
||||
->clone($query)
|
||||
->find();
|
||||
|
||||
foreach ($templateCollection as $template) {
|
||||
$list[] = $template->get('entityType');
|
||||
}
|
||||
|
||||
|
||||
316
application/Espo/Classes/AssignmentNotificators/Email.php
Normal file
316
application/Espo/Classes/AssignmentNotificators/Email.php
Normal file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\AssignmentNotificators;
|
||||
|
||||
use Espo\Services\Email as EmailService;
|
||||
use Espo\Services\Stream as StreamService;
|
||||
|
||||
use Espo\Core\Notification\AssignmentNotificator;
|
||||
use Espo\Core\Notification\AssignmentNotificator\Params;
|
||||
use Espo\Core\Notification\UserEnabledChecker;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\AclManager;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\Entities\Notification;
|
||||
use Espo\Entities\Email as EmailEntity;
|
||||
|
||||
use Espo\Repositories\Email as EmailRepository;
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
class Email implements AssignmentNotificator
|
||||
{
|
||||
private const DAYS_THRESHOLD = 2;
|
||||
|
||||
private ?StreamService $streamService = null;
|
||||
|
||||
private $user;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private $injectableFactory;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
private $userChecker;
|
||||
|
||||
public function __construct(
|
||||
User $user,
|
||||
EntityManager $entityManager,
|
||||
UserEnabledChecker $userChecker,
|
||||
InjectableFactory $injectableFactory,
|
||||
AclManager $aclManager
|
||||
) {
|
||||
$this->user = $user;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->userChecker = $userChecker;
|
||||
$this->injectableFactory = $injectableFactory;
|
||||
$this->aclManager = $aclManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var EmailEntity $entity */
|
||||
|
||||
if (
|
||||
!in_array(
|
||||
$entity->get('status'),
|
||||
[
|
||||
EmailEntity::STATUS_ARCHIVED,
|
||||
EmailEntity::STATUS_SENT,
|
||||
EmailEntity::STATUS_BEING_IMPORTED,
|
||||
]
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($params->getOption('isJustSent')) {
|
||||
$previousUserIdList = [];
|
||||
}
|
||||
else {
|
||||
$previousUserIdList = $entity->getFetched('usersIds');
|
||||
|
||||
if (!is_array($previousUserIdList)) {
|
||||
$previousUserIdList = [];
|
||||
}
|
||||
}
|
||||
|
||||
$dateSent = $entity->get('dateSent');
|
||||
|
||||
if (!$dateSent) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($dateSent);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($dt->diff(new DateTime())->days > self::DAYS_THRESHOLD) {
|
||||
return;
|
||||
}
|
||||
|
||||
$emailUserIdList = $entity->get('usersIds');
|
||||
|
||||
if (is_null($emailUserIdList) || !is_array($emailUserIdList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$userIdList = [];
|
||||
|
||||
foreach ($emailUserIdList as $userId) {
|
||||
if (
|
||||
!in_array($userId, $userIdList) &&
|
||||
!in_array($userId, $previousUserIdList) &&
|
||||
$userId !== $this->user->getId()
|
||||
) {
|
||||
$userIdList[] = $userId;
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'emailId' => $entity->getId(),
|
||||
'emailName' => $entity->get('name'),
|
||||
];
|
||||
|
||||
/** @var EmailRepository $emailRepository */
|
||||
$emailRepository = $this->entityManager->getRepository('Email');
|
||||
/** @var EmailAddressRepository $emailAddressRepository */
|
||||
$emailAddressRepository = $this->entityManager->getRepository('EmailAddress');
|
||||
|
||||
if (!$entity->has('from')) {
|
||||
$emailRepository->loadFromField($entity);
|
||||
}
|
||||
|
||||
if (!$entity->has('to')) {
|
||||
$emailRepository->loadToField($entity);
|
||||
}
|
||||
|
||||
$person = null;
|
||||
|
||||
$from = $entity->get('from');
|
||||
|
||||
if ($from) {
|
||||
$person = $emailAddressRepository->getEntityByAddress($from, null, ['User', 'Contact', 'Lead']);
|
||||
|
||||
if ($person) {
|
||||
$data['personEntityType'] = $person->getEntityType();
|
||||
$data['personEntityName'] = $person->get('name');
|
||||
$data['personEntityId'] = $person->getId();
|
||||
}
|
||||
}
|
||||
|
||||
$userIdFrom = null;
|
||||
|
||||
if ($person && $person->getEntityType() === 'User') {
|
||||
$userIdFrom = $person->getId();
|
||||
}
|
||||
|
||||
if (empty($data['personEntityId'])) {
|
||||
$data['fromString'] = EmailService::parseFromName($entity->get('fromString'));
|
||||
|
||||
if (empty($data['fromString']) && $from) {
|
||||
$data['fromString'] = $from;
|
||||
}
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
|
||||
$parentId = $entity->get('parentId');
|
||||
$parentType = $entity->get('parentType');
|
||||
|
||||
if ($parentType && $parentId) {
|
||||
$parent = $this->entityManager->getEntityById($parentType, $parentId);
|
||||
}
|
||||
|
||||
$account = null;
|
||||
|
||||
$accountId = $entity->get('accountId');
|
||||
|
||||
if ($accountId) {
|
||||
$account = $this->entityManager->getEntityById('Account', $accountId);
|
||||
}
|
||||
|
||||
foreach ($userIdList as $userId) {
|
||||
if (!$userId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($userIdFrom === $userId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($entity->getLinkMultipleColumn('users', 'inTrash', $userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->userChecker->checkAssignment('Email', $userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
$params->getOption('isBeingImported') ||
|
||||
$params->getOption('isJustSent')
|
||||
) {
|
||||
$folderId = $entity->getLinkMultipleColumn('users', 'folderId', $userId);
|
||||
|
||||
if ($folderId) {
|
||||
if (
|
||||
$this->entityManager
|
||||
->getRDBRepository('EmailFolder')
|
||||
->where([
|
||||
'id' => $folderId,
|
||||
'skipNotifications' => true,
|
||||
])
|
||||
->count()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @var User|null $user */
|
||||
$user = $this->entityManager->getEntity('User', $userId);
|
||||
|
||||
if (!$user) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($user->isPortal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->aclManager->checkScope($user, 'Email')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$isArchivedOrBeingImported =
|
||||
$entity->get('status') === EmailEntity::STATUS_ARCHIVED ||
|
||||
$params->getOption('isBeingImported');
|
||||
|
||||
if (
|
||||
$isArchivedOrBeingImported &&
|
||||
$parent &&
|
||||
$this->getStreamService()->checkIsFollowed($parent, $userId)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
$isArchivedOrBeingImported &&
|
||||
$account &&
|
||||
$this->getStreamService()->checkIsFollowed($account, $userId)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$existing = $this->entityManager
|
||||
->getRDBRepository(Notification::ENTITY_TYPE)
|
||||
->where([
|
||||
'type' => Notification::TYPE_EMAIL_RECEIVED,
|
||||
'userId' => $userId,
|
||||
'relatedId' => $entity->getId(),
|
||||
'relatedType' => 'Email',
|
||||
])
|
||||
->select(['id'])
|
||||
->findOne();
|
||||
|
||||
if ($existing) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->entityManager->createEntity(Notification::ENTITY_TYPE, [
|
||||
'type' => Notification::TYPE_EMAIL_RECEIVED,
|
||||
'userId' => $userId,
|
||||
'data' => $data,
|
||||
'relatedId' => $entity->getId(),
|
||||
'relatedType' => 'Email',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function getStreamService(): StreamService
|
||||
{
|
||||
if (empty($this->streamService)) {
|
||||
$this->streamService = $this->injectableFactory->create(StreamService::class);
|
||||
}
|
||||
|
||||
return $this->streamService;
|
||||
}
|
||||
}
|
||||
73
application/Espo/Classes/Cleanup/Exports.php
Normal file
73
application/Espo/Classes/Cleanup/Exports.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Cleanup;
|
||||
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
use Espo\Entities\Export;
|
||||
|
||||
class Exports implements Cleanup
|
||||
{
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private string $cleanupPeriod = '2 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupExportsPeriod', $this->cleanupPeriod);
|
||||
|
||||
$before = DateTime::createNow()
|
||||
->modify($period)
|
||||
->getString();
|
||||
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from(Export::ENTITY_TYPE)
|
||||
->where([
|
||||
'createdAt<' => $before,
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($delete);
|
||||
}
|
||||
}
|
||||
71
application/Espo/Classes/Cleanup/MassActions.php
Normal file
71
application/Espo/Classes/Cleanup/MassActions.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Cleanup;
|
||||
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
class MassActions implements Cleanup
|
||||
{
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private string $cleanupPeriod = '14 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupMassActionsPeriod', $this->cleanupPeriod);
|
||||
|
||||
$before = DateTime::createNow()
|
||||
->modify($period)
|
||||
->getString();
|
||||
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('MassAction')
|
||||
->where([
|
||||
'createdAt<' => $before,
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($delete);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,47 +27,47 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Authentication\TwoFactor\User;
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Entities\UserData;
|
||||
use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils;
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
use StdClass;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class Totp implements CodeVerify
|
||||
use Espo\Entities\PasswordChangeRequest;
|
||||
|
||||
class PasswordChangeRequests implements Cleanup
|
||||
{
|
||||
protected $entityManager;
|
||||
protected $totp;
|
||||
private Config $config;
|
||||
|
||||
public function __construct(TotpUtils $totp, Config $config)
|
||||
private EntityManager $entityManager;
|
||||
|
||||
private string $cleanupPeriod = '30 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->totp = $totp;
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function generateData(UserData $userData, StdClass $data, string $userName) : StdClass
|
||||
public function process(): void
|
||||
{
|
||||
$secret = $this->totp->createSecret();
|
||||
$period = '-' . $this->config->get('cleanupPasswordChangeRequestsPeriod', $this->cleanupPeriod);
|
||||
|
||||
$label = rawurlencode($this->config->get('applicationName')) . ':' . rawurlencode($userName);
|
||||
$before = DateTime::createNow()
|
||||
->modify($period)
|
||||
->getString();
|
||||
|
||||
return (object) [
|
||||
'auth2FATotpSecret' => $secret,
|
||||
'label' => $label,
|
||||
];
|
||||
}
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from(PasswordChangeRequest::ENTITY_TYPE)
|
||||
->where([
|
||||
'createdAt<' => $before,
|
||||
])
|
||||
->build();
|
||||
|
||||
public function verify(UserData $userData, string $code) : bool
|
||||
{
|
||||
if (!$code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$code = str_replace(' ', '', trim($code));
|
||||
|
||||
$secret = $userData->get('auth2FATotpSecret');
|
||||
|
||||
return $this->totp->verifyCode($secret, $code);
|
||||
$this->entityManager->getQueryExecutor()->execute($delete);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,17 +29,19 @@
|
||||
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class Reminders
|
||||
class Reminders implements Cleanup
|
||||
{
|
||||
protected $config;
|
||||
protected $entityManager;
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private string $cleanupRemindersPeriod = '15 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
@@ -47,9 +49,7 @@ class Reminders
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
protected $cleanupRemindersPeriod = '15 days';
|
||||
|
||||
public function process()
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupRemindersPeriod', $this->cleanupRemindersPeriod);
|
||||
|
||||
@@ -57,7 +57,8 @@ class Reminders
|
||||
|
||||
$dt->modify($period);
|
||||
|
||||
$delete = $this->entityManager->getQueryBuilder()
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('Reminder')
|
||||
->where([
|
||||
|
||||
77
application/Espo/Classes/Cleanup/TwoFactorCodes.php
Normal file
77
application/Espo/Classes/Cleanup/TwoFactorCodes.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\Cleanup;
|
||||
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\DateTime as DateTimeUtil;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Entities\TwoFactorCode;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class TwoFactorCodes implements Cleanup
|
||||
{
|
||||
private const PERIOD = '5 days';
|
||||
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupTwoFactorCodesPeriod', self::PERIOD);
|
||||
|
||||
$from = (new DateTime())
|
||||
->modify($period)
|
||||
->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
|
||||
|
||||
$query = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from(TwoFactorCode::ENTITY_TYPE)
|
||||
->where([
|
||||
'createdAt<' => $from,
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager
|
||||
->getQueryExecutor()
|
||||
->execute($query);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,19 +29,19 @@
|
||||
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class WebhookQueue
|
||||
class WebhookQueue implements Cleanup
|
||||
{
|
||||
protected $cleanupWebhookQueuePeriod = '10 days';
|
||||
private string $cleanupWebhookQueuePeriod = '10 days';
|
||||
|
||||
protected $config;
|
||||
protected $entityManager;
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ class WebhookQueue
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process()
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupWebhookQueuePeriod', $this->cleanupWebhookQueuePeriod);
|
||||
|
||||
@@ -58,7 +58,8 @@ class WebhookQueue
|
||||
$datetime->modify($period);
|
||||
$from = $datetime->format('Y-m-d H:i:s');
|
||||
|
||||
$query = $this->entityManager->getQueryBuilder()
|
||||
$query1 = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('WebhookQueueItem')
|
||||
->where([
|
||||
@@ -70,9 +71,10 @@ class WebhookQueue
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($query);
|
||||
$this->entityManager->getQueryExecutor()->execute($query1);
|
||||
|
||||
$query = $this->entityManager->getQueryBuilder()
|
||||
$query2 = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('WebhookEventQueueItem')
|
||||
->where([
|
||||
@@ -84,6 +86,6 @@ class WebhookQueue
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($query);
|
||||
$this->entityManager->getQueryExecutor()->execute($query2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,110 +29,109 @@
|
||||
|
||||
namespace Espo\Classes\ConsoleCommands;
|
||||
|
||||
use Espo\Tools\Import\Service;
|
||||
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
|
||||
use Espo\Core\{
|
||||
ServiceFactory,
|
||||
Console\Commands\Command,
|
||||
Console\Command,
|
||||
Console\Command\Params,
|
||||
Console\IO,
|
||||
};
|
||||
|
||||
use Throwable;
|
||||
|
||||
class Import implements Command
|
||||
{
|
||||
protected $serviceFactory;
|
||||
private Service $service;
|
||||
|
||||
public function __construct(ServiceFactory $serviceFactory)
|
||||
private FileManager $fileManager;
|
||||
|
||||
public function __construct(Service $service, FileManager $fileManager)
|
||||
{
|
||||
$this->serviceFactory = $serviceFactory;
|
||||
$this->service = $service;
|
||||
$this->fileManager = $fileManager;
|
||||
}
|
||||
|
||||
public function run(array $options, array $flagList)
|
||||
public function run(Params $params, IO $io) : void
|
||||
{
|
||||
$id = $options['id'] ?? null;
|
||||
$filePath = $options['file'] ?? null;
|
||||
$paramsId = $options['paramsId'] ?? null;
|
||||
$id = $params->getOption('id');
|
||||
$filePath = $params->getOption('file');
|
||||
$paramsId = $params->getOption('paramsId');
|
||||
|
||||
$service = $this->serviceFactory->create('Import');
|
||||
|
||||
$forceResume = in_array('resume', $flagList);
|
||||
$revert = in_array('revert', $flagList);
|
||||
$forceResume = $params->hasFlag('resume');
|
||||
$revert = $params->hasFlag('revert');
|
||||
|
||||
if (!$id && $filePath) {
|
||||
if (!$paramsId) {
|
||||
$this->out("You need to specify --params-id option.\n");
|
||||
$io->writeLine("You need to specify --params-id option.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$this->out("File not found.\n");
|
||||
if (!$this->fileManager->isFile($filePath)) {
|
||||
$io->writeLine("File not found.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = file_get_contents($filePath);
|
||||
$contents = $this->fileManager->getContents($filePath);
|
||||
|
||||
try {
|
||||
$result = $service->importFileWithParamsId($contents, $paramsId);
|
||||
$result = $this->service->importContentsWithParamsId($contents, $paramsId);
|
||||
|
||||
$resultId = $result->id;
|
||||
$countCreated = $result->countCreated;
|
||||
$countUpdated = $result->countUpdated;
|
||||
$resultId = $result->getId();
|
||||
$countCreated = $result->getCountCreated();
|
||||
$countUpdated = $result->getCountUpdated();
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: ".$e->getMessage()."\n");
|
||||
$io->writeLine("Error occurred: ". $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Finished. Import ID: {$resultId}. Created: {$countCreated}. Updated: {$countUpdated}.\n");
|
||||
$io->writeLine("Finished. Import ID: {$resultId}. Created: {$countCreated}. Updated: {$countUpdated}.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id && $revert) {
|
||||
$this->out("Reverting import...\n");
|
||||
$io->writeLine("Reverting import...");
|
||||
|
||||
try {
|
||||
$service->revert($id);
|
||||
$this->service->revert($id);
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: " . $e->getMessage() . "\n");
|
||||
$io->writeLine("Error occurred: " . $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Finished.\n");
|
||||
$io->writeLine("Finished.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$this->out("Running import, this may take a while...\n");
|
||||
$io->writeLine("Running import, this may take a while...");
|
||||
|
||||
try {
|
||||
$result = $service->importById($id, true, $forceResume);
|
||||
$result = $this->service->importById($id, true, $forceResume);
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: " . $e->getMessage() . "\n");
|
||||
$io->writeLine("Error occurred: " . $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$countCreated = $result->countCreated;
|
||||
$countUpdated = $result->countUpdated;
|
||||
$countCreated = $result->getCountCreated();
|
||||
$countUpdated = $result->getCountUpdated();
|
||||
|
||||
$this->out("Finished. Created: {$countCreated}. Updated: {$countUpdated}.\n");
|
||||
$io->writeLine("Finished. Created: {$countCreated}. Updated: {$countUpdated}.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Not enough params passed.\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected function out($string)
|
||||
{
|
||||
fwrite(\STDOUT, $string);
|
||||
$io->writeLine("Not enough params passed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,32 +33,32 @@ use Espo\Core\Utils\Metadata;
|
||||
|
||||
class DefaultSidePanelType
|
||||
{
|
||||
protected $metadata;
|
||||
private $metadata;
|
||||
|
||||
public function __construct(Metadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function get(string $scope) : array
|
||||
/**
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function get(string $scope): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
if (
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUser', 'type']) === 'link'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUser', 'type']) === 'link' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'assignedUser', 'entity']) === 'User'
|
||||
||
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUsers', 'type']) === 'linkMultiple'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUsers', 'type']) === 'linkMultiple' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'assignedUsers', 'entity']) === 'User'
|
||||
) {
|
||||
$list[] = (object) ['name' => ':assignedUser'];
|
||||
}
|
||||
|
||||
if (
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'teams', 'type']) === 'linkMultiple'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'teams', 'type']) === 'linkMultiple' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'teams', 'entity']) === 'Team'
|
||||
) {
|
||||
$list[] = (object) ['name' => 'teams'];
|
||||
|
||||
114
application/Espo/Classes/DuplicateWhereBuilders/Company.php
Normal file
114
application/Espo/Classes/DuplicateWhereBuilders/Company.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\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,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements WhereBuilder<CoreEntity>
|
||||
*/
|
||||
class Company implements WhereBuilder
|
||||
{
|
||||
public function build(Entity $entity): ?WhereItem
|
||||
{
|
||||
assert($entity instanceof CoreEntity);
|
||||
|
||||
$orBuilder = OrGroup::createBuilder();
|
||||
|
||||
$toCheck = false;
|
||||
|
||||
if ($entity->get('name')) {
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Cond::column('name'),
|
||||
$entity->get('name')
|
||||
),
|
||||
);
|
||||
|
||||
$toCheck = true;
|
||||
}
|
||||
|
||||
if (
|
||||
($entity->get('emailAddress') || $entity->get('emailAddressData')) &&
|
||||
(
|
||||
$entity->isNew() ||
|
||||
$entity->isAttributeChanged('emailAddress') ||
|
||||
$entity->isAttributeChanged('emailAddressData')
|
||||
)
|
||||
) {
|
||||
foreach ($this->getEmailAddressList($entity) as $emailAddress) {
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Cond::column('emailAddress'),
|
||||
$emailAddress
|
||||
)
|
||||
);
|
||||
|
||||
$toCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $orBuilder->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function getEmailAddressList(CoreEntity $entity): array
|
||||
{
|
||||
if ($entity->get('emailAddressData')) {
|
||||
/** @var EmailAddressGroup $eaGroup */
|
||||
$eaGroup = $entity->getValueObject('emailAddress');
|
||||
|
||||
return $eaGroup->getAddressList();
|
||||
}
|
||||
|
||||
if ($entity->get('emailAddress')) {
|
||||
return [
|
||||
$entity->get('emailAddress')
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
123
application/Espo/Classes/DuplicateWhereBuilders/Person.php
Normal file
123
application/Espo/Classes/DuplicateWhereBuilders/Person.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\ORM\Entity as CoreEntity;
|
||||
|
||||
use Espo\Core\{
|
||||
Duplicate\WhereBuilder,
|
||||
Field\EmailAddressGroup,
|
||||
};
|
||||
|
||||
use Espo\ORM\{
|
||||
Query\Part\Condition as Cond,
|
||||
Query\Part\WhereItem,
|
||||
Query\Part\Where\OrGroup,
|
||||
Entity,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements WhereBuilder<CoreEntity>
|
||||
*/
|
||||
class Person implements WhereBuilder
|
||||
{
|
||||
public function build(Entity $entity): ?WhereItem
|
||||
{
|
||||
assert($entity instanceof CoreEntity);
|
||||
|
||||
$orBuilder = OrGroup::createBuilder();
|
||||
|
||||
$toCheck = false;
|
||||
|
||||
if ($entity->get('firstName') || $entity->get('lastName')) {
|
||||
$orBuilder->add(
|
||||
Cond::and(
|
||||
Cond::equal(
|
||||
Cond::column('firstName'),
|
||||
$entity->get('firstName')
|
||||
),
|
||||
Cond::equal(
|
||||
Cond::column('lastName'),
|
||||
$entity->get('lastName')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$toCheck = true;
|
||||
}
|
||||
|
||||
if (
|
||||
($entity->get('emailAddress') || $entity->get('emailAddressData')) &&
|
||||
(
|
||||
$entity->isNew() ||
|
||||
$entity->isAttributeChanged('emailAddress') ||
|
||||
$entity->isAttributeChanged('emailAddressData')
|
||||
)
|
||||
) {
|
||||
foreach ($this->getEmailAddressList($entity) as $emailAddress) {
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Cond::column('emailAddress'),
|
||||
$emailAddress
|
||||
)
|
||||
);
|
||||
|
||||
$toCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$toCheck) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $orBuilder->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function getEmailAddressList(CoreEntity $entity): array
|
||||
{
|
||||
if ($entity->get('emailAddressData')) {
|
||||
/** @var EmailAddressGroup $eaGroup */
|
||||
$eaGroup = $entity->getValueObject('emailAddress');
|
||||
|
||||
return $eaGroup->getAddressList();
|
||||
}
|
||||
|
||||
if ($entity->get('emailAddress')) {
|
||||
return [
|
||||
$entity->get('emailAddress')
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldDuplicators;
|
||||
|
||||
use Espo\Core\Record\Duplicator\FieldDuplicator;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Repositories\Attachment as AttachmentRepository;
|
||||
use Espo\Entities\Attachment;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class AttachmentMultiple implements FieldDuplicator
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function duplicate(Entity $entity, string $field): stdClass
|
||||
{
|
||||
$valueMap = (object) [];
|
||||
|
||||
/** @var \Espo\ORM\Collection<Attachment> $attachmentList */
|
||||
$attachmentList = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, $field)
|
||||
->find();
|
||||
|
||||
if (is_countable($attachmentList) && !count($attachmentList)) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
$idList = [];
|
||||
$nameHash = (object) [];
|
||||
$typeHash = (object) [];
|
||||
|
||||
/** @var AttachmentRepository $attachmentRepository */
|
||||
$attachmentRepository = $this->entityManager->getRepository(Attachment::ENTITY_TYPE);
|
||||
|
||||
foreach ($attachmentList as $attachment) {
|
||||
$copiedAttachment = $attachmentRepository->getCopiedAttachment($attachment);
|
||||
|
||||
$copiedAttachment->set('field', $field);
|
||||
|
||||
$this->entityManager->saveEntity($copiedAttachment);
|
||||
|
||||
$idList[] = $copiedAttachment->getId();
|
||||
|
||||
$nameHash->{$copiedAttachment->getId()} = $copiedAttachment->getName();
|
||||
$typeHash->{$copiedAttachment->getId()} = $copiedAttachment->getType();
|
||||
}
|
||||
|
||||
$valueMap->{$field . 'Ids'} = $idList;
|
||||
$valueMap->{$field . 'Names'} = $nameHash;
|
||||
$valueMap->{$field . 'Types'} = $typeHash;
|
||||
|
||||
return $valueMap;
|
||||
}
|
||||
}
|
||||
75
application/Espo/Classes/FieldDuplicators/File.php
Normal file
75
application/Espo/Classes/FieldDuplicators/File.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldDuplicators;
|
||||
|
||||
use Espo\Core\Record\Duplicator\FieldDuplicator;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Repositories\Attachment as AttachmentRepository;
|
||||
use Espo\Entities\Attachment;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class File implements FieldDuplicator
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function duplicate(Entity $entity, string $field): stdClass
|
||||
{
|
||||
$valueMap = (object) [];
|
||||
|
||||
/** @var Attachment|null $attachment */
|
||||
$attachment = $this->entityManager
|
||||
->getRDBRepository($entity->getEntityType())
|
||||
->getRelation($entity, $field)
|
||||
->findOne();
|
||||
|
||||
if (!$attachment) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
/** @var AttachmentRepository $attachmentRepository */
|
||||
$attachmentRepository = $this->entityManager->getRepository(Attachment::ENTITY_TYPE);
|
||||
|
||||
$copiedAttachment = $attachmentRepository->getCopiedAttachment($attachment);
|
||||
|
||||
$idAttribute = $field . 'Id';
|
||||
|
||||
$valueMap->$idAttribute = $copiedAttachment->getId();
|
||||
|
||||
return $valueMap;
|
||||
}
|
||||
}
|
||||
82
application/Espo/Classes/FieldDuplicators/LinkMultiple.php
Normal file
82
application/Espo/Classes/FieldDuplicators/LinkMultiple.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldDuplicators;
|
||||
|
||||
use Espo\Core\Record\Duplicator\FieldDuplicator;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class LinkMultiple implements FieldDuplicator
|
||||
{
|
||||
private EntityManager $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function duplicate(Entity $entity, string $field): stdClass
|
||||
{
|
||||
$valueMap = (object) [];
|
||||
|
||||
$entityDefs = $this->entityManager
|
||||
->getDefs()
|
||||
->getEntity($entity->getEntityType());
|
||||
|
||||
if (!$entity->hasRelation($field)) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
$relationDefs = $entityDefs->getRelation($field);
|
||||
|
||||
if (
|
||||
!$relationDefs->hasForeignEntityType() ||
|
||||
!$relationDefs->hasForeignRelationName()
|
||||
) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
$foreignRelationType = $this->entityManager
|
||||
->getDefs()
|
||||
->getEntity($relationDefs->getForeignEntityType())
|
||||
->getRelation($relationDefs->getForeignRelationName())
|
||||
->getType();
|
||||
|
||||
if ($foreignRelationType !== Entity::MANY_MANY) {
|
||||
$valueMap->{$field . 'Ids'} = [];
|
||||
$valueMap->{$field . 'Names'} = (object) [];
|
||||
$valueMap->{$field . 'Columns'} = (object) [];
|
||||
}
|
||||
|
||||
return $valueMap;
|
||||
}
|
||||
}
|
||||
117
application/Espo/Classes/FieldDuplicators/Wysiwyg.php
Normal file
117
application/Espo/Classes/FieldDuplicators/Wysiwyg.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldDuplicators;
|
||||
|
||||
use Espo\Core\Record\Duplicator\FieldDuplicator;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Repositories\Attachment as AttachmentRepository;
|
||||
use Espo\Entities\Attachment;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class Wysiwyg implements FieldDuplicator
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function duplicate(Entity $entity, string $field): stdClass
|
||||
{
|
||||
$valueMap = (object) [];
|
||||
|
||||
$contents = $entity->get($field);
|
||||
|
||||
if (!$contents) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
|
||||
$matchResult = preg_match_all("/\?entryPoint=attachment&id=([^&=\"']+)/", $contents, $matches);
|
||||
|
||||
if (
|
||||
!$matchResult ||
|
||||
empty($matches[1]) ||
|
||||
!is_array($matches[1])
|
||||
) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
$attachmentIdList = $matches[1];
|
||||
|
||||
/** @var Attachment[] $attachmentList */
|
||||
$attachmentList = [];
|
||||
|
||||
foreach ($attachmentIdList as $id) {
|
||||
/** @var Attachment|null $attachment */
|
||||
$attachment = $this->entityManager->getEntity(Attachment::ENTITY_TYPE, $id);
|
||||
|
||||
if (!$attachment) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachmentList[] = $attachment;
|
||||
}
|
||||
|
||||
if (!count($attachmentList)) {
|
||||
return $valueMap;
|
||||
}
|
||||
|
||||
/** @var AttachmentRepository $attachmentRepository */
|
||||
$attachmentRepository = $this->entityManager->getRepository(Attachment::ENTITY_TYPE);
|
||||
|
||||
foreach ($attachmentList as $attachment) {
|
||||
$copiedAttachment = $attachmentRepository->getCopiedAttachment($attachment);
|
||||
|
||||
$copiedAttachment->set([
|
||||
'relatedId' => null,
|
||||
'relatedType' => $entity->getEntityType(),
|
||||
'field' => $field,
|
||||
]);
|
||||
|
||||
$this->entityManager->saveEntity($copiedAttachment);
|
||||
|
||||
$contents = str_replace(
|
||||
'?entryPoint=attachment&id=' . $attachment->getId(),
|
||||
'?entryPoint=attachment&id=' . $copiedAttachment->getId(),
|
||||
$contents
|
||||
);
|
||||
}
|
||||
|
||||
$valueMap->$field = $contents;
|
||||
|
||||
return $valueMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Repositories\Email as EmailRepository;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class AddressDataLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var EmailRepository $repository */
|
||||
$repository = $this->entityManager->getRepository('Email');
|
||||
|
||||
$repository->loadFromField($entity);
|
||||
$repository->loadToField($entity);
|
||||
$repository->loadCcField($entity);
|
||||
$repository->loadBccField($entity);
|
||||
$repository->loadReplyToField($entity);
|
||||
$repository->loadNameHash($entity);
|
||||
}
|
||||
}
|
||||
212
application/Espo/Classes/FieldProcessing/Email/IcsDataLoader.php
Normal file
212
application/Espo/Classes/FieldProcessing/Email/IcsDataLoader.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
use Espo\Entities\EmailAddress;
|
||||
use Espo\Entities\Email;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
Mail\Event\Event as EspoEvent,
|
||||
Mail\Event\EventFactory,
|
||||
Utils\Log,
|
||||
};
|
||||
|
||||
use ICal\ICal;
|
||||
use ICal\Event;
|
||||
|
||||
use Throwable;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class IcsDataLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $log;
|
||||
|
||||
/**
|
||||
* @var array<string,string>
|
||||
*/
|
||||
private $entityTypeLinkMap = [
|
||||
'User' => 'users',
|
||||
'Contact' => 'contacts',
|
||||
'Lead' => 'leads',
|
||||
];
|
||||
|
||||
public function __construct(EntityManager $entityManager, Log $log)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$icsContents = $entity->get('icsContents');
|
||||
|
||||
if ($icsContents === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ical = new ICal();
|
||||
|
||||
$ical->initString($icsContents);
|
||||
|
||||
/* @var $event Event */
|
||||
$event = $ical->events()[0] ?? null;
|
||||
|
||||
if ($event === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->status === 'CANCELLED') {
|
||||
return;
|
||||
}
|
||||
|
||||
$espoEvent = EventFactory::createFromU01jmg3Ical($ical);
|
||||
|
||||
$valueMap = (object) [
|
||||
'sourceEmailId' => $entity->getId(),
|
||||
];
|
||||
|
||||
try {
|
||||
$valueMap->name = $espoEvent->getName();
|
||||
$valueMap->description = $espoEvent->getDescription();
|
||||
$valueMap->dateStart = $espoEvent->getDateStart();
|
||||
$valueMap->dateEnd = $espoEvent->getDateEnd();
|
||||
$valueMap->location = $espoEvent->getLocation();
|
||||
$valueMap->isAllDay = $espoEvent->isAllDay();
|
||||
|
||||
if ($espoEvent->isAllDay()) {
|
||||
$valueMap->dateStartDate = $espoEvent->getDateStart();
|
||||
$valueMap->dateEndDate = $espoEvent->getDateEnd();
|
||||
}
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->log->warning("Error while converting ICS event '" . $entity->getId() . "': " . $e->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var EmailAddressRepository $emailAddressRepository */
|
||||
$emailAddressRepository = $this->entityManager->getRepository(EmailAddress::ENTITY_TYPE);
|
||||
|
||||
$attendeeEmailAddressList = $espoEvent->getAttendeeEmailAddressList();
|
||||
|
||||
$organizerEmailAddress = $espoEvent->getOrganizerEmailAddress();
|
||||
|
||||
if ($organizerEmailAddress) {
|
||||
$attendeeEmailAddressList[] = $organizerEmailAddress;
|
||||
}
|
||||
|
||||
foreach ($attendeeEmailAddressList as $address) {
|
||||
$personEntity = $emailAddressRepository->getEntityByAddress($address);
|
||||
|
||||
if (!$personEntity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$link = $this->entityTypeLinkMap[$personEntity->getEntityType()] ?? null;
|
||||
|
||||
if (!$link) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$idsAttribute = $link . 'Ids';
|
||||
$namesAttribute = $link . 'Names';
|
||||
|
||||
$idList = $valueMap->$idsAttribute ?? [];
|
||||
$nameMap = $valueMap->$namesAttribute ?? (object) [];
|
||||
|
||||
$idList[] = $personEntity->getId();
|
||||
$nameMap->{$personEntity->getId()} = $personEntity->get('name');
|
||||
|
||||
$valueMap->$idsAttribute = $idList;
|
||||
$valueMap->$namesAttribute = $nameMap;
|
||||
}
|
||||
|
||||
$eventData = (object) [
|
||||
'valueMap' => $valueMap,
|
||||
'uid' => $espoEvent->getUid(),
|
||||
'createdEvent' => null,
|
||||
];
|
||||
|
||||
$this->loadCreatedEvent($entity, $espoEvent, $eventData);
|
||||
|
||||
$entity->set('icsEventData', $eventData);
|
||||
|
||||
$entity->set('icsEventDateStart', $espoEvent->getDateStart());
|
||||
|
||||
if ($espoEvent->isAllDay()) {
|
||||
$entity->set('icsEventDateStartDate', $espoEvent->getDateStart());
|
||||
}
|
||||
}
|
||||
|
||||
private function loadCreatedEvent(Entity $entity, EspoEvent $espoEvent, stdClass $eventData): void
|
||||
{
|
||||
$emailSameEvent = $this->entityManager
|
||||
->getRDBRepository(Email::ENTITY_TYPE)
|
||||
->where([
|
||||
'icsEventUid' => $espoEvent->getUid(),
|
||||
'id!=' => $entity->getId()
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if (!$emailSameEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!$emailSameEvent->get('createdEventId') ||
|
||||
!$emailSameEvent->get('createdEventType')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$createdEvent = $this->entityManager
|
||||
->getEntity($emailSameEvent->get('createdEventType'), $emailSameEvent->get('createdEventId'));
|
||||
|
||||
if (!$createdEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$eventData->createdEvent = (object) [
|
||||
'id' => $createdEvent->getId(),
|
||||
'entityType' => $emailSameEvent->getEntityType(),
|
||||
'name' => $createdEvent->get('name'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\User;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class StringDataLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var array<string,string>
|
||||
*/
|
||||
private $fromEmailAddressNameCache = [];
|
||||
|
||||
public function __construct(EntityManager $entityManager, User $user)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
$userEmailAdddressIdList = [];
|
||||
|
||||
$emailAddressCollection = $this->entityManager
|
||||
->getRDBRepository('User')
|
||||
->getRelation($this->user, 'emailAddresses')
|
||||
->select(['id'])
|
||||
->find();
|
||||
|
||||
foreach ($emailAddressCollection as $emailAddress) {
|
||||
$userEmailAdddressIdList[] = $emailAddress->getId();
|
||||
}
|
||||
|
||||
if (
|
||||
in_array($entity->get('fromEmailAddressId'), $userEmailAdddressIdList) ||
|
||||
$entity->get('createdById') === $this->user->getId() && $entity->get('status') === Email::STATUS_SENT
|
||||
) {
|
||||
$entity->loadLinkMultipleField('toEmailAddresses');
|
||||
|
||||
$idList = $entity->get('toEmailAddressesIds');
|
||||
$names = $entity->get('toEmailAddressesNames');
|
||||
|
||||
if (empty($idList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($idList as $emailAddressId) {
|
||||
$person = $this->getEmailAddressRepository()->getEntityByAddressId($emailAddressId, null, true);
|
||||
|
||||
$list[] = $person ? $person->get('name') : $names->$emailAddressId;
|
||||
}
|
||||
|
||||
$entity->set('personStringData', 'To: ' . implode(', ', $list));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var ?string */
|
||||
$fromEmailAddressId = $entity->get('fromEmailAddressId');
|
||||
|
||||
if (!$fromEmailAddressId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!array_key_exists($fromEmailAddressId, $this->fromEmailAddressNameCache)) {
|
||||
$person = $this->getEmailAddressRepository()->getEntityByAddressId($fromEmailAddressId, null, true);
|
||||
|
||||
$fromName = $person ? $person->get('name') : null;
|
||||
|
||||
$this->fromEmailAddressNameCache[$fromEmailAddressId] = $fromName;
|
||||
}
|
||||
|
||||
$fromName =
|
||||
$this->fromEmailAddressNameCache[$fromEmailAddressId] ??
|
||||
$entity->get('fromName') ??
|
||||
$entity->get('fromEmailAddressName');
|
||||
|
||||
$entity->set('personStringData', $fromName);
|
||||
}
|
||||
|
||||
private function getEmailAddressRepository(): EmailAddressRepository
|
||||
{
|
||||
/** @var EmailAddressRepository */
|
||||
return $this->entityManager->getRepository('EmailAddress');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class UserColumnsLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $user;
|
||||
|
||||
public function __construct(EntityManager $entityManager, User $user)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$emailUser = $this->entityManager
|
||||
->getRDBRepository('EmailUser')
|
||||
->select(['isRead', 'isImportant', 'inTrash'])
|
||||
->where([
|
||||
'deleted' => false,
|
||||
'userId' => $this->user->getId(),
|
||||
'emailId' => $entity->getId(),
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if (!$emailUser) {
|
||||
$entity->set('isRead', null);
|
||||
$entity->clear('isImportant');
|
||||
$entity->clear('inTrash');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$entity->set([
|
||||
'isRead' => $emailUser->get('isRead'),
|
||||
'isImportant' => $emailUser->get('isImportant'),
|
||||
'inTrash' => $emailUser->get('inTrash'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Import;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Repositories\Import as ImportRepository;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Import>
|
||||
*/
|
||||
class CountsLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var ImportRepository $repository */
|
||||
$repository = $this->entityManager->getRepository('Import');
|
||||
|
||||
$importedCount = $repository->countResultRecords($entity, 'imported');
|
||||
$duplicateCount = $repository->countResultRecords($entity, 'duplicates');
|
||||
$updatedCount = $repository->countResultRecords($entity, 'updated');
|
||||
|
||||
$entity->set([
|
||||
'importedCount' => $importedCount,
|
||||
'duplicateCount' => $duplicateCount,
|
||||
'updatedCount' => $updatedCount,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Note;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
};
|
||||
|
||||
use Espo\Entities\Note;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Note>
|
||||
*/
|
||||
class AttachmentsLoader implements Loader
|
||||
{
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Note $entity */
|
||||
$entity->loadAttachments();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\Portal;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Repositories\Portal as PortalRepository;
|
||||
use Espo\Entities\Portal;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Portal>
|
||||
*/
|
||||
class UrlLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Portal $entity */
|
||||
|
||||
$this->getPortalRepository()->loadUrlField($entity);
|
||||
}
|
||||
|
||||
private function getPortalRepository(): PortalRepository
|
||||
{
|
||||
/** @var PortalRepository */
|
||||
return $this->entityManager->getRepository('Portal');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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\FieldProcessing\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
Acl,
|
||||
Acl\Table,
|
||||
};
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\User>
|
||||
*/
|
||||
class LastAccessLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $acl;
|
||||
|
||||
public function __construct(EntityManager $entityManager, Acl $acl)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->acl = $acl;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$forbiddenFieldList = $this->acl
|
||||
->getScopeForbiddenFieldList($entity->getEntityType(), Table::ACTION_READ);
|
||||
|
||||
if (in_array('lastAccess', $forbiddenFieldList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$authToken = $this->entityManager
|
||||
->getRDBRepository('AuthToken')
|
||||
->select(['id', 'lastAccess'])
|
||||
->where([
|
||||
'userId' => $entity->getId(),
|
||||
])
|
||||
->order('lastAccess', 'DESC')
|
||||
->findOne();
|
||||
|
||||
$lastAccess = null;
|
||||
|
||||
if ($authToken) {
|
||||
$lastAccess = $authToken->get('lastAccess');
|
||||
}
|
||||
|
||||
$dt = null;
|
||||
|
||||
if ($lastAccess) {
|
||||
try {
|
||||
$dt = new DateTime($lastAccess);
|
||||
}
|
||||
catch (Exception $e) {}
|
||||
}
|
||||
|
||||
$where = [
|
||||
'userId' => $entity->getId(),
|
||||
'isDenied' => false,
|
||||
];
|
||||
|
||||
if ($dt) {
|
||||
$where['requestTime>'] = $dt->format('U');
|
||||
}
|
||||
|
||||
$authLogRecord = $this->entityManager
|
||||
->getRDBRepository('AuthLogRecord')
|
||||
->select(['id', 'createdAt'])
|
||||
->where($where)
|
||||
->order('requestTime', true)
|
||||
->findOne();
|
||||
|
||||
if ($authLogRecord) {
|
||||
$lastAccess = $authLogRecord->get('createdAt');
|
||||
}
|
||||
|
||||
$entity->set('lastAccess', $lastAccess);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,22 +31,31 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class ArrayType extends BaseType
|
||||
use StdClass;
|
||||
|
||||
class ArrayType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMaxCount(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkMaxCount(Entity $entity, string $field, int $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (count($list) > $validationValue) return false;
|
||||
|
||||
if (count($list) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkArray(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function rawCheckArray(StdClass $data, string $field): bool
|
||||
{
|
||||
if (isset($data->$field) && $data->$field !== null && !is_array($data->$field)) {
|
||||
return false;
|
||||
@@ -55,12 +64,22 @@ class ArrayType extends BaseType
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return false;
|
||||
if (!$entity->has($field) || $entity->get($field) === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (!is_array($list)) return false;
|
||||
if (count($list)) return true;
|
||||
|
||||
if (!is_array($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,7 +33,7 @@ use Espo\ORM\Entity;
|
||||
|
||||
class CurrencyType extends FloatType
|
||||
{
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return
|
||||
$entity->has($field) && $entity->get($field) !== null &&
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,14 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class DateType extends BaseType
|
||||
class DateType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,15 +33,21 @@ use Espo\ORM\Entity;
|
||||
|
||||
class DatetimeOptionalType extends DatetimeType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($entity->has($field) && $entity->get($field) !== null) return true;
|
||||
if ($entity->has($field . 'Date') && $entity->get($field . 'Date') !== null) return true;
|
||||
if ($entity->has($field) && $entity->get($field) !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->has($field . 'Date') && $entity->get($field . 'Date') !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 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;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailAddresses
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($entity->get('status') === 'Draft') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
private function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,46 +31,61 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailType extends BaseType
|
||||
class EmailType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) return true;
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (!is_array($dataList)) return false;
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (!empty($item->emailAddress)) return true;
|
||||
if (!empty($item->emailAddress)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEmailAddress(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkEmailAddress(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
$address = $entity->get($field);
|
||||
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (is_array($dataList)) {
|
||||
foreach ($dataList as $item) {
|
||||
if (empty($item->emailAddress)) continue;
|
||||
$address = $item->emailAddress;
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (empty($item->emailAddress)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$address = $item->emailAddress;
|
||||
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,14 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EnumType extends BaseType
|
||||
class EnumType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,28 +31,46 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class IntType extends BaseType
|
||||
class IntType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMax(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
/**
|
||||
* @param mixed $validationValue
|
||||
*/
|
||||
public function checkMax(Entity $entity, string $field, $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if ($entity->get($field) > $validationValue) return false;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get($field) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkMin(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
/**
|
||||
* @param mixed $validationValue
|
||||
*/
|
||||
public function checkMin(Entity $entity, string $field, $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if ($entity->get($field) < $validationValue) return false;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get($field) < $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,21 +31,35 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class JsonArrayType extends BaseType
|
||||
{
|
||||
public function checkArray(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return true;
|
||||
use StdClass;
|
||||
|
||||
return is_array($entity->get($field));
|
||||
class JsonArrayType
|
||||
{
|
||||
public function rawCheckArray(StdClass $data, string $field): bool
|
||||
{
|
||||
if (isset($data->$field) && $data->$field !== null && !is_array($data->$field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return false;
|
||||
if (!$entity->has($field) || $entity->get($field) === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (!is_array($list)) return false;
|
||||
if (count($list)) return true;
|
||||
|
||||
if (!is_array($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -30,11 +30,19 @@
|
||||
namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
|
||||
class LinkMultipleType extends BaseType
|
||||
class LinkMultipleType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return count($entity->getLinkMultipleIdList($field)) > 0;
|
||||
if (!$entity instanceof CoreEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var string[] */
|
||||
$idList = $entity->getLinkMultipleIdList($field);
|
||||
|
||||
return count($idList) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,18 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class LinkParentType extends BaseType
|
||||
class LinkParentType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$idAttribute = $field . 'Id';
|
||||
$typeAttribute = $field . 'Type';
|
||||
|
||||
if (!$entity->has($idAttribute) || $entity->get($idAttribute) === '' || $entity->get($idAttribute) === null) {
|
||||
if (
|
||||
!$entity->has($idAttribute) ||
|
||||
$entity->get($idAttribute) === '' ||
|
||||
$entity->get($idAttribute) === null
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,9 +31,9 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class LinkType extends BaseType
|
||||
class LinkType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$idAttribute = $field . 'Id';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,21 +31,41 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PersonNameType extends BaseType
|
||||
use Espo\Core\{
|
||||
Utils\FieldUtil,
|
||||
};
|
||||
|
||||
class PersonNameType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
private $fieldUtil;
|
||||
|
||||
public function __construct(FieldUtil $fieldUtil)
|
||||
{
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
}
|
||||
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$isEmpty = true;
|
||||
foreach ($this->getActualAttributeList($entity, $field) as $attribute) {
|
||||
|
||||
$attributeList = $this->fieldUtil->getActualAttributeList($entity->getEntityType(), $field);
|
||||
|
||||
foreach ($attributeList as $attribute) {
|
||||
if ($attribute === 'salutation' . ucfirst($field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($entity->has($attribute) && $entity->get($attribute) !== '') {
|
||||
$isEmpty = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isEmpty) return false;
|
||||
|
||||
if ($isEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,23 +31,30 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PhoneType extends BaseType
|
||||
class PhoneType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) return true;
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (!is_array($dataList)) return false;
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (!empty($item->phoneNumber)) return true;
|
||||
if (!empty($item->phoneNumber)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,25 +31,27 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class VarcharType extends BaseType
|
||||
class VarcharType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMaxLength(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkMaxLength(Entity $entity, string $field, int $validationValue): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
$value = $entity->get($field);
|
||||
|
||||
if (mb_strlen($value) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user