Compare commits
2492 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 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 | |||
| 6b8f46bf81 | |||
| 1a71f43c54 | |||
| b4d732656f | |||
| 6a335269f4 | |||
| c51f2fa401 | |||
| 69072cf0ca | |||
| b023964aec | |||
| 59321dbd56 | |||
| f1c282451b | |||
| ff0c34c0b8 | |||
| 439598d7ee | |||
| 08fa24b095 | |||
| c836548fc7 | |||
| f109146379 | |||
| af7f4e3bc4 | |||
| ddc299fa08 | |||
| 43df9d25f0 | |||
| 250ac0e8ba | |||
| 29d960878c | |||
| 8e6634ff0f | |||
| 15b5cf9750 | |||
| c001c4b5bd | |||
| aa0db4b665 | |||
| cda62b8a3e | |||
| 9c741da4e8 | |||
| 2dfd43c8ba | |||
| 5536687d90 | |||
| 34c421733e | |||
| b0b29443a5 | |||
| a637dcd28d | |||
| b6b3ec04be | |||
| 6586f51791 | |||
| 92e4e81788 | |||
| aa9ee7e1af | |||
| 2d3f2f4b36 | |||
| 73fe4d68f1 | |||
| d244602818 | |||
| 67d9c6ed4e | |||
| 55f8932495 | |||
| 5d47009e07 | |||
| c46acc1ad4 | |||
| 20051a835b | |||
| 873e33a04f | |||
| e33c5d7cbc | |||
| b729ec1a85 | |||
| 9b18ecf072 | |||
| 88c4ae5721 | |||
| d2b94955d1 | |||
| dbcc00fe1a | |||
| b56ae68854 | |||
| 312ea7d962 | |||
| ceb3b562e6 | |||
| b211009e91 | |||
| 70fa577e10 | |||
| b8f3f53d56 | |||
| d5623dabb6 | |||
| db50687a1e | |||
| 272fd58481 | |||
| ecbde48f63 | |||
| 39827e449b | |||
| 44d0c78077 | |||
| 929b8c2d50 | |||
| b71a64c214 | |||
| 66c5d408c6 | |||
| ab1dbd0d5c | |||
| 6754efc486 | |||
| 1e5d9d314b | |||
| cea6aaf7ff | |||
| c1f019e71c | |||
| c00b511c17 | |||
| 51c6067c17 | |||
| c032e74e58 | |||
| 412d40d041 | |||
| 2cc69a0725 | |||
| 89b3b6da61 | |||
| 77a7fffcb2 | |||
| 30a9c8c90e | |||
| abd52c7a42 | |||
| 9bb164246e | |||
| 87d0e18696 | |||
| e8f5864dd9 | |||
| 51d7b3f413 | |||
| fb3de84aa4 | |||
| 4a2aa91b6d | |||
| a4edac59c6 | |||
| 19af59b301 | |||
| d1b27dfd9d | |||
| 274fb0f380 | |||
| 8e70567688 | |||
| 2bdcf3919e | |||
| 8214f4ba20 | |||
| d0a5fc24b1 | |||
| c8084c670a | |||
| 82a9779b09 | |||
| fdb887e43a | |||
| 7761244eec | |||
| 6580334bdd | |||
| e2f7a22457 | |||
| 494382f5cb | |||
| 7ed15a2dbc | |||
| 3d1725054a | |||
| d6e37f9f13 | |||
| 2c78bef505 | |||
| d60b9706b3 | |||
| d20996d788 | |||
| f1d87da9b6 | |||
| ac8674a8b3 | |||
| c2af7914e3 | |||
| 102db4c937 | |||
| 555cc74312 | |||
| 761319c13d | |||
| 828e867ac9 | |||
| 6a7b4f107e | |||
| c0df364b4f | |||
| ec5f8fc4f5 | |||
| f5e6ed914d | |||
| 2e7bc894f1 | |||
| 18537b9cdb | |||
| ed5cb715da | |||
| 32cf86ede5 | |||
| 97f320c9a7 | |||
| 7c6dd75a23 | |||
| 6a59355514 | |||
| 91c3413c57 | |||
| 717f5f6e2e | |||
| f48efae82d | |||
| 5f372ebee3 | |||
| 5b27fad3aa | |||
| 6149a951bd | |||
| 2529205359 | |||
| 81b71a7676 | |||
| 29c80f7845 | |||
| 05372fc4a4 | |||
| 50e433aba0 | |||
| ac4797a943 | |||
| 3c7baa7237 | |||
| 3f9d6e48b5 | |||
| 79adfe70a4 | |||
| ae8b616fed | |||
| 0b8b2db41e | |||
| 63183b33f1 | |||
| de09d1dbd2 | |||
| b59e318444 | |||
| 0a65da2fc4 | |||
| e46be54688 | |||
| e4f8a51df8 | |||
| a51f48f060 | |||
| 32df0c1730 | |||
| 530c8818b7 | |||
| 6c99f73596 | |||
| 61acaaa054 | |||
| 25b695bc32 | |||
| 0f41cb5ad4 | |||
| 40e57e3a54 | |||
| 113b05ed05 | |||
| 824ce88914 | |||
| a1e243714e | |||
| 1c0ed64f67 | |||
| 1f1cd1b6d7 | |||
| e81725eb16 | |||
| ee4220e1ce | |||
| a733c6c68d | |||
| d7c7619218 | |||
| 77066ba7e5 | |||
| 35c5919c44 | |||
| fcdd286965 | |||
| e84fa1d636 | |||
| bfe9bad905 | |||
| 459b6bc6fe | |||
| 332211fb13 | |||
| e5d42cf0eb | |||
| 424df8d4fe | |||
| 2f4422f719 | |||
| 831611af1e | |||
| c302d362a4 | |||
| 69d4b1096f | |||
| 2514a89286 | |||
| 2034055148 | |||
| 3a3b1007b9 | |||
| 09a83b36ff | |||
| 32cc59228d | |||
| 31b2413953 | |||
| c8eb643818 | |||
| 11b251003e | |||
| 28bb0e99cb | |||
| 5c9c686317 | |||
| 098425bdbf | |||
| 5189f6b392 | |||
| f487479b1d | |||
| 03224cc4f6 | |||
| 482754eddb | |||
| 7fcf6874e3 | |||
| a3e0eee8d4 | |||
| b7ffb06f9c | |||
| 35a209bcb6 | |||
| c3a2a15608 | |||
| 9acdfe5dcf | |||
| 9ec8056d89 | |||
| b9c2cc2c4f | |||
| 675a2811d4 | |||
| b1df5f533b | |||
| a61cf3f889 | |||
| ace09646c6 | |||
| d2113c4379 | |||
| 9e60778075 | |||
| 4e78e4019f | |||
| 823d13af34 | |||
| 4007870bfb | |||
| 5d92f98548 | |||
| cbbff69003 | |||
| f40240d8cb | |||
| 9671599fc9 | |||
| e1be421410 | |||
| f4a80ed856 | |||
| 39610bce24 | |||
| 18e0044373 | |||
| a9759a20c2 | |||
| f5b9673044 |
@@ -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.
|
||||
@@ -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
|
||||
@@ -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,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
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'hotfix/**'
|
||||
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
|
||||
@@ -4,6 +4,7 @@
|
||||
/data/preferences/*
|
||||
/data/.backup/*
|
||||
/data/config.php
|
||||
/data/config-internal.php
|
||||
/data/tmp/*
|
||||
/build
|
||||
/node_modules
|
||||
@@ -18,4 +19,11 @@
|
||||
/composer.phar
|
||||
/vendor/
|
||||
/custom/Espo/Custom/*
|
||||
/custom/Espo/Modules/*
|
||||
!/custom/Espo/Custom/.htaccess
|
||||
!/custom/Espo/Modules/.htaccess
|
||||
/install/config.php
|
||||
|
||||
client/css/espo/*
|
||||
client/lib/*
|
||||
client/modules/crm/lib/*
|
||||
|
||||
@@ -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>
|
||||
|
||||
+338
-193
@@ -2,7 +2,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -19,113 +19,68 @@
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* * `grunt` - full build
|
||||
* * `grunt dev` - build only items needed for development (takes less time)
|
||||
* * `grunt offline` - build but skip *composer install*
|
||||
* * `grant release` - full build plus upgrade packages`
|
||||
* * `grant test` - build for test running
|
||||
* * `grant run-tests` - build and run unit and integratino tests
|
||||
*/
|
||||
/**
|
||||
* * `grunt` - full build;
|
||||
* * `grunt dev` - build only items needed for development (takes less time);
|
||||
* * `grunt offline` - build but skip *composer install*;
|
||||
* * `grunt internal` - build only libs and css;
|
||||
* * `grunt release` - full build plus upgrade packages`;
|
||||
* * `grunt test` - build for tests running;
|
||||
* * `grunt run-tests` - build and run unit and integration tests.
|
||||
*/
|
||||
|
||||
module.exports = function (grunt) {
|
||||
const fs = require('fs');
|
||||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
var jsFilesToMinify = [
|
||||
'client/lib/jquery-2.1.4.min.js',
|
||||
'client/lib/underscore-min.js',
|
||||
'client/lib/es6-promise.min.js',
|
||||
'client/lib/backbone-min.js',
|
||||
'client/lib/handlebars.js',
|
||||
'client/lib/base64.js',
|
||||
'client/lib/jquery-ui.min.js',
|
||||
'client/lib/jquery.ui.touch-punch.min.js',
|
||||
'client/lib/moment.min.js',
|
||||
'client/lib/moment-timezone.min.js',
|
||||
'client/lib/moment-timezone-data.js',
|
||||
'client/lib/jquery.timepicker.min.js',
|
||||
'client/lib/jquery.autocomplete.js',
|
||||
'client/lib/bootstrap.min.js',
|
||||
'client/lib/bootstrap-datepicker.js',
|
||||
'client/lib/bull.js',
|
||||
'client/lib/marked.min.js',
|
||||
'client/lib/autobahn.js',
|
||||
'client/lib/gridstack.all.js',
|
||||
module.exports = grunt => {
|
||||
|
||||
'client/src/namespace.js',
|
||||
'client/src/exceptions.js',
|
||||
'client/src/loader.js',
|
||||
'client/src/utils.js',
|
||||
const pkg = grunt.file.readJSON('package.json');
|
||||
const bundleConfig = require('./frontend/bundle-config.json');
|
||||
|
||||
'client/src/acl.js',
|
||||
'client/src/model.js',
|
||||
'client/src/model-offline.js',
|
||||
'client/src/ajax.js',
|
||||
'client/src/controller.js',
|
||||
let jsFilesToBundle = getBundleLibList().concat(bundleConfig.jsFiles);
|
||||
let jsFilesToCopy = getCopyLibDataList();
|
||||
|
||||
'client/src/ui.js',
|
||||
'client/src/acl-manager.js',
|
||||
'client/src/cache.js',
|
||||
'client/src/storage.js',
|
||||
'client/src/models/settings.js',
|
||||
'client/src/language.js',
|
||||
'client/src/metadata.js',
|
||||
'client/src/field-manager.js',
|
||||
'client/src/models/user.js',
|
||||
'client/src/models/preferences.js',
|
||||
'client/src/model-factory.js',
|
||||
'client/src/collection-factory.js',
|
||||
'client/src/pre-loader.js',
|
||||
'client/src/controllers/base.js',
|
||||
'client/src/router.js',
|
||||
'client/src/date-time.js',
|
||||
'client/src/layout-manager.js',
|
||||
'client/src/theme-manager.js',
|
||||
'client/src/session-storage.js',
|
||||
'client/src/view-helper.js',
|
||||
'client/src/page-title.js',
|
||||
let libFilesToMinify = jsFilesToCopy
|
||||
.filter(item => item.minify)
|
||||
.reduce((map, item) => (
|
||||
map[item.dest] = item.dest,
|
||||
map
|
||||
), {});
|
||||
|
||||
'client/src/app.js'
|
||||
];
|
||||
let currentPath = path.dirname(fs.realpathSync(__filename));
|
||||
|
||||
function camelCaseToHyphen (string){
|
||||
if (string == null) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
let themeList = [];
|
||||
|
||||
var fs = require('fs');
|
||||
var cp = require('child_process');
|
||||
var path = require('path');
|
||||
|
||||
var currentPath = path.dirname(fs.realpathSync(__filename));
|
||||
|
||||
var themeList = [];
|
||||
fs.readdirSync('application/Espo/Resources/metadata/themes').forEach(function (file) {
|
||||
fs.readdirSync('application/Espo/Resources/metadata/themes').forEach(file => {
|
||||
themeList.push(file.substr(0, file.length - 5));
|
||||
});
|
||||
|
||||
var cssminFilesData = {};
|
||||
var lessData = {};
|
||||
themeList.forEach(function (theme) {
|
||||
var name = camelCaseToHyphen(theme);
|
||||
var files = {};
|
||||
let cssminFilesData = {};
|
||||
|
||||
let lessData = {};
|
||||
|
||||
themeList.forEach(theme => {
|
||||
let name = camelCaseToHyphen(theme);
|
||||
|
||||
let files = {};
|
||||
|
||||
files['client/css/espo/'+name+'.css'] = 'frontend/less/'+name+'/main.less';
|
||||
files['client/css/espo/'+name+'-iframe.css'] = 'frontend/less/'+name+'/iframe/main.less';
|
||||
|
||||
cssminFilesData['client/css/espo/'+name+'.css'] = 'client/css/espo/'+name+'.css';
|
||||
cssminFilesData['client/css/espo/'+name+'-iframe.css'] = 'client/css/espo/'+name+'-iframe.css';
|
||||
var o = {
|
||||
|
||||
let o = {
|
||||
options: {
|
||||
yuicompress: true,
|
||||
},
|
||||
files: files
|
||||
files: files,
|
||||
};
|
||||
|
||||
lessData[theme] = o;
|
||||
});
|
||||
|
||||
var pkg = grunt.file.readJSON('package.json');
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: pkg,
|
||||
|
||||
@@ -135,45 +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: [
|
||||
@@ -185,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',
|
||||
@@ -218,7 +196,6 @@ module.exports = function (grunt) {
|
||||
'extension.php',
|
||||
'websocket.php',
|
||||
'command.php',
|
||||
'oauth-callback.php',
|
||||
'index.php',
|
||||
'LICENSE.txt',
|
||||
'.htaccess',
|
||||
@@ -234,120 +211,205 @@ module.exports = function (grunt) {
|
||||
dest: 'build/EspoCRM-<%= pkg.version %>/',
|
||||
},
|
||||
},
|
||||
chmod: {
|
||||
php: {
|
||||
options: {
|
||||
mode: '644'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.php',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.json',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.config',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/.htaccess',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.js',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.css',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/**/*.tpl',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.html',
|
||||
'build/EspoCRM-<%= pkg.version %>/**/*.txt',
|
||||
]
|
||||
},
|
||||
folders: {
|
||||
options: {
|
||||
mode: '755'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/install',
|
||||
'build/EspoCRM-<%= pkg.version %>/portal',
|
||||
'build/EspoCRM-<%= pkg.version %>/api',
|
||||
'build/EspoCRM-<%= pkg.version %>/api/v1',
|
||||
'build/EspoCRM-<%= pkg.version %>/api/v1/portal-access',
|
||||
'build/EspoCRM-<%= pkg.version %>',
|
||||
]
|
||||
},
|
||||
foldersWritable: {
|
||||
options: {
|
||||
mode: '775'
|
||||
},
|
||||
src: [
|
||||
'build/EspoCRM-<%= pkg.version %>/data',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom/Espo',
|
||||
'build/EspoCRM-<%= pkg.version %>/custom/Espo/Custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/custom',
|
||||
'build/EspoCRM-<%= pkg.version %>/client/modules',
|
||||
'build/EspoCRM-<%= pkg.version %>/application/Espo/Modules',
|
||||
]
|
||||
},
|
||||
},
|
||||
|
||||
replace: {
|
||||
version: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: 'version',
|
||||
replacement: '<%= pkg.version %>'
|
||||
replacement: '<%= pkg.version %>',
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
src: 'build/tmp/application/Espo/Resources/defaults/config.php',
|
||||
dest: 'build/tmp/application/Espo/Resources/defaults/config.php'
|
||||
dest: 'build/tmp/application/Espo/Resources/defaults/config.php',
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
dev: {
|
||||
options: {
|
||||
patterns: [
|
||||
{
|
||||
match: /\# \{\#dev\}(.*)\{\/dev\}/gs,
|
||||
replacement: '',
|
||||
}
|
||||
]
|
||||
},
|
||||
files: [
|
||||
{
|
||||
src: 'build/tmp/.htaccess',
|
||||
dest: 'build/tmp/.htaccess',
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
grunt.registerTask("chmod-folders", function() {
|
||||
cp.execSync("find . -type d -exec chmod 755 {} + ", {stdio: 'ignore', cwd: 'build/EspoCRM-' + pkg.version});
|
||||
grunt.registerTask('chmod-folders', () => {
|
||||
cp.execSync(
|
||||
"find . -type d -exec chmod 755 {} +",
|
||||
{
|
||||
cwd: 'build/EspoCRM-' + pkg.version,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
grunt.registerTask("composer", function() {
|
||||
cp.execSync("composer install --ignore-platform-reqs --no-dev", {stdio: 'ignore'});
|
||||
grunt.registerTask('chmod-multiple', () => {
|
||||
let dirPath = 'build/EspoCRM-' + pkg.version;
|
||||
|
||||
let fileList = [
|
||||
{
|
||||
name: '*.php',
|
||||
},
|
||||
{
|
||||
name: '*.json',
|
||||
},
|
||||
{
|
||||
name: '*.config',
|
||||
},
|
||||
{
|
||||
name: '.htaccess',
|
||||
},
|
||||
{
|
||||
name: '*.html',
|
||||
},
|
||||
{
|
||||
name: '*.txt',
|
||||
},
|
||||
{
|
||||
name: '*.js',
|
||||
folder: 'client',
|
||||
},
|
||||
{
|
||||
name: '*.css',
|
||||
folder: 'client',
|
||||
},
|
||||
{
|
||||
name: '*.tpl',
|
||||
folder: 'client',
|
||||
},
|
||||
];
|
||||
|
||||
let dirReadableList = [
|
||||
'public/install',
|
||||
'public/portal',
|
||||
'public/api',
|
||||
'public/api/v1',
|
||||
'public/api/v1/portal-access',
|
||||
'.',
|
||||
];
|
||||
|
||||
let dirWritableList = [
|
||||
'data',
|
||||
'custom',
|
||||
'custom/Espo',
|
||||
'custom/Espo/Custom',
|
||||
'client/custom',
|
||||
'client/modules',
|
||||
'application/Espo/Modules',
|
||||
];
|
||||
|
||||
fileList.forEach(item => {
|
||||
let path = item.folder || '.';
|
||||
let name = item.name;
|
||||
|
||||
cp.execSync(
|
||||
`find ${path} -type f -iname "${name}" -exec chmod 644 {} +`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
dirReadableList.forEach(item => {
|
||||
cp.execSync(
|
||||
`chmod 755 ${item}`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
dirWritableList.forEach(item => {
|
||||
cp.execSync(
|
||||
`chmod 775 ${item}`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
cp.execSync(
|
||||
`find bin -type f -exec chmod 754 {} +`,
|
||||
{
|
||||
cwd: dirPath,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
grunt.registerTask("composer-dev", function() {
|
||||
cp.execSync("composer install --ignore-platform-reqs", {stdio: 'ignore'});
|
||||
grunt.registerTask('composer-install', () => {
|
||||
cp.execSync("composer install --no-dev", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.registerTask("upgrade", function() {
|
||||
grunt.registerTask('composer-install-dev', () => {
|
||||
cp.execSync("composer install", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.registerTask('upgrade', () => {
|
||||
cp.execSync("node diff --all --vendor", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("unit-tests-run", function() {
|
||||
grunt.registerTask('unit-tests-run', () => {
|
||||
cp.execSync("vendor/bin/phpunit ./tests/unit", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("integration-tests-run", function() {
|
||||
grunt.registerTask('integration-tests-run', () => {
|
||||
cp.execSync("vendor/bin/phpunit ./tests/integration", {stdio: 'inherit'});
|
||||
});
|
||||
|
||||
grunt.registerTask("zip", function() {
|
||||
var fs = require('fs');
|
||||
grunt.registerTask('set-config-params', () => {
|
||||
cp.execSync("composer run-script setConfigParams", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
var resolve = this.async();
|
||||
grunt.registerTask('zip', () => {
|
||||
const archiver = require('archiver');
|
||||
|
||||
var folder = 'EspoCRM-' + pkg.version;
|
||||
let resolve = this.async();
|
||||
|
||||
var zipPath = 'build/' + folder +'.zip';
|
||||
if (fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
|
||||
let folder = 'EspoCRM-' + pkg.version;
|
||||
|
||||
var archiver = require('archiver');
|
||||
var archive = archiver('zip');
|
||||
let zipPath = 'build/' + folder +'.zip';
|
||||
|
||||
archive.on('error', function (err) {
|
||||
if (fs.existsSync(zipPath)) {
|
||||
fs.unlinkSync(zipPath);
|
||||
}
|
||||
|
||||
let archive = archiver('zip');
|
||||
|
||||
archive.on('error', err => {
|
||||
grunt.fail.warn(err);
|
||||
});
|
||||
var zipOutput = fs.createWriteStream(zipPath);
|
||||
zipOutput.on('close', function () {
|
||||
|
||||
let zipOutput = fs.createWriteStream(zipPath);
|
||||
|
||||
zipOutput.on('close', () => {
|
||||
console.log("EspoCRM package has been built.");
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
archive.directory(currentPath + '/build/' + folder, folder).pipe(zipOutput);
|
||||
archive
|
||||
.directory(currentPath + '/build/' + folder, folder)
|
||||
.pipe(zipOutput)
|
||||
.finalize();
|
||||
});
|
||||
|
||||
archive.finalize();
|
||||
grunt.registerTask('npm-install', () => {
|
||||
cp.execSync("npm ci", {stdio: 'ignore'});
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
@@ -357,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',
|
||||
@@ -397,7 +467,7 @@ module.exports = function (grunt) {
|
||||
]);
|
||||
|
||||
grunt.registerTask('run-unit-tests', [
|
||||
'composer-dev',
|
||||
'composer-install-dev',
|
||||
'unit-tests-run',
|
||||
]);
|
||||
|
||||
@@ -407,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();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
## EspoCRM
|
||||
|
||||
[EspoCRM is an Open Source CRM](https://www.espocrm.com) (Customer Relationship Management) software that allows you to see, enter and evaluate all your company relationships regardless of the type. People, companies or opportunities - all in an easy and intuitive interface.
|
||||
[](#espocrm)
|
||||
|
||||
[EspoCRM is an Open Source CRM](https://www.espocrm.com) (Customer Relationship Management) software that allows you to see, enter and evaluate all your company relationships regardless of the type. People, companies or opportunities – all in an easy and intuitive interface.
|
||||
|
||||
It's a web application with a frontend designed as a single page application and REST API backend written in PHP.
|
||||
|
||||
@@ -8,22 +10,22 @@ It's a web application with a frontend designed as a single page application and
|
||||
|
||||
### Requirements
|
||||
|
||||
* PHP 7.2 and later (with pdo, json, gd, openssl, zip, imap, mbstring, curl extensions);
|
||||
* PHP 7.4 and later (with pdo, json, gd, openssl, zip, imap, mbstring, curl extensions);
|
||||
* MySQL 5.7 (and later), or MariaDB 10.1 (and later).
|
||||
|
||||
For more information about server configuration see [this article](https://docs.espocrm.com/administration/server-configuration/).
|
||||
|
||||
### Documentation
|
||||
|
||||
Documentation for administrators, users and developers is available [here](https://docs.espocrm.com).
|
||||
The documentation for administrators, users and developers is available [here](https://docs.espocrm.com).
|
||||
|
||||
### How to report a bug
|
||||
### Bug reporting
|
||||
|
||||
Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our [forum](http://forum.espocrm.com/forum/bug-reports).
|
||||
|
||||
### How to install a stable version
|
||||
### Installing the stable version
|
||||
|
||||
[Download](https://www.espocrm.com/download/) the latest version. See the [instructions](https://docs.espocrm.com/administration/installation/) about installation.
|
||||
See the [instructions](https://docs.espocrm.com/administration/installation/) about installation.
|
||||
|
||||
### Development
|
||||
|
||||
@@ -31,13 +33,13 @@ Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our
|
||||
* [Running tests](https://docs.espocrm.com/development/tests)
|
||||
* [Making translation](https://docs.espocrm.com/development/translation)
|
||||
|
||||
### How to contribute
|
||||
### Contributing
|
||||
|
||||
Before we can merge your pull request you need to accept our CLA [here](https://github.com/espocrm/cla). It's very simple to do.
|
||||
|
||||
Branches:
|
||||
|
||||
* *hotfix/** – upcoming maintenance release; fixes should be pushed to this branch;
|
||||
* *fix* – upcoming maintenance release; fixes should be pushed to this branch;
|
||||
* *master* – develop branch; new features should be pushed to this branch;
|
||||
* *stable* – last stable release.
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Attachment extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
$hasParent = false;
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
} else if ($entity->get('relatedId') && $entity->get('relatedType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('relatedType'), $entity->get('relatedId'));
|
||||
}
|
||||
|
||||
if ($hasParent) {
|
||||
if ($parent) {
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
if ($parent->get('parentId') && $parent->get('parentType')) {
|
||||
$parentOfParent = $this->getEntityManager()->getEntity($parent->get('parentType'), $parent->get('parentId'));
|
||||
if ($parentOfParent && $this->getAclManager()->checkEntity($user, $parentOfParent)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Email extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
protected $ownerUserIdAttribute = 'usersIds';
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($data)) {
|
||||
if ($data->read === false || $data->read === 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$entity->has('usersIds')) {
|
||||
$entity->loadLinkMultipleField('users');
|
||||
}
|
||||
$userIdList = $entity->get('usersIds');
|
||||
if (is_array($userIdList) && in_array($user->id, $userIdList)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->hasLinkMultipleId('assignedUsers', $user->id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data->delete === 'own') {
|
||||
if ($user->id === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$assignedUserIdList = $entity->getLinkMultipleIdList('assignedUsers');
|
||||
if (count($assignedUserIdList) === 1 && $entity->hasLinkMultipleId('assignedUsers', $user->id)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'delete')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data->edit !== 'no' || $data->create !== 'no') {
|
||||
if ($entity->get('createdById') === $user->id) {
|
||||
if ($entity->get('status') !== 'Sent' && $entity->get('status') !== 'Archived') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailAddress extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('EmailAddress');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameAddressList = $repository->getEntityListByAddressId($id, $excludeEntity);
|
||||
foreach ($entityWithSameAddressList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
if (
|
||||
$e->getEntityType() === 'User' &&
|
||||
$e->isPortal() &&
|
||||
$excludeEntity->getEntityType() === 'Contact' &&
|
||||
$e->get('contactId') === $excludeEntity->id
|
||||
) {
|
||||
$isFobidden = false;
|
||||
}
|
||||
if ($isFobidden) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Note extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
protected $deleteThresholdPeriod = '1 month';
|
||||
|
||||
protected $editThresholdPeriod = '7 days';
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($entity->get('type') === 'Post' && $user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
if ($parent) {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent, 'stream')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'edit')) {
|
||||
if ($this->checkIsOwner($user, $entity)) {
|
||||
$createdAt = $entity->get('createdAt');
|
||||
if ($createdAt) {
|
||||
$noteEditThresholdPeriod = '-' . $this->getConfig()->get('noteEditThresholdPeriod', $this->editThresholdPeriod);
|
||||
$dt = new \DateTime();
|
||||
$dt->modify($noteEditThresholdPeriod);
|
||||
try {
|
||||
if ($dt->format('U') > (new \DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'delete')) {
|
||||
if ($this->checkIsOwner($user, $entity)) {
|
||||
$createdAt = $entity->get('createdAt');
|
||||
if ($createdAt) {
|
||||
$deleteThresholdPeriod = '-' . $this->getConfig()->get('noteDeleteThresholdPeriod', $this->deleteThresholdPeriod);
|
||||
$dt = new \DateTime();
|
||||
$dt->modify($deleteThresholdPeriod);
|
||||
try {
|
||||
if ($dt->format('U') > (new \DateTime($createdAt))->format('U')) {
|
||||
return false;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PhoneNumber extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('PhoneNumber');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameNumberList = $repository->getEntityListByPhoneNumberId($id, $excludeEntity);
|
||||
foreach ($entityWithSameNumberList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
if (
|
||||
$e->getEntityType() === 'User' &&
|
||||
$e->isPortal() &&
|
||||
$excludeEntity->getEntityType() === 'Contact' &&
|
||||
$e->get('contactId') === $excludeEntity->id
|
||||
) {
|
||||
$isFobidden = false;
|
||||
}
|
||||
if ($isFobidden) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
|
||||
use Espo\Entities\User as EntityUser;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class Webhook extends \Espo\Core\Acl\Acl
|
||||
{
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
return $user->id === $entity->get('userId') && $user->isApi();
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) return true;
|
||||
if (!$data) return false;
|
||||
if ($user->isApi() && $user->id === $entity->get('userId')) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\AclPortal;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class Attachment extends \Espo\Core\AclPortal\Base
|
||||
{
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get('parentType') === 'Settings') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
$hasParent = false;
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
} else if ($entity->get('relatedId') && $entity->get('relatedType')) {
|
||||
$hasParent = true;
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('relatedType'), $entity->get('relatedId'));
|
||||
}
|
||||
|
||||
if ($hasParent) {
|
||||
if ($parent) {
|
||||
if ($parent->getEntityType() === 'Note') {
|
||||
if ($parent->get('parentId') && $parent->get('parentType')) {
|
||||
$parentOfParent = $this->getEntityManager()->getEntity($parent->get('parentType'), $parent->get('parentId'));
|
||||
if ($parentOfParent && $this->getAclManager()->checkEntity($user, $parentOfParent)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($this->getAclManager()->checkEntity($user, $parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\AclPortal;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
|
||||
class EmailAddress extends \Espo\Core\AclPortal\Base
|
||||
{
|
||||
public function checkEditInEntity(EntityUser $user, Entity $entity, Entity $excludeEntity)
|
||||
{
|
||||
$id = $entity->id;
|
||||
|
||||
$isFobidden = false;
|
||||
|
||||
$repository = $this->getEntityManager()->getRepository('EmailAddress');
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$entityWithSameAddressList = $repository->getEntityListByAddressId($id, $excludeEntity);
|
||||
foreach ($entityWithSameAddressList as $e) {
|
||||
if (!$this->getAclManager()->check($user, $e, 'edit')) {
|
||||
$isFobidden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return !$isFobidden;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\Acl\ActionHistoryRecord;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\ActionHistoryRecord>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $entity->get('userId') === $user->getId();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+35
-28
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,46 +27,53 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\AclPortal;
|
||||
namespace Espo\Classes\Acl\Email;
|
||||
|
||||
use \Espo\Entities\User as EntityUser;
|
||||
use \Espo\ORM\Entity;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Entities\Email;
|
||||
|
||||
class Email extends \Espo\Core\AclPortal\Base
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\DefaultOwnershipChecker,
|
||||
Acl\OwnershipOwnChecker,
|
||||
Acl\OwnershipTeamChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Email>
|
||||
* @implements OwnershipTeamChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker, OwnershipTeamChecker
|
||||
{
|
||||
protected $ownerUserIdAttribute = 'usersIds';
|
||||
private $defaultOwnershipChecker;
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
public function __construct(DefaultOwnershipChecker $defaultOwnershipChecker)
|
||||
{
|
||||
if ($this->checkEntity($user, $entity, $data, 'read')) {
|
||||
$this->defaultOwnershipChecker = $defaultOwnershipChecker;
|
||||
}
|
||||
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
if ($user->getId() === $entity->get('assignedUserId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
if (is_object($data)) {
|
||||
if ($data->read === false || $data->read === 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$entity->has('usersIds')) {
|
||||
$entity->loadLinkMultipleField('users');
|
||||
}
|
||||
$userIdList = $entity->get('usersIds');
|
||||
if (is_array($userIdList) && in_array($user->id, $userIdList)) {
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->hasLinkMultipleId('assignedUsers', $user->getId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
public function checkTeam(User $user, Entity $entity): bool
|
||||
{
|
||||
if ($user->id === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $this->defaultOwnershipChecker->checkTeam($user, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-29
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,57 +27,56 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Authentication\TwoFactor\Methods;
|
||||
namespace Espo\Classes\Acl\EmailFilter;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use StdClass;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
class Totp implements CodeVerify
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\EmailFilter>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
protected $entityManager;
|
||||
protected $totp;
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager, TotpUtils $totp)
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->totp = $totp;
|
||||
}
|
||||
|
||||
public function verifyCode(User $user, string $code) : bool
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$userData = $this->entityManager
|
||||
->getRepository('UserData')
|
||||
->getByUserId($user->id);
|
||||
|
||||
if (!$userData) {
|
||||
if (!$entity->has('parentId') || !$entity->has('parentType')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$userData->get('auth2FA')) {
|
||||
$parentType = $entity->get('parentType');
|
||||
$parentId = $entity->get('parentId');
|
||||
|
||||
if (!$parentType || !$parentId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($userData->get('auth2FAMethod') != 'Totp') {
|
||||
$parent = $this->entityManager->getEntity($parentType, $parentId);
|
||||
|
||||
if (!$parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$secret = $userData->get('auth2FATotpSecret');
|
||||
|
||||
if (!$secret) {
|
||||
return false;
|
||||
if ($parent->getEntityType() === 'User') {
|
||||
return $parent->getId() === $user->getId();
|
||||
}
|
||||
|
||||
return $this->totp->verifyCode($secret, $code);
|
||||
}
|
||||
if ($parent->has('assignedUserId') && $parent->get('assignedUserId') === $user->getId()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLoginData(User $user) : StdClass
|
||||
{
|
||||
return (object) [
|
||||
'message' => 'enterTotpCode',
|
||||
];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,23 +27,27 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\AclPortal;
|
||||
namespace Espo\Classes\Acl\Notification;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\AclPortal\Acl;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
class Account extends Acl
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Notification>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkInAccount(User $user, Entity $entity)
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$accountIdList = $user->getLinkMultipleIdList('accounts');
|
||||
if (count($accountIdList)) {
|
||||
if (in_array($entity->id, $accountIdList)) {
|
||||
return true;
|
||||
}
|
||||
if ($user->getId() === $entity->get('userId')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+82
-38
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,72 +27,116 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Acl;
|
||||
namespace Espo\Classes\Acl\User;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Entities\User as EntityUser;
|
||||
|
||||
class User extends \Espo\Core\Acl\Acl
|
||||
use Espo\Core\{
|
||||
Acl\Table,
|
||||
Acl\ScopeData,
|
||||
Acl\DefaultAccessChecker,
|
||||
Acl\AccessEntityCREDSChecker,
|
||||
Acl\Traits\DefaultAccessCheckerDependency,
|
||||
AclManager,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements AccessEntityCREDSChecker<User>
|
||||
*/
|
||||
class AccessChecker implements AccessEntityCREDSChecker
|
||||
{
|
||||
public function checkIsOwner(EntityUser $user, Entity $entity)
|
||||
use DefaultAccessCheckerDependency;
|
||||
|
||||
private $defaultAccessChecker;
|
||||
|
||||
private $aclManager;
|
||||
|
||||
public function __construct(DefaultAccessChecker $defaultAccessChecker, AclManager $aclManager)
|
||||
{
|
||||
return $user->id === $entity->id;
|
||||
$this->defaultAccessChecker = $defaultAccessChecker;
|
||||
$this->aclManager = $aclManager;
|
||||
}
|
||||
|
||||
public function checkEntityRead(EntityUser $user, Entity $entity, $data)
|
||||
public function checkEntityCreate(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if (!$user->isAdmin() && $entity->isPortal()) {
|
||||
if ($this->getAclManager()->get($user, 'portalPermission') === 'yes') {
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityCreate($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityRead(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isPortal()) {
|
||||
if ($this->aclManager->getPermissionLevel($user, 'portal') === Table::LEVEL_YES) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'read');
|
||||
}
|
||||
|
||||
public function checkEntityCreate(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'create');
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityRead($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(EntityUser $user, Entity $entity, $data)
|
||||
public function checkEntityEdit(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
if ($entity->id === 'system') {
|
||||
return false;
|
||||
}
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
/** @var User $entity */
|
||||
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return parent::checkEntityDelete($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityEdit(EntityUser $user, Entity $entity, $data)
|
||||
{
|
||||
if ($entity->id === 'system') {
|
||||
return false;
|
||||
}
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
if (!$user->isAdmin()) {
|
||||
if ($user->id !== $entity->id) {
|
||||
if ($user->getId() !== $entity->getId()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
return $this->checkEntity($user, $entity, $data, 'edit');
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityEdit($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityDelete(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSystem()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($entity->isSuperAdmin() && !$user->isSuperAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->defaultAccessChecker->checkEntityDelete($user, $entity, $data);
|
||||
}
|
||||
|
||||
public function checkEntityStream(User $user, Entity $entity, ScopeData $data): bool
|
||||
{
|
||||
/** @var User $entity */
|
||||
|
||||
return $this->aclManager->checkUserPermission($user, $entity, 'user');
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\Acl\Webhook;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\Acl\OwnershipOwnChecker;
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Webhook>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $user->getId() === $entity->get('userId') && $user->isApi();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,23 +27,27 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Modules\Crm\AclPortal;
|
||||
namespace Espo\Classes\AclPortal\Email;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\AclPortal\Acl;
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
class Contact extends Acl
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\Email>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkIsOwnContact(User $user, Entity $entity)
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
$contactId = $user->get('contactId');
|
||||
if ($contactId) {
|
||||
if ($entity->id === $contactId) {
|
||||
return true;
|
||||
}
|
||||
if ($user->getId() === $entity->get('createdById')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\AclPortal\User;
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\OwnershipOwnChecker,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements OwnershipOwnChecker<\Espo\Entities\User>
|
||||
*/
|
||||
class OwnershipChecker implements OwnershipOwnChecker
|
||||
{
|
||||
public function checkOwn(User $user, Entity $entity): bool
|
||||
{
|
||||
return $user->getId() === $entity->getId();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter1 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter2 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter3 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
namespace Espo\Classes\AddressFormatters;
|
||||
|
||||
use Espo\Core\FieldUtils\Address\{
|
||||
AddressFormatter,
|
||||
AddressValue,
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFormatter,
|
||||
};
|
||||
|
||||
class Formatter4 implements AddressFormatter
|
||||
{
|
||||
public function format(AddressValue $address) : string
|
||||
public function format(Address $address): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -30,28 +30,26 @@
|
||||
namespace Espo\Classes\AppInfo;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Module,
|
||||
Binding\EspoBindingLoader,
|
||||
Binding\Binding as BindingItem,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Binding
|
||||
{
|
||||
protected $fileManager;
|
||||
private $module;
|
||||
|
||||
public function __construct(FileManager $fileManager)
|
||||
public function __construct(Module $module)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
public function process(array $options, array $flagList) : ?string
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$bindingLoader = new EspoBindingLoader(
|
||||
new Module($this->fileManager)
|
||||
);
|
||||
$bindingLoader = new EspoBindingLoader($this->module);
|
||||
|
||||
$data = $bindingLoader->load();
|
||||
|
||||
@@ -71,14 +69,14 @@ class Binding
|
||||
$keyList = $data->getContextKeyList($context);
|
||||
|
||||
foreach ($keyList as $key) {
|
||||
$result .= $this->printItem($key, $data->getContext($context, $key), true);
|
||||
$result .= $this->printItem($key, $data->getContext($context, $key));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function printItem(string $key, BindingItem $binding) : string
|
||||
private function printItem(string $key, BindingItem $binding): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
@@ -94,6 +92,7 @@ class Binding
|
||||
BindingItem::CONTAINER_SERVICE => 'Service',
|
||||
BindingItem::VALUE => 'Value',
|
||||
BindingItem::CALLBACK => 'Callback',
|
||||
BindingItem::FACTORY_CLASS_NAME => 'Factory',
|
||||
][$type];
|
||||
|
||||
$result .= $tab . "Type: {$typeString}\n";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -32,12 +32,14 @@ namespace Espo\Classes\AppInfo;
|
||||
use Espo\Core\{
|
||||
Container as ContainerService,
|
||||
Utils\Metadata,
|
||||
Console\Command\Params,
|
||||
};
|
||||
|
||||
class Container
|
||||
{
|
||||
protected $container;
|
||||
protected $metadata;
|
||||
private $container;
|
||||
|
||||
private $metadata;
|
||||
|
||||
public function __construct(ContainerService $container, Metadata $metadata)
|
||||
{
|
||||
@@ -45,9 +47,9 @@ class Container
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function process(array $options, array $flagList) : ?string
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$nameOnly = in_array('nameOnly', $flagList);
|
||||
$nameOnly = $params->hasFlag('nameOnly');
|
||||
|
||||
$result = '';
|
||||
|
||||
@@ -61,10 +63,11 @@ class Container
|
||||
'user',
|
||||
];
|
||||
|
||||
/** @var string[] */
|
||||
$fileList = scandir('application/Espo/Core/Loaders');
|
||||
|
||||
if (file_exists('custom/Espo/Custom/Core/Loaders')) {
|
||||
$fileList = array_merge($fileList, scandir('custom/Espo/Custom/Core/Loaders'));
|
||||
$fileList = array_merge($fileList, scandir('custom/Espo/Custom/Core/Loaders') ?: []);
|
||||
}
|
||||
|
||||
foreach ($fileList as $file) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\AppInfo;
|
||||
|
||||
use Espo\Core\Console\Command\Params;
|
||||
use Espo\Core\Utils\ClassFinder;
|
||||
use Espo\Core\Job\MetadataProvider;
|
||||
|
||||
class Jobs
|
||||
{
|
||||
private $classFinder;
|
||||
|
||||
private $metadataProvider;
|
||||
|
||||
public function __construct(ClassFinder $classFinder, MetadataProvider $metadataProvider)
|
||||
{
|
||||
$this->classFinder = $classFinder;
|
||||
$this->metadataProvider = $metadataProvider;
|
||||
}
|
||||
|
||||
public function process(Params $params): string
|
||||
{
|
||||
$result = "Available jobs:\n\n";
|
||||
|
||||
$list = array_map(
|
||||
function ($item) {
|
||||
return ' ' . $item;
|
||||
},
|
||||
array_unique(
|
||||
array_merge(
|
||||
array_keys($this->classFinder->getMap('Jobs')),
|
||||
$this->metadataProvider->getScheduledJobNameList()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
asort($list);
|
||||
|
||||
return $result . implode("\n", $list) . "\n";
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,7 +31,7 @@ namespace Espo\Classes\AppParams;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl,
|
||||
Select\SelectManagerFactory,
|
||||
Select\SelectBuilderFactory,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
@@ -40,18 +40,23 @@ use Espo\Core\{
|
||||
*/
|
||||
class TemplateEntityTypeList
|
||||
{
|
||||
protected $acl;
|
||||
protected $selectManagerFactory;
|
||||
protected $entityManager;
|
||||
private $acl;
|
||||
|
||||
public function __construct(Acl $acl, SelectManagerFactory $selectManagerFactory, EntityManager $entityManager)
|
||||
private $selectBuilderFactory;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Acl $acl, SelectBuilderFactory $selectBuilderFactory, EntityManager $entityManager)
|
||||
{
|
||||
$this->acl = $acl;
|
||||
$this->selectManagerFactory = $selectManagerFactory;
|
||||
$this->selectBuilderFactory = $selectBuilderFactory;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function get()
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
if (!$this->acl->checkScope('Template')) {
|
||||
return [];
|
||||
@@ -59,17 +64,21 @@ class TemplateEntityTypeList
|
||||
|
||||
$list = [];
|
||||
|
||||
$selectManager = $this->selectManagerFactory->create('Template');
|
||||
|
||||
$selectParams = $selectManager->getEmptySelectParams();
|
||||
$selectManager->applyAccess($selectParams);
|
||||
|
||||
$templateList = $this->entityManager->getRepository('Template')
|
||||
$query = $this->selectBuilderFactory
|
||||
->create()
|
||||
->from('Template')
|
||||
->withAccessControlFilter()
|
||||
->buildQueryBuilder()
|
||||
->select(['entityType'])
|
||||
->groupBy(['entityType'])
|
||||
->find($selectParams);
|
||||
->group(['entityType'])
|
||||
->build();
|
||||
|
||||
foreach ($templateList as $template) {
|
||||
$templateCollection = $this->entityManager
|
||||
->getRDBRepository('Template')
|
||||
->clone($query)
|
||||
->find();
|
||||
|
||||
foreach ($templateCollection as $template) {
|
||||
$list[] = $template->get('entityType');
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+29
-29
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -27,47 +27,47 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Authentication\TwoFactor\User;
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Entities\UserData;
|
||||
use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils;
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
use StdClass;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class Totp implements CodeVerify
|
||||
use Espo\Entities\PasswordChangeRequest;
|
||||
|
||||
class PasswordChangeRequests implements Cleanup
|
||||
{
|
||||
protected $entityManager;
|
||||
protected $totp;
|
||||
private Config $config;
|
||||
|
||||
public function __construct(TotpUtils $totp, Config $config)
|
||||
private EntityManager $entityManager;
|
||||
|
||||
private string $cleanupPeriod = '30 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->totp = $totp;
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function generateData(UserData $userData, StdClass $data, string $userName) : StdClass
|
||||
public function process(): void
|
||||
{
|
||||
$secret = $this->totp->createSecret();
|
||||
$period = '-' . $this->config->get('cleanupPasswordChangeRequestsPeriod', $this->cleanupPeriod);
|
||||
|
||||
$label = rawurlencode($this->config->get('applicationName')) . ':' . rawurlencode($userName);
|
||||
$before = DateTime::createNow()
|
||||
->modify($period)
|
||||
->getString();
|
||||
|
||||
return (object) [
|
||||
'auth2FATotpSecret' => $secret,
|
||||
'label' => $label,
|
||||
];
|
||||
}
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from(PasswordChangeRequest::ENTITY_TYPE)
|
||||
->where([
|
||||
'createdAt<' => $before,
|
||||
])
|
||||
->build();
|
||||
|
||||
public function verify(UserData $userData, string $code) : bool
|
||||
{
|
||||
if (!$code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$code = str_replace(' ', '', trim($code));
|
||||
|
||||
$secret = $userData->get('auth2FATotpSecret');
|
||||
|
||||
return $this->totp->verifyCode($secret, $code);
|
||||
$this->entityManager->getQueryExecutor()->execute($delete);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,17 +29,19 @@
|
||||
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class Reminders
|
||||
class Reminders implements Cleanup
|
||||
{
|
||||
protected $config;
|
||||
protected $entityManager;
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
private string $cleanupRemindersPeriod = '15 days';
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
@@ -47,9 +49,7 @@ class Reminders
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
protected $cleanupRemindersPeriod = '15 days';
|
||||
|
||||
public function process()
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupRemindersPeriod', $this->cleanupRemindersPeriod);
|
||||
|
||||
@@ -57,7 +57,8 @@ class Reminders
|
||||
|
||||
$dt->modify($period);
|
||||
|
||||
$delete = $this->entityManager->getQueryBuilder()
|
||||
$delete = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('Reminder')
|
||||
->where([
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\DateTime as DateTimeUtil;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Entities\TwoFactorCode;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class TwoFactorCodes implements Cleanup
|
||||
{
|
||||
private const PERIOD = '5 days';
|
||||
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupTwoFactorCodesPeriod', self::PERIOD);
|
||||
|
||||
$from = (new DateTime())
|
||||
->modify($period)
|
||||
->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT);
|
||||
|
||||
$query = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from(TwoFactorCode::ENTITY_TYPE)
|
||||
->where([
|
||||
'createdAt<' => $from,
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager
|
||||
->getQueryExecutor()
|
||||
->execute($query);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,19 +29,19 @@
|
||||
|
||||
namespace Espo\Classes\Cleanup;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
use Espo\Core\Cleanup\Cleanup;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class WebhookQueue
|
||||
class WebhookQueue implements Cleanup
|
||||
{
|
||||
protected $cleanupWebhookQueuePeriod = '10 days';
|
||||
private string $cleanupWebhookQueuePeriod = '10 days';
|
||||
|
||||
protected $config;
|
||||
protected $entityManager;
|
||||
private $config;
|
||||
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(Config $config, EntityManager $entityManager)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ class WebhookQueue
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process()
|
||||
public function process(): void
|
||||
{
|
||||
$period = '-' . $this->config->get('cleanupWebhookQueuePeriod', $this->cleanupWebhookQueuePeriod);
|
||||
|
||||
@@ -58,7 +58,8 @@ class WebhookQueue
|
||||
$datetime->modify($period);
|
||||
$from = $datetime->format('Y-m-d H:i:s');
|
||||
|
||||
$query = $this->entityManager->getQueryBuilder()
|
||||
$query1 = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('WebhookQueueItem')
|
||||
->where([
|
||||
@@ -70,9 +71,10 @@ class WebhookQueue
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($query);
|
||||
$this->entityManager->getQueryExecutor()->execute($query1);
|
||||
|
||||
$query = $this->entityManager->getQueryBuilder()
|
||||
$query2 = $this->entityManager
|
||||
->getQueryBuilder()
|
||||
->delete()
|
||||
->from('WebhookEventQueueItem')
|
||||
->where([
|
||||
@@ -84,6 +86,6 @@ class WebhookQueue
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->entityManager->getQueryExecutor()->execute($query);
|
||||
$this->entityManager->getQueryExecutor()->execute($query2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -29,110 +29,109 @@
|
||||
|
||||
namespace Espo\Classes\ConsoleCommands;
|
||||
|
||||
use Espo\Tools\Import\Service;
|
||||
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
|
||||
use Espo\Core\{
|
||||
ServiceFactory,
|
||||
Console\Commands\Command,
|
||||
Console\Command,
|
||||
Console\Command\Params,
|
||||
Console\IO,
|
||||
};
|
||||
|
||||
use Throwable;
|
||||
|
||||
class Import implements Command
|
||||
{
|
||||
protected $serviceFactory;
|
||||
private Service $service;
|
||||
|
||||
public function __construct(ServiceFactory $serviceFactory)
|
||||
private FileManager $fileManager;
|
||||
|
||||
public function __construct(Service $service, FileManager $fileManager)
|
||||
{
|
||||
$this->serviceFactory = $serviceFactory;
|
||||
$this->service = $service;
|
||||
$this->fileManager = $fileManager;
|
||||
}
|
||||
|
||||
public function run(array $options, array $flagList)
|
||||
public function run(Params $params, IO $io) : void
|
||||
{
|
||||
$id = $options['id'] ?? null;
|
||||
$filePath = $options['file'] ?? null;
|
||||
$paramsId = $options['paramsId'] ?? null;
|
||||
$id = $params->getOption('id');
|
||||
$filePath = $params->getOption('file');
|
||||
$paramsId = $params->getOption('paramsId');
|
||||
|
||||
$service = $this->serviceFactory->create('Import');
|
||||
|
||||
$forceResume = in_array('resume', $flagList);
|
||||
$revert = in_array('revert', $flagList);
|
||||
$forceResume = $params->hasFlag('resume');
|
||||
$revert = $params->hasFlag('revert');
|
||||
|
||||
if (!$id && $filePath) {
|
||||
if (!$paramsId) {
|
||||
$this->out("You need to specify --params-id option.\n");
|
||||
$io->writeLine("You need to specify --params-id option.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$this->out("File not found.\n");
|
||||
if (!$this->fileManager->isFile($filePath)) {
|
||||
$io->writeLine("File not found.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$contents = file_get_contents($filePath);
|
||||
$contents = $this->fileManager->getContents($filePath);
|
||||
|
||||
try {
|
||||
$result = $service->importFileWithParamsId($contents, $paramsId);
|
||||
$result = $this->service->importContentsWithParamsId($contents, $paramsId);
|
||||
|
||||
$resultId = $result->id;
|
||||
$countCreated = $result->countCreated;
|
||||
$countUpdated = $result->countUpdated;
|
||||
$resultId = $result->getId();
|
||||
$countCreated = $result->getCountCreated();
|
||||
$countUpdated = $result->getCountUpdated();
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: ".$e->getMessage()."\n");
|
||||
$io->writeLine("Error occurred: ". $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Finished. Import ID: {$resultId}. Created: {$countCreated}. Updated: {$countUpdated}.\n");
|
||||
$io->writeLine("Finished. Import ID: {$resultId}. Created: {$countCreated}. Updated: {$countUpdated}.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id && $revert) {
|
||||
$this->out("Reverting import...\n");
|
||||
$io->writeLine("Reverting import...");
|
||||
|
||||
try {
|
||||
$service->revert($id);
|
||||
$this->service->revert($id);
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: " . $e->getMessage() . "\n");
|
||||
$io->writeLine("Error occurred: " . $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Finished.\n");
|
||||
$io->writeLine("Finished.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$this->out("Running import, this may take a while...\n");
|
||||
$io->writeLine("Running import, this may take a while...");
|
||||
|
||||
try {
|
||||
$result = $service->importById($id, true, $forceResume);
|
||||
$result = $this->service->importById($id, true, $forceResume);
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->out("Error occured: " . $e->getMessage() . "\n");
|
||||
$io->writeLine("Error occurred: " . $e->getMessage() . "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$countCreated = $result->countCreated;
|
||||
$countUpdated = $result->countUpdated;
|
||||
$countCreated = $result->getCountCreated();
|
||||
$countUpdated = $result->getCountUpdated();
|
||||
|
||||
$this->out("Finished. Created: {$countCreated}. Updated: {$countUpdated}.\n");
|
||||
$io->writeLine("Finished. Created: {$countCreated}. Updated: {$countUpdated}.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->out("Not enough params passed.\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected function out($string)
|
||||
{
|
||||
fwrite(\STDOUT, $string);
|
||||
$io->writeLine("Not enough params passed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,32 +33,32 @@ use Espo\Core\Utils\Metadata;
|
||||
|
||||
class DefaultSidePanelType
|
||||
{
|
||||
protected $metadata;
|
||||
private $metadata;
|
||||
|
||||
public function __construct(Metadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function get(string $scope) : array
|
||||
/**
|
||||
* @return \stdClass[]
|
||||
*/
|
||||
public function get(string $scope): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
if (
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUser', 'type']) === 'link'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUser', 'type']) === 'link' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'assignedUser', 'entity']) === 'User'
|
||||
||
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUsers', 'type']) === 'linkMultiple'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'assignedUsers', 'type']) === 'linkMultiple' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'assignedUsers', 'entity']) === 'User'
|
||||
) {
|
||||
$list[] = (object) ['name' => ':assignedUser'];
|
||||
}
|
||||
|
||||
if (
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'teams', 'type']) === 'linkMultiple'
|
||||
&&
|
||||
$this->metadata->get(['entityDefs', $scope, 'fields', 'teams', 'type']) === 'linkMultiple' &&
|
||||
$this->metadata->get(['entityDefs', $scope, 'links', 'teams', 'entity']) === 'Team'
|
||||
) {
|
||||
$list[] = (object) ['name' => 'teams'];
|
||||
|
||||
@@ -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 [];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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::HAS_MANY) {
|
||||
$valueMap->{$field . 'Ids'} = [];
|
||||
$valueMap->{$field . 'Names'} = (object) [];
|
||||
$valueMap->{$field . 'Columns'} = (object) [];
|
||||
}
|
||||
|
||||
return $valueMap;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
use Espo\Entities\EmailAddress;
|
||||
use Espo\Entities\Email;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
Mail\Event\Event as EspoEvent,
|
||||
Mail\Event\EventFactory,
|
||||
Utils\Log,
|
||||
};
|
||||
|
||||
use ICal\ICal;
|
||||
use ICal\Event;
|
||||
|
||||
use Throwable;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class IcsDataLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $log;
|
||||
|
||||
/**
|
||||
* @var array<string,string>
|
||||
*/
|
||||
private $entityTypeLinkMap = [
|
||||
'User' => 'users',
|
||||
'Contact' => 'contacts',
|
||||
'Lead' => 'leads',
|
||||
];
|
||||
|
||||
public function __construct(EntityManager $entityManager, Log $log)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$icsContents = $entity->get('icsContents');
|
||||
|
||||
if ($icsContents === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ical = new ICal();
|
||||
|
||||
$ical->initString($icsContents);
|
||||
|
||||
/* @var $event Event */
|
||||
$event = $ical->events()[0] ?? null;
|
||||
|
||||
if ($event === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->status === 'CANCELLED') {
|
||||
return;
|
||||
}
|
||||
|
||||
$espoEvent = EventFactory::createFromU01jmg3Ical($ical);
|
||||
|
||||
$valueMap = (object) [
|
||||
'sourceEmailId' => $entity->getId(),
|
||||
];
|
||||
|
||||
try {
|
||||
$valueMap->name = $espoEvent->getName();
|
||||
$valueMap->description = $espoEvent->getDescription();
|
||||
$valueMap->dateStart = $espoEvent->getDateStart();
|
||||
$valueMap->dateEnd = $espoEvent->getDateEnd();
|
||||
$valueMap->location = $espoEvent->getLocation();
|
||||
$valueMap->isAllDay = $espoEvent->isAllDay();
|
||||
|
||||
if ($espoEvent->isAllDay()) {
|
||||
$valueMap->dateStartDate = $espoEvent->getDateStart();
|
||||
$valueMap->dateEndDate = $espoEvent->getDateEnd();
|
||||
}
|
||||
}
|
||||
catch (Throwable $e) {
|
||||
$this->log->warning("Error while converting ICS event '" . $entity->getId() . "': " . $e->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var EmailAddressRepository $emailAddressRepository */
|
||||
$emailAddressRepository = $this->entityManager->getRepository(EmailAddress::ENTITY_TYPE);
|
||||
|
||||
$attendeeEmailAddressList = $espoEvent->getAttendeeEmailAddressList();
|
||||
|
||||
$organizerEmailAddress = $espoEvent->getOrganizerEmailAddress();
|
||||
|
||||
if ($organizerEmailAddress) {
|
||||
$attendeeEmailAddressList[] = $organizerEmailAddress;
|
||||
}
|
||||
|
||||
foreach ($attendeeEmailAddressList as $address) {
|
||||
$personEntity = $emailAddressRepository->getEntityByAddress($address);
|
||||
|
||||
if (!$personEntity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$link = $this->entityTypeLinkMap[$personEntity->getEntityType()] ?? null;
|
||||
|
||||
if (!$link) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$idsAttribute = $link . 'Ids';
|
||||
$namesAttribute = $link . 'Names';
|
||||
|
||||
$idList = $valueMap->$idsAttribute ?? [];
|
||||
$nameMap = $valueMap->$namesAttribute ?? (object) [];
|
||||
|
||||
$idList[] = $personEntity->getId();
|
||||
$nameMap->{$personEntity->getId()} = $personEntity->get('name');
|
||||
|
||||
$valueMap->$idsAttribute = $idList;
|
||||
$valueMap->$namesAttribute = $nameMap;
|
||||
}
|
||||
|
||||
$eventData = (object) [
|
||||
'valueMap' => $valueMap,
|
||||
'uid' => $espoEvent->getUid(),
|
||||
'createdEvent' => null,
|
||||
];
|
||||
|
||||
$this->loadCreatedEvent($entity, $espoEvent, $eventData);
|
||||
|
||||
$entity->set('icsEventData', $eventData);
|
||||
|
||||
$entity->set('icsEventDateStart', $espoEvent->getDateStart());
|
||||
|
||||
if ($espoEvent->isAllDay()) {
|
||||
$entity->set('icsEventDateStartDate', $espoEvent->getDateStart());
|
||||
}
|
||||
}
|
||||
|
||||
private function loadCreatedEvent(Entity $entity, EspoEvent $espoEvent, stdClass $eventData): void
|
||||
{
|
||||
$emailSameEvent = $this->entityManager
|
||||
->getRDBRepository(Email::ENTITY_TYPE)
|
||||
->where([
|
||||
'icsEventUid' => $espoEvent->getUid(),
|
||||
'id!=' => $entity->getId()
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if (!$emailSameEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!$emailSameEvent->get('createdEventId') ||
|
||||
!$emailSameEvent->get('createdEventType')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$createdEvent = $this->entityManager
|
||||
->getEntity($emailSameEvent->get('createdEventType'), $emailSameEvent->get('createdEventId'));
|
||||
|
||||
if (!$createdEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$eventData->createdEvent = (object) [
|
||||
'id' => $createdEvent->getId(),
|
||||
'entityType' => $emailSameEvent->getEntityType(),
|
||||
'name' => $createdEvent->get('name'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\User;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class StringDataLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var array<string,string>
|
||||
*/
|
||||
private $fromEmailAddressNameCache = [];
|
||||
|
||||
public function __construct(EntityManager $entityManager, User $user)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Email $entity */
|
||||
|
||||
$userEmailAdddressIdList = [];
|
||||
|
||||
$emailAddressCollection = $this->entityManager
|
||||
->getRDBRepository('User')
|
||||
->getRelation($this->user, 'emailAddresses')
|
||||
->select(['id'])
|
||||
->find();
|
||||
|
||||
foreach ($emailAddressCollection as $emailAddress) {
|
||||
$userEmailAdddressIdList[] = $emailAddress->getId();
|
||||
}
|
||||
|
||||
if (
|
||||
in_array($entity->get('fromEmailAddressId'), $userEmailAdddressIdList) ||
|
||||
$entity->get('createdById') === $this->user->getId() && $entity->get('status') === Email::STATUS_SENT
|
||||
) {
|
||||
$entity->loadLinkMultipleField('toEmailAddresses');
|
||||
|
||||
$idList = $entity->get('toEmailAddressesIds');
|
||||
$names = $entity->get('toEmailAddressesNames');
|
||||
|
||||
if (empty($idList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($idList as $emailAddressId) {
|
||||
$person = $this->getEmailAddressRepository()->getEntityByAddressId($emailAddressId, null, true);
|
||||
|
||||
$list[] = $person ? $person->get('name') : $names->$emailAddressId;
|
||||
}
|
||||
|
||||
$entity->set('personStringData', 'To: ' . implode(', ', $list));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var ?string */
|
||||
$fromEmailAddressId = $entity->get('fromEmailAddressId');
|
||||
|
||||
if (!$fromEmailAddressId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!array_key_exists($fromEmailAddressId, $this->fromEmailAddressNameCache)) {
|
||||
$person = $this->getEmailAddressRepository()->getEntityByAddressId($fromEmailAddressId, null, true);
|
||||
|
||||
$fromName = $person ? $person->get('name') : null;
|
||||
|
||||
$this->fromEmailAddressNameCache[$fromEmailAddressId] = $fromName;
|
||||
}
|
||||
|
||||
$fromName =
|
||||
$this->fromEmailAddressNameCache[$fromEmailAddressId] ??
|
||||
$entity->get('fromName') ??
|
||||
$entity->get('fromEmailAddressName');
|
||||
|
||||
$entity->set('personStringData', $fromName);
|
||||
}
|
||||
|
||||
private function getEmailAddressRepository(): EmailAddressRepository
|
||||
{
|
||||
/** @var EmailAddressRepository */
|
||||
return $this->entityManager->getRepository('EmailAddress');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Entities\User;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Email>
|
||||
*/
|
||||
class UserColumnsLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $user;
|
||||
|
||||
public function __construct(EntityManager $entityManager, User $user)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$emailUser = $this->entityManager
|
||||
->getRDBRepository('EmailUser')
|
||||
->select(['isRead', 'isImportant', 'inTrash'])
|
||||
->where([
|
||||
'deleted' => false,
|
||||
'userId' => $this->user->getId(),
|
||||
'emailId' => $entity->getId(),
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if (!$emailUser) {
|
||||
$entity->set('isRead', null);
|
||||
$entity->clear('isImportant');
|
||||
$entity->clear('inTrash');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$entity->set([
|
||||
'isRead' => $emailUser->get('isRead'),
|
||||
'isImportant' => $emailUser->get('isImportant'),
|
||||
'inTrash' => $emailUser->get('inTrash'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Import;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
use Espo\Repositories\Import as ImportRepository;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Import>
|
||||
*/
|
||||
class CountsLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var ImportRepository $repository */
|
||||
$repository = $this->entityManager->getRepository('Import');
|
||||
|
||||
$importedCount = $repository->countResultRecords($entity, 'imported');
|
||||
$duplicateCount = $repository->countResultRecords($entity, 'duplicates');
|
||||
$updatedCount = $repository->countResultRecords($entity, 'updated');
|
||||
|
||||
$entity->set([
|
||||
'importedCount' => $importedCount,
|
||||
'duplicateCount' => $duplicateCount,
|
||||
'updatedCount' => $updatedCount,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Note;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
};
|
||||
|
||||
use Espo\Entities\Note;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Note>
|
||||
*/
|
||||
class AttachmentsLoader implements Loader
|
||||
{
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Note $entity */
|
||||
$entity->loadAttachments();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\Portal;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Repositories\Portal as PortalRepository;
|
||||
use Espo\Entities\Portal;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
};
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\Portal>
|
||||
*/
|
||||
class UrlLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
/** @var Portal $entity */
|
||||
|
||||
$this->getPortalRepository()->loadUrlField($entity);
|
||||
}
|
||||
|
||||
private function getPortalRepository(): PortalRepository
|
||||
{
|
||||
/** @var PortalRepository */
|
||||
return $this->entityManager->getRepository('Portal');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldProcessing\User;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader,
|
||||
FieldProcessing\Loader\Params,
|
||||
ORM\EntityManager,
|
||||
Acl,
|
||||
Acl\Table,
|
||||
};
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @implements Loader<\Espo\Entities\User>
|
||||
*/
|
||||
class LastAccessLoader implements Loader
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
private $acl;
|
||||
|
||||
public function __construct(EntityManager $entityManager, Acl $acl)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
$this->acl = $acl;
|
||||
}
|
||||
|
||||
public function process(Entity $entity, Params $params): void
|
||||
{
|
||||
$forbiddenFieldList = $this->acl
|
||||
->getScopeForbiddenFieldList($entity->getEntityType(), Table::ACTION_READ);
|
||||
|
||||
if (in_array('lastAccess', $forbiddenFieldList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$authToken = $this->entityManager
|
||||
->getRDBRepository('AuthToken')
|
||||
->select(['id', 'lastAccess'])
|
||||
->where([
|
||||
'userId' => $entity->getId(),
|
||||
])
|
||||
->order('lastAccess', 'DESC')
|
||||
->findOne();
|
||||
|
||||
$lastAccess = null;
|
||||
|
||||
if ($authToken) {
|
||||
$lastAccess = $authToken->get('lastAccess');
|
||||
}
|
||||
|
||||
$dt = null;
|
||||
|
||||
if ($lastAccess) {
|
||||
try {
|
||||
$dt = new DateTime($lastAccess);
|
||||
}
|
||||
catch (Exception $e) {}
|
||||
}
|
||||
|
||||
$where = [
|
||||
'userId' => $entity->getId(),
|
||||
'isDenied' => false,
|
||||
];
|
||||
|
||||
if ($dt) {
|
||||
$where['requestTime>'] = $dt->format('U');
|
||||
}
|
||||
|
||||
$authLogRecord = $this->entityManager
|
||||
->getRDBRepository('AuthLogRecord')
|
||||
->select(['id', 'createdAt'])
|
||||
->where($where)
|
||||
->order('requestTime', true)
|
||||
->findOne();
|
||||
|
||||
if ($authLogRecord) {
|
||||
$lastAccess = $authLogRecord->get('createdAt');
|
||||
}
|
||||
|
||||
$entity->set('lastAccess', $lastAccess);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,22 +31,31 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class ArrayType extends BaseType
|
||||
use StdClass;
|
||||
|
||||
class ArrayType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMaxCount(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkMaxCount(Entity $entity, string $field, int $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (count($list) > $validationValue) return false;
|
||||
|
||||
if (count($list) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkArray(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function rawCheckArray(StdClass $data, string $field): bool
|
||||
{
|
||||
if (isset($data->$field) && $data->$field !== null && !is_array($data->$field)) {
|
||||
return false;
|
||||
@@ -55,12 +64,22 @@ class ArrayType extends BaseType
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return false;
|
||||
if (!$entity->has($field) || $entity->get($field) === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (!is_array($list)) return false;
|
||||
if (count($list)) return true;
|
||||
|
||||
if (!is_array($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,7 +33,7 @@ use Espo\ORM\Entity;
|
||||
|
||||
class CurrencyType extends FloatType
|
||||
{
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return
|
||||
$entity->has($field) && $entity->get($field) !== null &&
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,14 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class DateType extends BaseType
|
||||
class DateType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -33,15 +33,21 @@ use Espo\ORM\Entity;
|
||||
|
||||
class DatetimeOptionalType extends DatetimeType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($entity->has($field) && $entity->get($field) !== null) return true;
|
||||
if ($entity->has($field . 'Date') && $entity->get($field . 'Date') !== null) return true;
|
||||
if ($entity->has($field) && $entity->get($field) !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->has($field . 'Date') && $entity->get($field . 'Date') !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Classes\FieldValidators\Email;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailAddresses
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($entity->get('status') === 'Draft') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
private function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,46 +31,61 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EmailType extends BaseType
|
||||
class EmailType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) return true;
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (!is_array($dataList)) return false;
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (!empty($item->emailAddress)) return true;
|
||||
if (!empty($item->emailAddress)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkEmailAddress(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkEmailAddress(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
$address = $entity->get($field);
|
||||
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (is_array($dataList)) {
|
||||
foreach ($dataList as $item) {
|
||||
if (empty($item->emailAddress)) continue;
|
||||
$address = $item->emailAddress;
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (empty($item->emailAddress)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$address = $item->emailAddress;
|
||||
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,14 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class EnumType extends BaseType
|
||||
class EnumType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,28 +31,46 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class IntType extends BaseType
|
||||
class IntType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMax(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
/**
|
||||
* @param mixed $validationValue
|
||||
*/
|
||||
public function checkMax(Entity $entity, string $field, $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if ($entity->get($field) > $validationValue) return false;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get($field) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkMin(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
/**
|
||||
* @param mixed $validationValue
|
||||
*/
|
||||
public function checkMin(Entity $entity, string $field, $validationValue): bool
|
||||
{
|
||||
if (!$this->isNotEmpty($entity, $field)) return true;
|
||||
if ($entity->get($field) < $validationValue) return false;
|
||||
if (!$this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($entity->get($field) < $validationValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,21 +31,35 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class JsonArrayType extends BaseType
|
||||
{
|
||||
public function checkArray(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return true;
|
||||
use StdClass;
|
||||
|
||||
return is_array($entity->get($field));
|
||||
class JsonArrayType
|
||||
{
|
||||
public function rawCheckArray(StdClass $data, string $field): bool
|
||||
{
|
||||
if (isset($data->$field) && $data->$field !== null && !is_array($data->$field)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
if (!$entity->has($field) || $entity->get($field) === null) return false;
|
||||
if (!$entity->has($field) || $entity->get($field) === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$list = $entity->get($field);
|
||||
if (!is_array($list)) return false;
|
||||
if (count($list)) return true;
|
||||
|
||||
if (!is_array($list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($list)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -30,11 +30,19 @@
|
||||
namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\Core\ORM\Entity as CoreEntity;
|
||||
|
||||
class LinkMultipleType extends BaseType
|
||||
class LinkMultipleType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return count($entity->getLinkMultipleIdList($field)) > 0;
|
||||
if (!$entity instanceof CoreEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var string[] */
|
||||
$idList = $entity->getLinkMultipleIdList($field);
|
||||
|
||||
return count($idList) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,14 +31,18 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class LinkParentType extends BaseType
|
||||
class LinkParentType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$idAttribute = $field . 'Id';
|
||||
$typeAttribute = $field . 'Type';
|
||||
|
||||
if (!$entity->has($idAttribute) || $entity->get($idAttribute) === '' || $entity->get($idAttribute) === null) {
|
||||
if (
|
||||
!$entity->has($idAttribute) ||
|
||||
$entity->get($idAttribute) === '' ||
|
||||
$entity->get($idAttribute) === null
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,9 +31,9 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class LinkType extends BaseType
|
||||
class LinkType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$idAttribute = $field . 'Id';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,21 +31,41 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PersonNameType extends BaseType
|
||||
use Espo\Core\{
|
||||
Utils\FieldUtil,
|
||||
};
|
||||
|
||||
class PersonNameType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
private $fieldUtil;
|
||||
|
||||
public function __construct(FieldUtil $fieldUtil)
|
||||
{
|
||||
$this->fieldUtil = $fieldUtil;
|
||||
}
|
||||
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
$isEmpty = true;
|
||||
foreach ($this->getActualAttributeList($entity, $field) as $attribute) {
|
||||
|
||||
$attributeList = $this->fieldUtil->getActualAttributeList($entity->getEntityType(), $field);
|
||||
|
||||
foreach ($attributeList as $attribute) {
|
||||
if ($attribute === 'salutation' . ucfirst($field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($entity->has($attribute) && $entity->get($attribute) !== '') {
|
||||
$isEmpty = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isEmpty) return false;
|
||||
|
||||
if ($isEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,23 +31,30 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class PhoneType extends BaseType
|
||||
class PhoneType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) return true;
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$dataList = $entity->get($field . 'Data');
|
||||
if (!is_array($dataList)) return false;
|
||||
|
||||
if (!is_array($dataList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($dataList as $item) {
|
||||
if (!empty($item->phoneNumber)) return true;
|
||||
if (!empty($item->phoneNumber)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
@@ -31,25 +31,27 @@ namespace Espo\Classes\FieldValidators;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class VarcharType extends BaseType
|
||||
class VarcharType
|
||||
{
|
||||
public function checkRequired(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkRequired(Entity $entity, string $field): bool
|
||||
{
|
||||
return $this->isNotEmpty($entity, $field);
|
||||
}
|
||||
|
||||
public function checkMaxLength(Entity $entity, string $field, $validationValue, $data) : bool
|
||||
public function checkMaxLength(Entity $entity, string $field, int $validationValue): bool
|
||||
{
|
||||
if ($this->isNotEmpty($entity, $field)) {
|
||||
$value = $entity->get($field);
|
||||
|
||||
if (mb_strlen($value) > $validationValue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isNotEmpty(Entity $entity, $field)
|
||||
protected function isNotEmpty(Entity $entity, string $field): bool
|
||||
{
|
||||
return $entity->has($field) && $entity->get($field) !== '' && $entity->get($field) !== null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<?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\JobPreparators;
|
||||
|
||||
use Espo\Core\Utils\DateTime;
|
||||
use Espo\Core\Job\Job\Status;
|
||||
use Espo\Core\Job\Preparator;
|
||||
use Espo\Core\Job\Preparator\Data;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Entities\Job as JobEntity;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
class CheckEmailAccounts implements Preparator
|
||||
{
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function prepare(Data $data, DateTimeImmutable $executeTime): void
|
||||
{
|
||||
$collection = $this->entityManager
|
||||
->getRDBRepository('EmailAccount')
|
||||
->join('assignedUser', 'assignedUserAdditional')
|
||||
->where([
|
||||
'status' => 'Active',
|
||||
'useImap' => true,
|
||||
'assignedUserAdditional.isActive' => true,
|
||||
])
|
||||
->find();
|
||||
|
||||
foreach ($collection as $entity) {
|
||||
$running = $this->entityManager
|
||||
->getRDBRepository(JobEntity::ENTITY_TYPE)
|
||||
->where([
|
||||
'scheduledJobId' => $data->getId(),
|
||||
'status' => [
|
||||
Status::RUNNING,
|
||||
Status::READY,
|
||||
],
|
||||
'targetType' => 'EmailAccount',
|
||||
'targetId' => $entity->getId(),
|
||||
])
|
||||
->findOne();
|
||||
|
||||
if ($running) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$countPending = $this->entityManager
|
||||
->getRDBRepository(JobEntity::ENTITY_TYPE)
|
||||
->where([
|
||||
'scheduledJobId' => $data->getId(),
|
||||
'status' => Status::PENDING,
|
||||
'targetType' => 'EmailAccount',
|
||||
'targetId' => $entity->getId(),
|
||||
])
|
||||
->count();
|
||||
|
||||
if ($countPending > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$jobEntity = $this->entityManager->getNewEntity(JobEntity::ENTITY_TYPE);
|
||||
|
||||
$jobEntity->set([
|
||||
'name' => $data->getName(),
|
||||
'scheduledJobId' => $data->getId(),
|
||||
'executeTime' => $executeTime->format(DateTime::SYSTEM_DATE_TIME_FORMAT),
|
||||
'targetType' => 'EmailAccount',
|
||||
'targetId' => $entity->getId(),
|
||||
]);
|
||||
|
||||
$this->entityManager->saveEntity($jobEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user