mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-10 12:47:02 +00:00
Compare commits
2799 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 | ||
|
|
7f57e64292 | ||
|
|
18537b9cdb | ||
|
|
ed5cb715da | ||
|
|
300a0ece75 | ||
|
|
3172ba213e | ||
|
|
32cf86ede5 | ||
|
|
97f320c9a7 | ||
|
|
7c6dd75a23 | ||
|
|
6a59355514 | ||
|
|
91c3413c57 | ||
|
|
717f5f6e2e | ||
|
|
f48efae82d | ||
|
|
5f372ebee3 | ||
|
|
5b27fad3aa | ||
|
|
5685ccbffd | ||
|
|
6149a951bd | ||
|
|
2529205359 | ||
|
|
81b71a7676 | ||
|
|
29c80f7845 | ||
|
|
05372fc4a4 | ||
|
|
50e433aba0 | ||
|
|
ac4797a943 | ||
|
|
3e372f753d | ||
|
|
3c7baa7237 | ||
|
|
3f9d6e48b5 | ||
|
|
79adfe70a4 | ||
|
|
ae8b616fed | ||
|
|
0b8b2db41e | ||
|
|
63183b33f1 | ||
|
|
de09d1dbd2 | ||
|
|
b59e318444 | ||
|
|
51ea8a5e1c | ||
|
|
0a65da2fc4 | ||
|
|
d3c634b89f | ||
|
|
e46be54688 | ||
|
|
e4f8a51df8 | ||
|
|
a51f48f060 | ||
|
|
32df0c1730 | ||
|
|
530c8818b7 | ||
|
|
6c99f73596 | ||
|
|
61acaaa054 | ||
|
|
eca341d7ec | ||
|
|
25b695bc32 | ||
|
|
0f41cb5ad4 | ||
|
|
454ca3b136 | ||
|
|
e3b8b450a4 | ||
|
|
c15c486603 | ||
|
|
40e57e3a54 | ||
|
|
c6554afaae | ||
|
|
0d6b5ce68c | ||
|
|
2830400da5 | ||
|
|
113b05ed05 | ||
|
|
824ce88914 | ||
|
|
aa8edf1ee9 | ||
|
|
f1bf439f7b | ||
|
|
220992fc37 | ||
|
|
a1e243714e | ||
|
|
1c0ed64f67 | ||
|
|
1f1cd1b6d7 | ||
|
|
e81725eb16 | ||
|
|
ee4220e1ce | ||
|
|
a733c6c68d | ||
|
|
d7c7619218 | ||
|
|
77066ba7e5 | ||
|
|
35c5919c44 | ||
|
|
fcdd286965 | ||
|
|
e84fa1d636 | ||
|
|
de52af79c5 | ||
|
|
c555102b5f | ||
|
|
4c05175dbe | ||
|
|
de543fa2db | ||
|
|
bfe9bad905 | ||
|
|
459b6bc6fe | ||
|
|
332211fb13 | ||
|
|
a0f85bd55a | ||
|
|
7273caac36 | ||
|
|
d8383dc38a | ||
|
|
7824ab8dc9 | ||
|
|
7320bf68e5 | ||
|
|
e5d42cf0eb | ||
|
|
d7b9492f15 | ||
|
|
6a7b782309 | ||
|
|
9d080d7dca | ||
|
|
424df8d4fe | ||
|
|
2f4422f719 | ||
|
|
831611af1e | ||
|
|
c302d362a4 | ||
|
|
69d4b1096f | ||
|
|
2514a89286 | ||
|
|
2034055148 | ||
|
|
3a3b1007b9 | ||
|
|
2582dfe3c4 | ||
|
|
295411a5d2 | ||
|
|
09a83b36ff | ||
|
|
32cc59228d | ||
|
|
31b2413953 | ||
|
|
c8eb643818 | ||
|
|
11b251003e | ||
|
|
28bb0e99cb | ||
|
|
5c9c686317 | ||
|
|
098425bdbf | ||
|
|
5189f6b392 | ||
|
|
f487479b1d | ||
|
|
03224cc4f6 | ||
|
|
482754eddb | ||
|
|
7fcf6874e3 | ||
|
|
a3e0eee8d4 | ||
|
|
453589de92 | ||
|
|
b7ffb06f9c | ||
|
|
35a209bcb6 | ||
|
|
c3a2a15608 | ||
|
|
9acdfe5dcf | ||
|
|
9ec8056d89 | ||
|
|
b9c2cc2c4f | ||
|
|
675a2811d4 | ||
|
|
b1df5f533b | ||
|
|
a61cf3f889 | ||
|
|
ace09646c6 | ||
|
|
f42c33d77a | ||
|
|
d2113c4379 | ||
|
|
0d202499bc | ||
|
|
9e60778075 | ||
|
|
be6896f34c | ||
|
|
4e78e4019f | ||
|
|
823d13af34 | ||
|
|
4007870bfb | ||
|
|
5d92f98548 | ||
|
|
e5a3a0637d | ||
|
|
cbbff69003 | ||
|
|
f40240d8cb | ||
|
|
9671599fc9 | ||
|
|
e1be421410 | ||
|
|
068653ad3e | ||
|
|
cd2a2c2639 | ||
|
|
2d37dde8b8 | ||
|
|
42613c79b6 | ||
|
|
f4a80ed856 | ||
|
|
39610bce24 | ||
|
|
124cce55bd | ||
|
|
589aa4ae40 | ||
|
|
41ccba7955 | ||
|
|
ac2613682c | ||
|
|
8a46cfb0da | ||
|
|
9c0643b61f | ||
|
|
4d755d3795 | ||
|
|
9fe61d2342 | ||
|
|
d0273febf9 | ||
|
|
5610ed6e15 | ||
|
|
89ff894917 | ||
|
|
e2b6f0c70f | ||
|
|
654741261b | ||
|
|
1f17d79e2d | ||
|
|
3b0c7f1d5b | ||
|
|
f2831f84df | ||
|
|
d30edee790 | ||
|
|
2635ed69ac | ||
|
|
18e0044373 | ||
|
|
a9759a20c2 | ||
|
|
f5b9673044 | ||
|
|
9756bfbc4d | ||
|
|
1ae125ceb1 | ||
|
|
443d010a59 | ||
|
|
fcdc704cc2 | ||
|
|
0815cc3b5e | ||
|
|
2416cf6ad5 | ||
|
|
9cf03fcbb0 | ||
|
|
43c524533c | ||
|
|
600ae5aed6 | ||
|
|
a9fb352fd9 | ||
|
|
dd2434d4b4 | ||
|
|
3f221878e8 | ||
|
|
876dbb3ab4 | ||
|
|
97e7b1982f | ||
|
|
ddff78756d | ||
|
|
d78df859b1 | ||
|
|
aa09f8789c | ||
|
|
106ffe5df7 | ||
|
|
f8c01808d4 | ||
|
|
9de775e0c9 | ||
|
|
e073c82992 | ||
|
|
90a6c85aff | ||
|
|
aa82f96993 | ||
|
|
867a0225f1 | ||
|
|
ead92aac31 | ||
|
|
97ff03f87e | ||
|
|
ec40acfac1 | ||
|
|
52904999fb | ||
|
|
14d296ea38 | ||
|
|
4ab636ded8 | ||
|
|
f764375e0e | ||
|
|
98b20a3e24 | ||
|
|
7f6843b895 | ||
|
|
74ad947ade | ||
|
|
3dc1a156d4 | ||
|
|
b6a6cf052b | ||
|
|
ae3975e3dd | ||
|
|
79b2beba8f | ||
|
|
e7345f678c | ||
|
|
771f8a8430 | ||
|
|
ddef5312fd | ||
|
|
43a7085f7c | ||
|
|
fd11c1d5bd | ||
|
|
5cf06bce7e | ||
|
|
f5232dc5af | ||
|
|
d0cf57cb66 | ||
|
|
ca17a5453a | ||
|
|
713ecb3be7 | ||
|
|
e43265fe57 | ||
|
|
9642f9ae41 | ||
|
|
5f95859bcd | ||
|
|
6fecf61648 | ||
|
|
85c199d563 | ||
|
|
facb5c747d | ||
|
|
1b517a6eb1 | ||
|
|
99dc6b1623 | ||
|
|
e569b8b9a7 | ||
|
|
f0b0c55d9b | ||
|
|
df179212b1 | ||
|
|
19ccf09c20 | ||
|
|
641382dc66 | ||
|
|
8f89fa4597 | ||
|
|
543eb21a8b | ||
|
|
9fbc62837f | ||
|
|
d194eac5bc | ||
|
|
5ffd03ca85 | ||
|
|
d6dec82610 | ||
|
|
521a166c92 | ||
|
|
2ca97d4e31 | ||
|
|
b30df2f6e2 | ||
|
|
4ab0d765e3 | ||
|
|
58d3929bee | ||
|
|
35eff68f64 | ||
|
|
bb10b0a266 | ||
|
|
9dc050332e | ||
|
|
c65b9d8cc2 | ||
|
|
2d26d1a9d1 | ||
|
|
a2be80501a | ||
|
|
e19462c045 | ||
|
|
8a23bba39a | ||
|
|
105b494710 | ||
|
|
e35ecf96ca | ||
|
|
df16f37912 | ||
|
|
d3dcaa92e5 | ||
|
|
b1e31c9999 | ||
|
|
3a89b16b91 | ||
|
|
06ff48515c | ||
|
|
b870025f88 | ||
|
|
7041a9ca9d | ||
|
|
2f40830630 | ||
|
|
55b7d81922 | ||
|
|
07d63013aa | ||
|
|
70d15cbac5 | ||
|
|
fad183e20a | ||
|
|
ad2e977b7c | ||
|
|
bdf5664672 | ||
|
|
83a44c60c1 | ||
|
|
43b529ea8b | ||
|
|
08fa801878 | ||
|
|
426260de00 | ||
|
|
86ff40e408 | ||
|
|
4272376278 | ||
|
|
3d2857eec2 | ||
|
|
4c0298aed9 | ||
|
|
e9917f4fca | ||
|
|
826ba4c97c | ||
|
|
5ef73d3c08 | ||
|
|
26e1d1d81d | ||
|
|
a76f5498cb | ||
|
|
66075b3d9d | ||
|
|
524773f855 | ||
|
|
2935118dab | ||
|
|
989d431acf | ||
|
|
2d385c163f | ||
|
|
4e1e6bf776 | ||
|
|
0d50bc9563 | ||
|
|
35cefea3a8 | ||
|
|
4fc7700e7e | ||
|
|
3b2c776060 | ||
|
|
103e67ab8e | ||
|
|
72256e7f8b | ||
|
|
8cdbcdcb8c | ||
|
|
218dba2c78 | ||
|
|
68b8230b99 | ||
|
|
9d872c3fd7 | ||
|
|
9f2b2de261 | ||
|
|
8110b7ba4b | ||
|
|
95ed02f0e4 | ||
|
|
87e94bc5a7 | ||
|
|
b757f18d53 |
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
* text=auto
|
||||
*.php text eol=crlf
|
||||
*.js text eol=crlf
|
||||
*.json text eol=crlf
|
||||
*.md text eol=crlf
|
||||
*.less text eol=crlf
|
||||
*.css text eol=crlf
|
||||
*.tpl text eol=crlf
|
||||
*.html text eol=crlf
|
||||
|
||||
*.png binary
|
||||
17
.github/CONTRIBUTING.md
vendored
Normal file
17
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
## Pull Requests
|
||||
|
||||
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
|
||||
|
||||
See [Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
|
||||
|
||||
Branches:
|
||||
|
||||
* *hotfix/** – upcoming maintenance release; fixes should be pushed to this branch;
|
||||
* *master* – develop branch; new features should be pushed to this branch;
|
||||
* *stable* – last stable release.
|
||||
|
||||
## Issues
|
||||
|
||||
When reporting a possible bug please provide detail steps so that we will be able to reproduce the issue. Please try not to use phrases like "very big bug", "huge issue", etc. No need to use exclamation marks as well.
|
||||
|
||||
Note that we don't provide developer help or any kind of support on Github. Please use our [forum](https://forum.espocrm.com) for this.
|
||||
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
|
||||
10
.gitignore
vendored
10
.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/*
|
||||
/install/config.php
|
||||
/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>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
## Pull Requests
|
||||
|
||||
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
|
||||
|
||||
[Code Style Guidelines](https://github.com/espocrm/espocrm/wiki/Code-Style-Guidelines).
|
||||
|
||||
Branches:
|
||||
|
||||
* *hotfix/** – upcoming maintenance release; fixes should be pushed to this branch;
|
||||
* *master* – develop branch; new features should be pushed to this branch;
|
||||
* *stable* – last stable release.
|
||||
|
||||
## Issues
|
||||
|
||||
We don't provide developer help or any kind of support on github. Please use our [forum](https://forum.espocrm.com) for this.
|
||||
536
Gruntfile.js
536
Gruntfile.js
@@ -2,7 +2,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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() {
|
||||
cp.execSync("vendor/bin/phpunit --bootstrap=./vendor/autoload.php ./tests/unit", {stdio: 'inherit'});
|
||||
grunt.registerTask('unit-tests-run', () => {
|
||||
cp.execSync("vendor/bin/phpunit ./tests/unit", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("integration-tests-run", function() {
|
||||
cp.execSync("vendor/bin/phpunit --bootstrap=./vendor/autoload.php ./tests/integration", {stdio: 'inherit'});
|
||||
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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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;
|
||||
}
|
||||
}
|
||||
@@ -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\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;
|
||||
}
|
||||
}
|
||||
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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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,20 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\AclPortal;
|
||||
namespace Espo\Classes\Acl\Webhook;
|
||||
|
||||
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\Webhook>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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 Account extends Acl
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
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('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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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,42 +27,63 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Acl;
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use \Espo\Entities\User;
|
||||
use \Espo\ORM\Entity;
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class MassEmail extends \Espo\Core\Acl\Base
|
||||
class Formatter1 implements AddressFormatter
|
||||
{
|
||||
|
||||
public function checkIsOwner(User $user, Entity $entity)
|
||||
public function format(Address $address): string
|
||||
{
|
||||
if ($entity->has('campaignId')) {
|
||||
$campaignId = $entity->get('campaignId');
|
||||
if (!$campaignId) return;
|
||||
$result = '';
|
||||
|
||||
$campaign = $this->getEntityManager()->getEntity('Campaign', $campaignId);
|
||||
if ($campaign && $this->getAclManager()->getImplementation('Campaign')->checkIsOwner($user, $campaign)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return parent::checkIsOwner($user, $entity);
|
||||
$street = $address->getStreet();
|
||||
$city = $address->getCity();
|
||||
$country = $address->getCountry();
|
||||
$state = $address->getState();
|
||||
$postalCode = $address->getPostalCode();
|
||||
|
||||
if ($street) {
|
||||
$result .= $street;
|
||||
}
|
||||
}
|
||||
|
||||
public function checkInTeam(User $user, Entity $entity)
|
||||
{
|
||||
if ($entity->has('campaignId')) {
|
||||
$campaignId = $entity->get('campaignId');
|
||||
if (!$campaignId) return;
|
||||
|
||||
$campaign = $this->getEntityManager()->getEntity('Campaign', $campaignId);
|
||||
if ($campaign && $this->getAclManager()->getImplementation('Campaign')->checkInTeam($user, $campaign)) {
|
||||
return true;
|
||||
if ($city || $state || $postalCode) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
if ($city) {
|
||||
$result .= $city;
|
||||
}
|
||||
|
||||
if ($state && $city) {
|
||||
$result .= ', ';
|
||||
}
|
||||
|
||||
if ($state) {
|
||||
$result .= $state;
|
||||
}
|
||||
|
||||
if ($postalCode && ($state || $city)) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($postalCode) {
|
||||
$result .= $postalCode;
|
||||
}
|
||||
} else {
|
||||
return parent::checkInTeam($user, $entity);
|
||||
}
|
||||
|
||||
if ($country) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
$result .= $country;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
91
application/Espo/Classes/AddressFormatters/Formatter2.php
Normal file
91
application/Espo/Classes/AddressFormatters/Formatter2.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?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\AddressFormatters;
|
||||
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter2 implements AddressFormatter
|
||||
{
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$street = $address->getStreet();
|
||||
$city = $address->getCity();
|
||||
$country = $address->getCountry();
|
||||
$state = $address->getState();
|
||||
$postalCode = $address->getPostalCode();
|
||||
|
||||
if ($street) {
|
||||
$result .= $street;
|
||||
}
|
||||
|
||||
if ($city || $postalCode) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
if ($postalCode) {
|
||||
$result .= $postalCode;
|
||||
}
|
||||
|
||||
if ($postalCode && $city) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($city) {
|
||||
$result .= $city;
|
||||
}
|
||||
}
|
||||
|
||||
if ($state || $country) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
if ($state) {
|
||||
$result .= $state;
|
||||
}
|
||||
|
||||
if ($state && $country) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($country) {
|
||||
$result .= $country;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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,40 +27,63 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\Acl;
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use \Espo\Entities\User;
|
||||
use \Espo\ORM\Entity;
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class CampaignLogRecord extends \Espo\Core\Acl\Base
|
||||
class Formatter3 implements AddressFormatter
|
||||
{
|
||||
|
||||
public function checkIsOwner(User $user, Entity $entity)
|
||||
public function format(Address $address): string
|
||||
{
|
||||
if ($entity->has('campaignId')) {
|
||||
$campaignId = $entity->get('campaignId');
|
||||
if (!$campaignId) return;
|
||||
$result = '';
|
||||
|
||||
$campaign = $this->getEntityManager()->getEntity('Campaign', $campaignId);
|
||||
if ($campaign && $this->getAclManager()->getImplementation('Campaign')->checkIsOwner($user, $campaign)) {
|
||||
return true;
|
||||
$street = $address->getStreet();
|
||||
$city = $address->getCity();
|
||||
$country = $address->getCountry();
|
||||
$state = $address->getState();
|
||||
$postalCode = $address->getPostalCode();
|
||||
|
||||
if ($country) {
|
||||
$result .= $country;
|
||||
}
|
||||
|
||||
if ($city || $state || $postalCode) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
if ($state) {
|
||||
$result .= $state;
|
||||
}
|
||||
|
||||
if ($state && $postalCode) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($postalCode) {
|
||||
$result .= $postalCode;
|
||||
}
|
||||
|
||||
if ($city && ($state || $postalCode)) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($city) {
|
||||
$result .= $city;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkInTeam(User $user, Entity $entity)
|
||||
{
|
||||
if ($entity->has('campaignId')) {
|
||||
$campaignId = $entity->get('campaignId');
|
||||
if (!$campaignId) return;
|
||||
|
||||
$campaign = $this->getEntityManager()->getEntity('Campaign', $campaignId);
|
||||
if ($campaign && $this->getAclManager()->getImplementation('Campaign')->checkInTeam($user, $campaign)) {
|
||||
return true;
|
||||
if ($street) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
$result .= $street;
|
||||
}
|
||||
return false;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
89
application/Espo/Classes/AddressFormatters/Formatter4.php
Normal file
89
application/Espo/Classes/AddressFormatters/Formatter4.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?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\AddressFormatters;
|
||||
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter4 implements AddressFormatter
|
||||
{
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$street = $address->getStreet();
|
||||
$city = $address->getCity();
|
||||
$country = $address->getCountry();
|
||||
$state = $address->getState();
|
||||
$postalCode = $address->getPostalCode();
|
||||
|
||||
if ($street) {
|
||||
$result .= $street;
|
||||
}
|
||||
|
||||
if ($city) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
$result .= $city;
|
||||
}
|
||||
|
||||
if ($country || $state || $postalCode) {
|
||||
if ($result) {
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
if ($country) {
|
||||
$result .= $country;
|
||||
}
|
||||
|
||||
if ($state && $country) {
|
||||
$result .= ' - ';
|
||||
}
|
||||
|
||||
if ($state) {
|
||||
$result .= $state;
|
||||
}
|
||||
|
||||
if ($postalCode && ($state || $country)) {
|
||||
$result .= ' ';
|
||||
}
|
||||
|
||||
if ($postalCode) {
|
||||
$result .= $postalCode;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
120
application/Espo/Classes/AppInfo/Binding.php
Normal file
120
application/Espo/Classes/AppInfo/Binding.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?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\{
|
||||
Utils\Module,
|
||||
Binding\EspoBindingLoader,
|
||||
Binding\Binding as BindingItem,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Binding
|
||||
{
|
||||
private $module;
|
||||
|
||||
public function __construct(Module $module)
|
||||
{
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$bindingLoader = new EspoBindingLoader($this->module);
|
||||
|
||||
$data = $bindingLoader->load();
|
||||
|
||||
$keyList = $data->getGlobalKeyList();
|
||||
|
||||
$result .= "Global:\n\n";
|
||||
|
||||
foreach ($keyList as $key) {
|
||||
$result .= $this->printItem($key, $data->getGlobal($key));
|
||||
}
|
||||
|
||||
$contextList = $data->getContextList();
|
||||
|
||||
foreach ($contextList as $context) {
|
||||
$result .= "Context: {$context}\n\n";
|
||||
|
||||
$keyList = $data->getContextKeyList($context);
|
||||
|
||||
foreach ($keyList as $key) {
|
||||
$result .= $this->printItem($key, $data->getContext($context, $key));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function printItem(string $key, BindingItem $binding): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$tab = ' ';
|
||||
|
||||
$result .= $tab . "Key: {$key}\n";
|
||||
|
||||
$type = $binding->getType();
|
||||
$value = $binding->getValue();
|
||||
|
||||
$typeString = [
|
||||
BindingItem::IMPLEMENTATION_CLASS_NAME => 'Implementation',
|
||||
BindingItem::CONTAINER_SERVICE => 'Service',
|
||||
BindingItem::VALUE => 'Value',
|
||||
BindingItem::CALLBACK => 'Callback',
|
||||
BindingItem::FACTORY_CLASS_NAME => 'Factory',
|
||||
][$type];
|
||||
|
||||
$result .= $tab . "Type: {$typeString}\n";
|
||||
|
||||
if ($type == BindingItem::IMPLEMENTATION_CLASS_NAME || $type == BindingItem::CONTAINER_SERVICE) {
|
||||
$result .= $tab . "Value: {$value}\n";
|
||||
}
|
||||
|
||||
if ($type == BindingItem::VALUE) {
|
||||
if (is_string($value) || is_int($value) || is_float($value)) {
|
||||
$result .= $tab . "Value: {$value}\n";
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$valueString = $value ? 'true' : 'false';
|
||||
|
||||
$result .= $tab . "Value: {$valueString}\n";
|
||||
}
|
||||
}
|
||||
|
||||
$result .= "\n";
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
110
application/Espo/Classes/AppInfo/Container.php
Normal file
110
application/Espo/Classes/AppInfo/Container.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\AppInfo;
|
||||
|
||||
use Espo\Core\{
|
||||
Container as ContainerService,
|
||||
Utils\Metadata,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Container
|
||||
{
|
||||
private $container;
|
||||
|
||||
private $metadata;
|
||||
|
||||
public function __construct(ContainerService $container, Metadata $metadata)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$nameOnly = $params->hasFlag('nameOnly');
|
||||
|
||||
$result = '';
|
||||
|
||||
$serviceList = [
|
||||
'injectableFactory',
|
||||
'config',
|
||||
'log',
|
||||
'fileManager',
|
||||
'dataManager',
|
||||
'metadata',
|
||||
'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') ?: []);
|
||||
}
|
||||
|
||||
foreach ($fileList as $file) {
|
||||
if (substr($file, -4) === '.php') {
|
||||
$name = lcfirst(substr($file, 0, -4));
|
||||
|
||||
if (!in_array($name, $serviceList) && $this->container->has($name)) {
|
||||
$serviceList[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->metadata->get(['app', 'containerServices']) ?? [] as $name => $data) {
|
||||
if (!in_array($name, $serviceList)) {
|
||||
$serviceList[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
sort($serviceList);
|
||||
|
||||
if ($nameOnly) {
|
||||
foreach ($serviceList as $name) {
|
||||
$result .= $name . "\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($serviceList as $name) {
|
||||
$result .= $name . "\n";
|
||||
|
||||
$obj = $this->container->get($name);
|
||||
$result .= get_class($obj) . "\n";
|
||||
|
||||
$result .= "\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy 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;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user