Compare commits
635 Commits
shift-9188
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b3f65be11 | |||
| 169232766f | |||
| 64ab9a1d56 | |||
| b6dd4bfca5 | |||
| 205b7a9f48 | |||
| 2d6759e668 | |||
| 7599291257 | |||
| 5a3f489263 | |||
| 3ef4075aa7 | |||
| 0772010119 | |||
|
|
c432b32d08 | ||
|
|
8cf628153c | ||
|
|
ab0bd9e7d9 | ||
|
|
51cd70f2ec | ||
| 235d4e3784 | |||
|
|
dd0bbad18f | ||
| f32059c3e7 | |||
|
|
92578ef738 | ||
| 367205f955 | |||
| 1fdf36669f | |||
|
|
dfa06b148f | ||
|
|
139b437118 | ||
| 4dca636359 | |||
| 4f1d2a179b | |||
|
|
ede28f375a | ||
|
|
06dfb8d7f6 | ||
| 2d4090922f | |||
| 3d58a09c21 | |||
| 05da5f016c | |||
|
|
256eead944 | ||
|
|
dcb8ffaa0d | ||
|
|
def671dd47 | ||
| 717f360952 | |||
|
|
1c0b91f52c | ||
| c733d39d30 | |||
| 87bdea3bba | |||
| efe80694f9 | |||
| be7e6ee400 | |||
| 319a7b27c5 | |||
| dbe20ac724 | |||
|
|
dc6ed3f43a | ||
| ecddb5c6d3 | |||
| 34e5a37e24 | |||
| eaca6bcc72 | |||
|
|
bad588d4b2 | ||
|
|
d5daf20351 | ||
|
|
f512ab96fc | ||
|
|
0cfa9a5483 | ||
|
|
979f934f22 | ||
|
|
1fa5820550 | ||
| 8233afa825 | |||
| ba6f67798d | |||
| daabbaa3e4 | |||
| caa68b24d6 | |||
| 114db744b4 | |||
| 8c910ed5f3 | |||
| 1ef4332df6 | |||
| 6e98269a0b | |||
|
|
c918b91438 | ||
| 2a1e634b34 | |||
|
|
d45165d759 | ||
| a0a885e004 | |||
| 52f7070311 | |||
| e0650da5e9 | |||
| bf5cf3bce4 | |||
| 07d1dc4955 | |||
| 11db41b900 | |||
| 3bca959d49 | |||
| 3fee673314 | |||
| 3121d12f3a | |||
| b8731c3f37 | |||
| b445a42896 | |||
| dbab224a9d | |||
| 03f9659243 | |||
| 0fb56133ff | |||
| afa7ca629c | |||
| 9a9c382d7f | |||
| 518b8d67bc | |||
| ff0f8194e0 | |||
| f84f982c29 | |||
| 420d81866c | |||
| 1cd78ce93a | |||
| 7cae8af89a | |||
| 5088cea413 | |||
| d670d52083 | |||
| 004aa116fb | |||
| 32a08e1e10 | |||
| 30d39c5326 | |||
| 8affea3360 | |||
| 3b6b4dc388 | |||
| 9a9e75d96d | |||
| ad6e4f0a23 | |||
| f66bc6d8aa | |||
| 845bb4763b | |||
| e476b203c7 | |||
| dd163630cb | |||
| 5d8a5ede7d | |||
| 35ccb03c2b | |||
| f6df068787 | |||
| b60a3601cb | |||
| 8676844930 | |||
| 7e80e19eec | |||
| e21c7ce1d0 | |||
| 42f2baca5e | |||
| d9c0c8f1d8 | |||
| b98e184d32 | |||
| f764466199 | |||
| 6adfd9f3fa | |||
| dbf9db1c92 | |||
| 6cb7a8cb43 | |||
| 2913960bcb | |||
| 8d0382a279 | |||
| aa5ef50ed0 | |||
| d87b869633 | |||
| 99782bdf67 | |||
| 6fa459e88e | |||
| 954f2beea7 | |||
| f216413a23 | |||
| 63572a2740 | |||
| aeb7595166 | |||
| f507d198a7 | |||
| 9b5166c570 | |||
| 2271aae557 | |||
| 8ed07e539f | |||
| b029574fa5 | |||
| e9d903ce79 | |||
| 1c9100e5de | |||
| 1a59ac955d | |||
| 4d8e58f920 | |||
|
|
55ce8e0d9e | ||
|
|
0d1a3f8dbf | ||
|
|
9687a3c7a8 | ||
|
|
471534021e | ||
| 8c75abf16a | |||
| 472abaf30b | |||
| 35426e1189 | |||
| 6507d57424 | |||
| 4252878019 | |||
|
|
8451cc1547 | ||
|
|
70ecefb007 | ||
| 4e7be1a18c | |||
| d1cc468dfa | |||
| 484512f2c7 | |||
| 83b4df3462 | |||
| 8ea46b4ea8 | |||
| a68faa11b0 | |||
| 541cd93c99 | |||
| c5a7982945 | |||
| 5cee36453e | |||
| 47ea87b614 | |||
| 4ad0df2c39 | |||
| f2ff8398eb | |||
| 3f915d6964 | |||
| 3e6a9da0d1 | |||
|
|
ca5f4ffd84 | ||
|
|
b66f9f79d2 | ||
|
|
dc0bfe6d7a | ||
|
|
5de463bd02 | ||
|
|
f3d858d785 | ||
|
|
0e537a6b46 | ||
| 8d78b15751 | |||
|
|
e1fc2fa271 | ||
|
|
27466ad3a6 | ||
|
|
f0d63b4120 | ||
|
|
163dd98b7b | ||
| 8610a1678d | |||
|
|
d20c7832da | ||
|
|
fcba4015ed | ||
|
|
bb34a3c33a | ||
|
|
dbded3ba14 | ||
|
|
3a654e0480 | ||
|
|
4b358fba4f | ||
|
|
5aaeab686d | ||
|
|
5ff0a4e86f | ||
|
|
0c866ed009 | ||
|
|
f09bf02c10 | ||
|
|
ee2c30f938 | ||
|
|
82f28bc712 | ||
|
|
8020baf9d1 | ||
|
|
b1cac44432 | ||
|
|
ab46b6118d | ||
|
|
52a1bfe804 | ||
|
|
c7c5b5298c | ||
|
|
4c07917542 | ||
|
|
fe06a2dd55 | ||
| 143f002ead | |||
| 83c0ae5841 | |||
| 0c05386804 | |||
| 9a70d4de0d | |||
| 8950b5f50b | |||
| 59e077fd6a | |||
| c9fc5b2157 | |||
| e128bcfaf9 | |||
| 7cf6b0bba6 | |||
| c36d4783e7 | |||
| 29acd76051 | |||
| eacf33b642 | |||
| 46666db231 | |||
| 3dfa753f33 | |||
| 41ae64a8c9 | |||
| fcf5400f71 | |||
| 2257736ad9 | |||
| 147b55ae78 | |||
| 5b6c951dc0 | |||
| 0840d65011 | |||
| 6394234960 | |||
| e1dde655cb | |||
| e01d59cbd8 | |||
| 22d1e195ed | |||
| c776e7b102 | |||
|
|
3cd95a5a6b | ||
| aba7845a4b | |||
| f23c4c42b5 | |||
| 05149dc723 | |||
| a615c9d1d8 | |||
| eed9ac8ff4 | |||
| 258e7fe307 | |||
| a49a86a597 | |||
| b01c5d57c7 | |||
| 4b0c113941 | |||
| 277a0ae2e3 | |||
| a61aafdc6a | |||
| 3a2899f913 | |||
| 05b172cd47 | |||
| 351259909c | |||
| 0af44ffe02 | |||
| 06799a90b0 | |||
| c7fc9a1480 | |||
| d5b8a89776 | |||
| eada83aaf8 | |||
| 9a63a9de80 | |||
| b4859fd97f | |||
| 794a18cfa0 | |||
| 581b732b05 | |||
| 0119875d22 | |||
| 0f34c7dfb9 | |||
| 04be7fdb3c | |||
| 123d45d172 | |||
|
|
864ae189af | ||
|
|
13b2620d2e | ||
|
|
75c4ad73ed | ||
|
|
2c2f5621df | ||
|
|
855accab4f | ||
|
|
afaa702a02 | ||
|
|
15637d398e | ||
|
|
f346625bb1 | ||
| 9764fef01c | |||
| 338d6c6f9d | |||
| 9da6f39e6e | |||
| 5759794f71 | |||
| ee9d96a5bf | |||
| 9197a86670 | |||
| 64e45b1892 | |||
| 6890a0939d | |||
| 61c78534d8 | |||
| 5a611f96a8 | |||
| 3e7f34d5c4 | |||
|
|
78d16bec5f | ||
| 33f658e088 | |||
| 0b46c34abe | |||
| f1ad20cb0b | |||
| 511da54909 | |||
| 104407646c | |||
| 622229cfc9 | |||
| f50e6ad209 | |||
| d7529cef80 | |||
|
|
f7432158e1 | ||
|
|
2df6597771 | ||
| 60a15c2227 | |||
| a369db9ca1 | |||
|
|
ac35d61ae2 | ||
| 489668a2ff | |||
| c9087d5df4 | |||
| ac06b3700c | |||
| 31578f5ed3 | |||
| 9b178ade4b | |||
| 92522b5494 | |||
| ccebb4eb73 | |||
| 16873e7477 | |||
| 79318e2f28 | |||
| f44a4f5d9d | |||
| b28925079b | |||
| cbf6803812 | |||
|
|
a0e804aa62 | ||
| d1b87bd64b | |||
| 5b783035a3 | |||
| a06363da75 | |||
| a68c691f75 | |||
|
|
8a61d258fb | ||
|
|
fd3f220752 | ||
|
|
0a0b2927ae | ||
|
|
4c19773818 | ||
|
|
071af03577 | ||
|
|
58da0b54b3 | ||
|
|
528ea4bcfb | ||
|
|
ca124d34cd | ||
| 70b53ce21a | |||
| 6dc226ab0b | |||
| d6524942f7 | |||
| 3ca5e81e34 | |||
| 561b5ad1b9 | |||
| 229bb9a5e0 | |||
| 280d3e9043 | |||
| a2384f4b35 | |||
| d65bf5bcd5 | |||
| e763a9140c | |||
| 3a06a375ef | |||
| bdf3f38190 | |||
| 5b2f6e44b1 | |||
| 250401fd62 | |||
| c1fb03add1 | |||
|
|
56bf7efcef | ||
| cc0508683e | |||
|
|
b232b65860 | ||
| 406d1d31c0 | |||
| f8fe5c92aa | |||
| 69623bd248 | |||
| 6d4995074b | |||
| ac94068864 | |||
| 31ed355d64 | |||
| 8a54fb272a | |||
| 6ecf807081 | |||
| 728472b897 | |||
| 30a8c8a03a | |||
| 00e7490037 | |||
| 1d152d730a | |||
| a010d91da2 | |||
| 3717248764 | |||
| 27753e903b | |||
| b621f71b54 | |||
| d4b3300b88 | |||
| 242fb9dda0 | |||
| 4f505cd155 | |||
| dca70a0f53 | |||
| b9a8c826ec | |||
| 363deb3ca7 | |||
| f77b5f7556 | |||
| d60efe38e2 | |||
| f779342e02 | |||
| 204e62b3bb | |||
| 5adc24f997 | |||
| ab25b0f64a | |||
| dd8e59cd4f | |||
| 0c4c36eb74 | |||
|
|
3481f10033 | ||
|
|
fdf61fef3d | ||
|
|
30c3c5d33f | ||
|
|
6cd7df79d9 | ||
|
|
b5b0b5d7bd | ||
|
|
d0266c7d0c | ||
|
|
283fd30c19 | ||
|
|
5d13135bd0 | ||
|
|
6c2961eef6 | ||
|
|
f9c006403e | ||
|
|
1f65f0fe30 | ||
|
|
a49a287855 | ||
| bf7f830f9e | |||
| ffce564a47 | |||
| 2cdcd9a424 | |||
| ffbc733571 | |||
| 3ea7188253 | |||
| 97c6a4c4ef | |||
| f3fe112427 | |||
| 189e4ef230 | |||
| d35b895ff4 | |||
| c47c511674 | |||
| 20be21c87d | |||
| 1d57dc519f | |||
| 644b42afe9 | |||
| 9ad11f24c2 | |||
| 1e2564f753 | |||
| f1ab544aae | |||
|
|
aa85d24952 | ||
|
|
b0f8817aae | ||
|
|
b9e3e9f5f2 | ||
|
|
ea05f5992d | ||
|
|
9c138d6bee | ||
|
|
7325880a70 | ||
|
|
320631e91d | ||
|
|
0997864cd6 | ||
|
|
9e0451d541 | ||
|
|
84245c5584 | ||
|
|
d72c0ea9f5 | ||
|
|
bf9500f960 | ||
|
|
f18cda6c00 | ||
| 0ab20a75ac | |||
| 133a6ed4ea | |||
| bc424b7a00 | |||
| be3c6d89ee | |||
| d814ed1972 | |||
| 8322229001 | |||
| da2a76d6cf | |||
|
|
abf7a2783c | ||
| 6690c69efe | |||
| 67044b7cf9 | |||
| 048d3af39b | |||
| 816989d472 | |||
| 8f6310b463 | |||
| 3cebdd838b | |||
| 9996404e29 | |||
| 1598efac35 | |||
| bfacb86f35 | |||
|
|
e5e5c7e19c | ||
|
|
9ede1d7eea | ||
| ff8cf83f1b | |||
| 326c8e7b81 | |||
| daeecfbd4f | |||
| 15c330c784 | |||
| 7ba80ccc58 | |||
| ef4efe723f | |||
| 64ef8e9acd | |||
| d88b6f6e95 | |||
| 440d66322c | |||
|
|
469a646ae3 | ||
| 9cb9ebbe4f | |||
|
|
d004855dd8 | ||
|
|
911645c9f5 | ||
|
|
6a16e78d80 | ||
| 937c5024cb | |||
|
|
7e12ba1a00 | ||
| 89d57bb915 | |||
| a111387a3f | |||
| 234fcb13af | |||
| 377fdad6e0 | |||
| 68020b0201 | |||
| f0628c5c05 | |||
| 66d2a2c48c | |||
| 6f1229418e | |||
| a430fee568 | |||
| 53b7ce651e | |||
| 1028064abe | |||
| ab285870e3 | |||
| 1a02d46151 | |||
| 1bb70bbe66 | |||
| c158155194 | |||
| 7bfd4c1198 | |||
| ea959d1a10 | |||
| 9fc5d81877 | |||
| 719aac6727 | |||
| c8398920c5 | |||
|
|
55bd914b8f | ||
|
|
2b06a52705 | ||
|
|
2c9c997d5a | ||
|
|
17f305d9cb | ||
|
|
44d071696f | ||
|
|
fa8f44135c | ||
|
|
b38e79ef8f | ||
|
|
e2e39fbdf5 | ||
|
|
a8262932cc | ||
|
|
6d3e9b3c1d | ||
|
|
b91619801d | ||
|
|
f1e32096f3 | ||
|
|
f5a327e72c | ||
| 4fe05e39f7 | |||
|
|
c3779bf371 | ||
| 54aa7e249e | |||
| 1744d192b5 | |||
| 3f7426c550 | |||
| c4e017c7b7 | |||
| e723831548 | |||
| 56b5dcd7d8 | |||
|
|
913d229630 | ||
| 3dfb11d692 | |||
| 759ab14899 | |||
| 329ff7c478 | |||
| a6022f7251 | |||
| d345be889e | |||
| 2dbe9955d9 | |||
|
|
8fcd33e0a1 | ||
| 14aa5e3b28 | |||
| 2cb9aac070 | |||
| 1c6a5c9d04 | |||
| 936aabf412 | |||
| fa7478a5b5 | |||
| 8992554ba6 | |||
| c8895137fa | |||
| f8bc75f1f9 | |||
| 43faa0f020 | |||
| 8e76a18590 | |||
| 9c1df26b4b | |||
| 6d89a499b1 | |||
| 03430c272f | |||
| baf15296ce | |||
| 56f74964ed | |||
| afad2df8f5 | |||
| d17ff1f2e7 | |||
| 4d9be34b4e | |||
|
|
5213b28c2e | ||
|
|
e0df5a53dc | ||
|
|
f13022ee1d | ||
|
|
c063badb38 | ||
|
|
693cf4cd2a | ||
| cc70b1a67f | |||
| 08d3366fe1 | |||
| 080b2fcfc4 | |||
| 5b1d02e3c1 | |||
| b322a405c7 | |||
| 0ed05b103b | |||
| 5431da3930 | |||
| 2a6e5b7992 | |||
| 85af95a8a0 | |||
| e0b04a57ae | |||
| 0533cd24fe | |||
| 9598031dd1 | |||
| 9f808717d2 | |||
| b4aa71b81b | |||
|
|
321a8f0946 | ||
|
|
93124cdad0 | ||
|
|
26eae9b1cf | ||
| f803bc0a59 | |||
| be5925f40d | |||
| b25b697e7b | |||
| 66e2a68cde | |||
| 673f6051c1 | |||
| 0478ab9eb2 | |||
| b7fde520be | |||
| 6f031f78e8 | |||
| 2f850ce152 | |||
|
|
a6240a3ca9 | ||
| 8906936e51 | |||
| fd6867740e | |||
| 183231206b | |||
| d4e832b526 | |||
| 667ff5cf94 | |||
| 6d2db21a62 | |||
| df398faddb | |||
| e07e2d2e2c | |||
| ca29189f9e | |||
|
|
15a1a3f666 | ||
|
|
8c4c09bc90 | ||
|
|
5a926d2d41 | ||
|
|
5127d8b283 | ||
|
|
c043a43fc5 | ||
|
|
013930d7c3 | ||
|
|
6b0d66be25 | ||
|
|
3b492d2005 | ||
|
|
29f4bfd3cc | ||
|
|
86e42c36cb | ||
|
|
c1d81c65d2 | ||
|
|
fd864b03d9 | ||
|
|
97eb51a434 | ||
|
|
76f9b96369 | ||
|
|
13e5cf2133 | ||
|
|
1c92f6449e | ||
|
|
3ed6cc8d5c | ||
|
|
5b79e415e0 | ||
|
|
98036c7266 | ||
|
|
8c8c59d8bd | ||
| fdbadbac7f | |||
| 9d788f919a | |||
| fac00bc4f6 | |||
| 6e511fc4a9 | |||
| 2f6214c48d | |||
| b2f791fc5f | |||
| 39140611ca | |||
| 567ee3062b | |||
| 584e0903c8 | |||
| 8990006d4c | |||
| 7feb78ba70 | |||
| d67ca133eb | |||
| f95557aa3a | |||
| f539ab7294 | |||
|
|
79284e2271 | ||
|
|
e303b565fc | ||
|
|
985e8a5cd6 | ||
|
|
541e1c4c2c | ||
|
|
10c1d500f3 | ||
|
|
678f16788c | ||
|
|
8871a1b7ae | ||
|
|
05c2f28f25 | ||
|
|
30179fe353 | ||
|
|
6846dd760d | ||
|
|
408f285cf3 | ||
|
|
fa76fc0f78 | ||
|
|
ade9cd6b05 | ||
|
|
933d18b784 | ||
| 48bae3b181 | |||
| 78f6ed1ef6 | |||
| 6d503939a5 | |||
| 3677f1c45b | |||
|
|
a23ce4e0e6 | ||
|
|
e7c43fa53a | ||
|
|
0de6735855 | ||
|
|
aa274b1df4 | ||
|
|
51261a4a5c | ||
|
|
9e92561502 | ||
| 2b28ebc014 | |||
| 196d9c358c | |||
|
|
38d58d92b4 | ||
| e136c910b5 | |||
| d0c4f7eea2 | |||
| bf9b0f3973 | |||
| 4534b46e97 | |||
| 68affe4e4c | |||
| aa2671f167 | |||
| 2178b61602 | |||
| 6a6b8ed9b2 | |||
| 784e8cf787 | |||
| 89a8b6926a | |||
| 9c926d15c1 | |||
|
|
1b1144c628 | ||
|
|
e9b1802af3 | ||
|
|
fe7c1d93ae | ||
|
|
8d1be827a7 | ||
|
|
cd4fe13117 | ||
|
|
34e169adba | ||
|
|
d064756cc6 | ||
|
|
bf7e1658f4 | ||
| 8de3c5dcba | |||
| e8827cbd50 | |||
| f839003f5e | |||
| b68d97455b | |||
|
|
e9dcb8b3f0 | ||
|
|
5e838ad61e | ||
|
|
a365977702 | ||
| 8b2542ebef | |||
|
|
69c5018367 | ||
|
|
4f536ae5a9 | ||
|
|
95395d1da7 | ||
|
|
fbf437ac99 | ||
|
|
5faf49688d | ||
|
|
4d7d0ed74d | ||
|
|
979b9f704c | ||
|
|
4124cf39db | ||
|
|
c83e21d588 | ||
|
|
c88630e9af | ||
|
|
40b265e145 | ||
|
|
3ad2b2fb8e | ||
|
|
8b671065e9 | ||
|
|
028e1a191e | ||
|
|
a133f82997 | ||
|
|
c4f3eb9a4e | ||
|
|
8a52c4529f | ||
|
|
d0493f3dd0 | ||
|
|
b845552c37 |
17
.gitignore
vendored
17
.gitignore
vendored
@@ -26,7 +26,7 @@ storage/*.key
|
|||||||
Homestead.yaml
|
Homestead.yaml
|
||||||
Homestead.json
|
Homestead.json
|
||||||
/.vagrant
|
/.vagrant
|
||||||
.phpunit.result.cache
|
/.phpunit.cache
|
||||||
|
|
||||||
### macOS ###
|
### macOS ###
|
||||||
# General
|
# General
|
||||||
@@ -237,11 +237,22 @@ dist/
|
|||||||
### This Project ###
|
### This Project ###
|
||||||
/public/uploads
|
/public/uploads
|
||||||
/public/build
|
/public/build
|
||||||
# /public/tinymce
|
|
||||||
*.key
|
*.key
|
||||||
|
|
||||||
|
### TinyMCE ###
|
||||||
|
/public/tinymce
|
||||||
|
!/public/tinymce/skins/ui/stemmech/
|
||||||
|
|
||||||
### Synk ###
|
### Synk ###
|
||||||
.dccache
|
.dccache
|
||||||
|
|
||||||
### TempCodeRunner ###
|
### TempCodeRunner ###
|
||||||
tempCodeRunnerFile.*
|
tempCodeRunnerFile.*
|
||||||
|
|
||||||
|
### PHPUnit ###
|
||||||
|
.phpunit.result.cache
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
### Codesniffer ###
|
||||||
|
phpcs.phar
|
||||||
|
phpcbf.phar
|
||||||
|
|||||||
14
.ls-lint.yml
Normal file
14
.ls-lint.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
ls:
|
||||||
|
resources/js/store:
|
||||||
|
.ts: pascalcase
|
||||||
|
"*":
|
||||||
|
.js: camelcase
|
||||||
|
.ts: camelcase
|
||||||
|
.vue: pascalcase
|
||||||
|
.dir: snakecase
|
||||||
|
.type.ts: camelcase
|
||||||
|
ignore:
|
||||||
|
- node_modules
|
||||||
|
- vendor
|
||||||
|
- public/build
|
||||||
|
- public/tinymce
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"bracketSameLine": true,
|
"bracketSameLine": true,
|
||||||
"tabWidth": 4
|
"tabWidth": 4,
|
||||||
|
"htmlWhitespaceSensitivity": "css"
|
||||||
}
|
}
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -16,5 +16,6 @@
|
|||||||
// "editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
|
// "editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
|
||||||
"editor.defaultFormatter": "wongjn.php-sniffer"
|
"editor.defaultFormatter": "wongjn.php-sniffer"
|
||||||
},
|
},
|
||||||
"cSpell.words": ["TIMESTAMPDIFF"]
|
"phpSniffer.autoDetect": true,
|
||||||
|
"phpSniffer.run": "onSave"
|
||||||
}
|
}
|
||||||
|
|||||||
67
README.md
67
README.md
@@ -1,66 +1,3 @@
|
|||||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
# TODO
|
||||||
|
|
||||||
<p align="center">
|
- Add Model JS helper (ie for confirmation to delete): https://jackwhiting.co.uk/posts/creating-a-modal-with-tailwind-and-alpine/
|
||||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## About Laravel
|
|
||||||
|
|
||||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
|
||||||
|
|
||||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
|
||||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
|
||||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
|
||||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
|
||||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
|
||||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
|
||||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
|
||||||
|
|
||||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
|
||||||
|
|
||||||
## Learning Laravel
|
|
||||||
|
|
||||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
|
||||||
|
|
||||||
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
|
||||||
|
|
||||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
|
||||||
|
|
||||||
## Laravel Sponsors
|
|
||||||
|
|
||||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
|
|
||||||
|
|
||||||
### Premium Partners
|
|
||||||
|
|
||||||
- **[Vehikl](https://vehikl.com/)**
|
|
||||||
- **[Tighten Co.](https://tighten.co)**
|
|
||||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
|
||||||
- **[64 Robots](https://64robots.com)**
|
|
||||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
|
||||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
|
||||||
- **[Many](https://www.many.co.uk)**
|
|
||||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
|
||||||
- **[DevSquad](https://devsquad.com)**
|
|
||||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
|
||||||
- **[OP.GG](https://op.gg)**
|
|
||||||
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
|
|
||||||
- **[Lendio](https://lendio.com)**
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
|
||||||
|
|
||||||
## Security Vulnerabilities
|
|
||||||
|
|
||||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
|
||||||
23355
_ide_helper.php
Normal file
23355
_ide_helper.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,16 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Conductors;
|
namespace App\Conductors;
|
||||||
|
|
||||||
use App\Models\Media;
|
|
||||||
use App\Models\User;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\InvalidCastException;
|
|
||||||
use Illuminate\Database\Eloquent\MissingAttributeException;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use LogicException;
|
|
||||||
|
|
||||||
class AnalyticsConductor extends Conductor
|
class AnalyticsConductor extends Conductor
|
||||||
{
|
{
|
||||||
@@ -19,20 +10,14 @@ class AnalyticsConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Analytics';
|
protected $class = \App\Models\AnalyticsSession::class;
|
||||||
|
|
||||||
/**
|
|
||||||
* The default sorting field
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $sort = 'created_at';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default includes to include in a request.
|
* The default includes to include in a request.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $includes = ['duration'];
|
protected $includes = ['requests.type','requests.path'];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,8 +26,9 @@ class AnalyticsConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow model to be visible.
|
* @return boolean Allow model to be visible.
|
||||||
*/
|
*/
|
||||||
public static function viewable(Model $model)
|
public static function viewable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
||||||
}
|
}
|
||||||
@@ -52,7 +38,7 @@ class AnalyticsConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Allow creating model.
|
* @return boolean Allow creating model.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -63,8 +49,9 @@ class AnalyticsConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
||||||
}
|
}
|
||||||
@@ -75,8 +62,9 @@ class AnalyticsConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
return ($user !== null && $user->hasPermission('admin/analytics') === true);
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\InvalidCastException;
|
|||||||
use Illuminate\Database\Eloquent\MissingAttributeException;
|
use Illuminate\Database\Eloquent\MissingAttributeException;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
|
||||||
class ArticleConductor extends Conductor
|
class ArticleConductor extends Conductor
|
||||||
@@ -19,7 +20,7 @@ class ArticleConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Article';
|
protected $class = \App\Models\Article::class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default sorting field
|
* The default sorting field
|
||||||
@@ -32,7 +33,7 @@ class ArticleConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $includes = ['attachments', 'user'];
|
protected $includes = ['attachments', 'user', 'gallery'];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,8 +42,9 @@ class ArticleConductor extends Conductor
|
|||||||
* @param Builder $builder The builder in use.
|
* @param Builder $builder The builder in use.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function scope(Builder $builder)
|
public function scope(Builder $builder): void
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/articles') === false) {
|
if ($user === null || $user->hasPermission('admin/articles') === false) {
|
||||||
$builder
|
$builder
|
||||||
@@ -56,9 +58,10 @@ class ArticleConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow model to be visible.
|
* @return boolean Allow model to be visible.
|
||||||
*/
|
*/
|
||||||
public static function viewable(Model $model)
|
public static function viewable(Model $model): bool
|
||||||
{
|
{
|
||||||
if (Carbon::parse($model->publish_at)->isFuture() === true) {
|
if (Carbon::parse($model->publish_at)->isFuture() === true) {
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/articles') === false) {
|
if ($user === null || $user->hasPermission('admin/articles') === false) {
|
||||||
return false;
|
return false;
|
||||||
@@ -73,8 +76,9 @@ class ArticleConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Allow creating model.
|
* @return boolean Allow creating model.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
||||||
}
|
}
|
||||||
@@ -85,8 +89,9 @@ class ArticleConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
||||||
}
|
}
|
||||||
@@ -97,8 +102,9 @@ class ArticleConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
return ($user !== null && $user->hasPermission('admin/articles') === true);
|
||||||
}
|
}
|
||||||
@@ -109,7 +115,7 @@ class ArticleConductor extends Conductor
|
|||||||
* @param array $data The model data to transform.
|
* @param array $data The model data to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
public function transformFinal(array $data)
|
public function transformFinal(array $data): array
|
||||||
{
|
{
|
||||||
unset($data['user_id']);
|
unset($data['user_id']);
|
||||||
return $data;
|
return $data;
|
||||||
@@ -123,11 +129,24 @@ class ArticleConductor extends Conductor
|
|||||||
*/
|
*/
|
||||||
public function includeAttachments(Model $model)
|
public function includeAttachments(Model $model)
|
||||||
{
|
{
|
||||||
return $model->attachments()->get()->map(function ($attachment) {
|
return $model->getAttachments()->map(function ($attachment) {
|
||||||
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
|
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include Gallery Field.
|
||||||
|
*
|
||||||
|
* @param Model $model Them model.
|
||||||
|
* @return mixed The model result.
|
||||||
|
*/
|
||||||
|
public function includeGallery(Model $model)
|
||||||
|
{
|
||||||
|
return $model->getGallery()->map(function ($item) {
|
||||||
|
return MediaConductor::includeModel(request(), 'gallery', $item->media);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include User Field.
|
* Include User Field.
|
||||||
*
|
*
|
||||||
@@ -136,17 +155,27 @@ class ArticleConductor extends Conductor
|
|||||||
*/
|
*/
|
||||||
public function includeUser(Model $model)
|
public function includeUser(Model $model)
|
||||||
{
|
{
|
||||||
return UserConductor::includeModel(request(), 'user', User::find($model['user_id']));
|
$cacheKey = "user:{$model['user_id']}";
|
||||||
|
$user = Cache::remember($cacheKey, now()->addDays(28), function () use ($model) {
|
||||||
|
return User::find($model['user_id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
return UserConductor::includeModel(request(), 'user', $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the Hero field.
|
* Transform the Hero field.
|
||||||
*
|
*
|
||||||
* @param mixed $value The current value.
|
* @param mixed $value The current value.
|
||||||
* @return array The new value.
|
* @return array|null The new value.
|
||||||
*/
|
*/
|
||||||
public function transformHero(mixed $value)
|
public function transformHero(mixed $value): array|null
|
||||||
{
|
{
|
||||||
return MediaConductor::includeModel(request(), 'hero', Media::find($value));
|
$cacheKey = "media:{$value}";
|
||||||
|
$media = Cache::remember($cacheKey, now()->addDays(28), function () use ($value) {
|
||||||
|
return Media::find($value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return MediaConductor::includeModel(request(), 'hero', $media);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Builder;
|
|||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Conductor
|
class Conductor
|
||||||
@@ -81,7 +81,7 @@ class Conductor
|
|||||||
* @param string $string The string to split.
|
* @param string $string The string to split.
|
||||||
* @return array The split string.
|
* @return array The split string.
|
||||||
*/
|
*/
|
||||||
private function splitString(string $string)
|
private function splitString(string $string): array
|
||||||
{
|
{
|
||||||
$parts = [];
|
$parts = [];
|
||||||
$start = 0;
|
$start = 0;
|
||||||
@@ -145,7 +145,7 @@ class Conductor
|
|||||||
* @param array|null $limitFields A list of fields to limit the filter request to.
|
* @param array|null $limitFields A list of fields to limit the filter request to.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function filter(Request $request, array|null $limitFields = null)
|
private function filter(Request $request, array|null $limitFields = null): void
|
||||||
{
|
{
|
||||||
if (is_array($limitFields) === true && count($limitFields) === 0) {
|
if (is_array($limitFields) === true && count($limitFields) === 0) {
|
||||||
$limitFields = null;
|
$limitFields = null;
|
||||||
@@ -164,14 +164,18 @@ class Conductor
|
|||||||
) {
|
) {
|
||||||
$value = trim($value);
|
$value = trim($value);
|
||||||
$operator = '';
|
$operator = '';
|
||||||
$join = 'OR';
|
$join = 'AND';
|
||||||
|
|
||||||
// Check if value has a operator and remove it if it's a number
|
// Check if value has a operator and remove it if it's a number
|
||||||
if (preg_match('/^(!?=|[<>]=?|<>|!)([^=!<>].*)*$/', $value, $matches) > 0) {
|
if (preg_match('/^(!?=|[<>]=?|<>|!|\|)([^=!<>].*)*$/', $value, $matches) > 0) {
|
||||||
$operator = $matches[1];
|
$operator = $matches[1];
|
||||||
$value = ($matches[2] ?? '');
|
$value = ($matches[2] ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen($value) === 0 && ($operator !== '==' && $operator !== '!=')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch ($operator) {
|
switch ($operator) {
|
||||||
case '=':
|
case '=':
|
||||||
$operator = '==';
|
$operator = '==';
|
||||||
@@ -182,15 +186,23 @@ class Conductor
|
|||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
case '<':
|
case '<':
|
||||||
|
case '|':
|
||||||
|
$separatorPos = strpos($value, '|');
|
||||||
|
if ($separatorPos !== false) {
|
||||||
|
$operator = '==';
|
||||||
|
$valueList = explode('|', $value);
|
||||||
|
foreach ($valueList as $valueItem) {
|
||||||
|
$this->appendFilter($field, $operator, $valueItem, 'OR');
|
||||||
|
}
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case '>=':
|
case '>=':
|
||||||
case '<=':
|
case '<=':
|
||||||
case '!=':
|
case '!=':
|
||||||
break;
|
break;
|
||||||
case '<>':
|
case '<>':
|
||||||
$separatorPos = strpos($value, '|');
|
$operator = '!=';
|
||||||
if ($separatorPos === false) {
|
|
||||||
$operator = '!=';
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$operator = 'LIKE';
|
$operator = 'LIKE';
|
||||||
@@ -213,13 +225,47 @@ class Conductor
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function applyFilters()
|
final public function applyFilters(): void
|
||||||
{
|
{
|
||||||
$parseFunc = function ($filterArray, $query) use (&$parseFunc) {
|
$parseFunc = function ($filterArray, $query) use (&$parseFunc) {
|
||||||
$item = null;
|
$item = null;
|
||||||
$result = null;
|
$result = null;
|
||||||
$join = 'AND';
|
$join = 'AND';
|
||||||
|
|
||||||
|
$relationFilter = [];
|
||||||
|
|
||||||
|
$buildWhereFunc = function ($query, $field, $operator, $value, $join) {
|
||||||
|
if ($join === 'OR') {
|
||||||
|
if ($operator === '<>') {
|
||||||
|
$separatorPos = strpos($value, '|');
|
||||||
|
if ($separatorPos !== false) {
|
||||||
|
$query->orWhereBetween(
|
||||||
|
$field,
|
||||||
|
[substr($value, 0, $separatorPos), substr($value, ($separatorPos + 1))]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$query->orWhere($field, '!=', $value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query->orWhere($field, $operator, $value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($operator === '<>') {
|
||||||
|
$separatorPos = strpos($value, '|');
|
||||||
|
if ($separatorPos !== false) {
|
||||||
|
$query->whereBetween(
|
||||||
|
$field,
|
||||||
|
[substr($value, 0, $separatorPos), substr($value, ($separatorPos + 1))]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$query->where($field, '!=', $value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query->where($field, $operator, $value);
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
};
|
||||||
|
|
||||||
if (gettype($query) === 'array') {
|
if (gettype($query) === 'array') {
|
||||||
$item = $query;
|
$item = $query;
|
||||||
}
|
}
|
||||||
@@ -243,81 +289,72 @@ class Conductor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list($field, $operator, $value) = $condition;
|
if (count($condition) < 3 && $condition[0] !== '') {
|
||||||
|
if (count($condition) < 2) {
|
||||||
if ($item !== null) {
|
$condition[1] = 'LIKE';
|
||||||
if (array_key_exists($field, $item) === true) {
|
|
||||||
switch ($operator) {
|
|
||||||
case '==':
|
|
||||||
$currentResult = ($item[$field] == $value);
|
|
||||||
break;
|
|
||||||
case 'NOT LIKE':
|
|
||||||
$currentResult = (stripos($item[$field], substr($value, 1, -1)) === false);
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
$currentResult = ($item[$field] > $value);
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
$currentResult = ($item[$field] < $value);
|
|
||||||
break;
|
|
||||||
case '>=':
|
|
||||||
$currentResult = ($item[$field] >= $value);
|
|
||||||
break;
|
|
||||||
case '<=':
|
|
||||||
$currentResult = ($item[$field] <= $value);
|
|
||||||
break;
|
|
||||||
case '!=':
|
|
||||||
$currentResult = ($item[$field] != $value);
|
|
||||||
break;
|
|
||||||
case '<>':
|
|
||||||
$separatorPos = strpos($value, '|');
|
|
||||||
if ($separatorPos !== false) {
|
|
||||||
$fieldInt = intval($item[$field]);
|
|
||||||
$currentResult = (
|
|
||||||
$fieldInt > intVal(
|
|
||||||
substr($value, 0, $separatorPos)
|
|
||||||
) && $fieldInt < intVal(substr($value, ($separatorPos + 1))));
|
|
||||||
} else {
|
|
||||||
$currentResult = ($item[$field] != $value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'LIKE':
|
|
||||||
$currentResult = (stripos($item[$field], substr($value, 1, -1)) !== false);
|
|
||||||
break;
|
|
||||||
}//end switch
|
|
||||||
}//end if
|
|
||||||
} else {
|
|
||||||
if ($operator === '==') {
|
|
||||||
$operator = '=';
|
|
||||||
}
|
}
|
||||||
|
$condition[2] = '%';
|
||||||
|
}
|
||||||
|
|
||||||
if ($join === 'OR') {
|
if (count($condition) === 3) {
|
||||||
if ($operator === '<>') {
|
list($field, $operator, $value) = $condition;
|
||||||
$separatorPos = strpos($value, '|');
|
|
||||||
if ($separatorPos !== false) {
|
if ($item !== null) {
|
||||||
$query->orWhereBetween(
|
if (array_key_exists($field, $item) === true) {
|
||||||
$field,
|
switch ($operator) {
|
||||||
[substr($value, 0, $separatorPos), substr($value, ($separatorPos + 1))]
|
case '==':
|
||||||
);
|
$currentResult = ($item[$field] == $value);
|
||||||
} else {
|
break;
|
||||||
$query->orWhere($field, '!=', $value);
|
case 'NOT LIKE':
|
||||||
}
|
$currentResult = (stripos($item[$field], substr($value, 1, -1)) === false);
|
||||||
} else {
|
break;
|
||||||
$query->orWhere($field, $operator, $value);
|
case '>':
|
||||||
}
|
$currentResult = ($item[$field] > $value);
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$currentResult = ($item[$field] < $value);
|
||||||
|
break;
|
||||||
|
case '>=':
|
||||||
|
$currentResult = ($item[$field] >= $value);
|
||||||
|
break;
|
||||||
|
case '<=':
|
||||||
|
$currentResult = ($item[$field] <= $value);
|
||||||
|
break;
|
||||||
|
case '!=':
|
||||||
|
$currentResult = ($item[$field] != $value);
|
||||||
|
break;
|
||||||
|
case '<>':
|
||||||
|
$separatorPos = strpos($value, '|');
|
||||||
|
if ($separatorPos !== false) {
|
||||||
|
$fieldInt = intval($item[$field]);
|
||||||
|
$currentResult = (
|
||||||
|
$fieldInt > intVal(
|
||||||
|
substr($value, 0, $separatorPos)
|
||||||
|
) && $fieldInt < intVal(substr($value, ($separatorPos + 1))));
|
||||||
|
} else {
|
||||||
|
$currentResult = ($item[$field] != $value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'LIKE':
|
||||||
|
$currentResult = (stripos($item[$field], substr($value, 1, -1)) !== false);
|
||||||
|
break;
|
||||||
|
}//end switch
|
||||||
|
}//end if
|
||||||
} else {
|
} else {
|
||||||
if ($operator === '<>') {
|
if ($operator === '==') {
|
||||||
$separatorPos = strpos($value, '|');
|
$operator = '=';
|
||||||
if ($separatorPos !== false) {
|
}
|
||||||
$query->whereBetween(
|
|
||||||
$field,
|
$relationSplit = strpos($field, '.');
|
||||||
[substr($value, 0, $separatorPos), substr($value, ($separatorPos + 1))]
|
if ($relationSplit !== false) {
|
||||||
);
|
$relation = substr($field, 0, $relationSplit);
|
||||||
} else {
|
$field = substr($field, ($relationSplit + 1));
|
||||||
$query->where($field, '!=', $value);
|
|
||||||
|
if (method_exists($this->class, $relation) === true) {
|
||||||
|
$relationFilter[$relation][] = [$field, $operator, $value, $join];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$query->where($field, $operator, $value);
|
$buildWhereFunc($query, $field, $operator, $value, $join);
|
||||||
}
|
}
|
||||||
}//end if
|
}//end if
|
||||||
}//end if
|
}//end if
|
||||||
@@ -341,6 +378,14 @@ class Conductor
|
|||||||
}//end if
|
}//end if
|
||||||
}//end foreach
|
}//end foreach
|
||||||
|
|
||||||
|
foreach ($relationFilter as $relation => $conditions) {
|
||||||
|
$query->whereHas($relation, function ($subQuery) use ($buildWhereFunc, $conditions) {
|
||||||
|
foreach ($conditions as $condition) {
|
||||||
|
$buildWhereFunc($subQuery, $condition[0], $condition[1], $condition[2], $condition[3]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -365,7 +410,7 @@ class Conductor
|
|||||||
* @param Request $request The request data.
|
* @param Request $request The request data.
|
||||||
* @return array The processed and transformed collection | the total rows found.
|
* @return array The processed and transformed collection | the total rows found.
|
||||||
*/
|
*/
|
||||||
final public static function request(Request $request)
|
final public static function request(Request $request): array
|
||||||
{
|
{
|
||||||
$conductor_class = get_called_class();
|
$conductor_class = get_called_class();
|
||||||
$conductor = new $conductor_class();
|
$conductor = new $conductor_class();
|
||||||
@@ -418,7 +463,7 @@ class Conductor
|
|||||||
return substr($field, 0, strpos($field, '.'));
|
return substr($field, 0, strpos($field, '.'));
|
||||||
}
|
}
|
||||||
return $field;
|
return $field;
|
||||||
}, explode(',', $request->input('fields')));
|
}, explode(',', $request->input('fields', '')));
|
||||||
if ($limitFields === null) {
|
if ($limitFields === null) {
|
||||||
$limitFields = $fields;
|
$limitFields = $fields;
|
||||||
} else {
|
} else {
|
||||||
@@ -457,7 +502,7 @@ class Conductor
|
|||||||
* @param Collection $collection The collection.
|
* @param Collection $collection The collection.
|
||||||
* @return array The processed and transformed model data.
|
* @return array The processed and transformed model data.
|
||||||
*/
|
*/
|
||||||
final public static function collection(Request $request, Collection $collection)
|
final public static function collection(Request $request, Collection $collection): array
|
||||||
{
|
{
|
||||||
$conductor_class = get_called_class();
|
$conductor_class = get_called_class();
|
||||||
$conductor = new $conductor_class();
|
$conductor = new $conductor_class();
|
||||||
@@ -505,7 +550,7 @@ class Conductor
|
|||||||
* @param array|null $limitFields Limit the request to these fields.
|
* @param array|null $limitFields Limit the request to these fields.
|
||||||
* @return Builder
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
public static function filterQuery(Builder $query, Request $request, array|null $limitFields = null)
|
public static function filterQuery(Builder $query, Request $request, array|null $limitFields = null): Builder
|
||||||
{
|
{
|
||||||
$conductor_class = get_called_class();
|
$conductor_class = get_called_class();
|
||||||
$conductor = new $conductor_class();
|
$conductor = new $conductor_class();
|
||||||
@@ -523,9 +568,9 @@ class Conductor
|
|||||||
* @param Request $request The request data.
|
* @param Request $request The request data.
|
||||||
* @param string $key The key prefix to use.
|
* @param string $key The key prefix to use.
|
||||||
* @param Model|null $model The model.
|
* @param Model|null $model The model.
|
||||||
* @return array The processed and transformed model data.
|
* @return array|null The processed and transformed model data.
|
||||||
*/
|
*/
|
||||||
final public static function includeModel(Request $request, string $key, mixed $model)
|
final public static function includeModel(Request $request, string $key, mixed $model): array|null
|
||||||
{
|
{
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
@@ -551,9 +596,9 @@ class Conductor
|
|||||||
*
|
*
|
||||||
* @param mixed $fields The fields to show.
|
* @param mixed $fields The fields to show.
|
||||||
* @param Model|null $model The model.
|
* @param Model|null $model The model.
|
||||||
* @return array The processed and transformed model data.
|
* @return array|null The processed and transformed model data.
|
||||||
*/
|
*/
|
||||||
final public static function model(mixed $fields, mixed $model)
|
final public static function model(mixed $fields, mixed $model): array|null
|
||||||
{
|
{
|
||||||
if ($model === null) {
|
if ($model === null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -562,6 +607,7 @@ class Conductor
|
|||||||
$conductor_class = get_called_class();
|
$conductor_class = get_called_class();
|
||||||
$conductor = new $conductor_class();
|
$conductor = new $conductor_class();
|
||||||
|
|
||||||
|
$requestIncludes = [];
|
||||||
$modelFields = $conductor->fields(new $conductor->class());
|
$modelFields = $conductor->fields(new $conductor->class());
|
||||||
|
|
||||||
// Limit fields
|
// Limit fields
|
||||||
@@ -606,7 +652,7 @@ class Conductor
|
|||||||
*
|
*
|
||||||
* @return integer The current collection count.
|
* @return integer The current collection count.
|
||||||
*/
|
*/
|
||||||
final public function count()
|
final public function count(): int
|
||||||
{
|
{
|
||||||
if ($this->query !== null) {
|
if ($this->query !== null) {
|
||||||
return $this->query->count();
|
return $this->query->count();
|
||||||
@@ -621,7 +667,7 @@ class Conductor
|
|||||||
* @param mixed $fields A field name or array of field names to sort. Supports prefix of +/- to change direction.
|
* @param mixed $fields A field name or array of field names to sort. Supports prefix of +/- to change direction.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function sort(mixed $fields = null)
|
final public function sort(mixed $fields = null): void
|
||||||
{
|
{
|
||||||
$collectionSort = [];
|
$collectionSort = [];
|
||||||
|
|
||||||
@@ -700,7 +746,7 @@ class Conductor
|
|||||||
* @param array $includes The list of includes to include.
|
* @param array $includes The list of includes to include.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function applyIncludes(Model $model, array $includes)
|
final public function applyIncludes(Model $model, array $includes): void
|
||||||
{
|
{
|
||||||
foreach ($includes as $include) {
|
foreach ($includes as $include) {
|
||||||
$includeMethodName = 'include' . Str::studly($include);
|
$includeMethodName = 'include' . Str::studly($include);
|
||||||
@@ -720,7 +766,7 @@ class Conductor
|
|||||||
* @param array $fields An array of field names.
|
* @param array $fields An array of field names.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function limitFields(array $fields)
|
final public function limitFields(array $fields): void
|
||||||
{
|
{
|
||||||
if (empty($fields) !== true) {
|
if (empty($fields) !== true) {
|
||||||
$this->query->select(array_diff($fields, $this->includes));
|
$this->query->select(array_diff($fields, $this->includes));
|
||||||
@@ -735,8 +781,11 @@ class Conductor
|
|||||||
* @param string $outerJoin The join for this filter group.
|
* @param string $outerJoin The join for this filter group.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function appendFilterString(string $rawFilter, array|null $limitFields = null, string $outerJoin = 'OR')
|
final public function appendFilterString(
|
||||||
{
|
string $rawFilter,
|
||||||
|
array|null $limitFields = null,
|
||||||
|
string $outerJoin = 'AND'
|
||||||
|
): void {
|
||||||
if ($rawFilter === '') {
|
if ($rawFilter === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -773,8 +822,10 @@ class Conductor
|
|||||||
$field = substr($field, 1, -1);
|
$field = substr($field, 1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$set = &$value;
|
if ($set !== $value) {
|
||||||
continue;
|
$set = &$value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} elseif (($char === ')' && $string[($i + 1)] === ',') || $char === ',') {
|
} elseif (($char === ')' && $string[($i + 1)] === ',') || $char === ',') {
|
||||||
if ($value === null) {
|
if ($value === null) {
|
||||||
$tokens[] = $field;
|
$tokens[] = $field;
|
||||||
@@ -849,7 +900,7 @@ class Conductor
|
|||||||
* @param string $join The join to append.
|
* @param string $join The join to append.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
final public function appendFilter(string $field, string $operator, string $value, string $join = 'OR')
|
final public function appendFilter(string $field, string $operator, string $value, string $join = 'OR'): void
|
||||||
{
|
{
|
||||||
if (count($this->filterArray) !== 0) {
|
if (count($this->filterArray) !== 0) {
|
||||||
$this->filterArray[] = $join;
|
$this->filterArray[] = $join;
|
||||||
@@ -863,8 +914,9 @@ class Conductor
|
|||||||
* @param Builder $builder The builder in use.
|
* @param Builder $builder The builder in use.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function scope(Builder $builder)
|
public function scope(Builder $builder): void
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -873,14 +925,28 @@ class Conductor
|
|||||||
* @param Model $model The model in question.
|
* @param Model $model The model in question.
|
||||||
* @return array The array of field names.
|
* @return array The array of field names.
|
||||||
*/
|
*/
|
||||||
public function fields(Model $model)
|
public function fields(Model $model): array
|
||||||
{
|
{
|
||||||
$visibleFields = $model->getVisible();
|
$visibleFields = Cache::remember(
|
||||||
if (empty($visibleFields) === true) {
|
"model:{$model->getTable()}:visible",
|
||||||
$visibleFields = $model->getConnection()
|
now()->addDays(28),
|
||||||
->getSchemaBuilder()
|
function () use ($model) {
|
||||||
->getColumnListing($model->getTable());
|
$fields = $model->getVisible();
|
||||||
}
|
if (empty($fields) === true) {
|
||||||
|
$fields = Cache::remember(
|
||||||
|
"schema:{$model->getTable()}:columns",
|
||||||
|
now()->addDays(28),
|
||||||
|
function () use ($model) {
|
||||||
|
return $model->getConnection()
|
||||||
|
->getSchemaBuilder()
|
||||||
|
->getColumnListing($model->getTable());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$appends = $model->getAppends();
|
$appends = $model->getAppends();
|
||||||
if (is_array($appends) === true) {
|
if (is_array($appends) === true) {
|
||||||
@@ -900,7 +966,7 @@ class Conductor
|
|||||||
* @param Model $model The model to transform.
|
* @param Model $model The model to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
protected function transformModel(Model $model)
|
protected function transformModel(Model $model): array
|
||||||
{
|
{
|
||||||
$result = $this->transform($model);
|
$result = $this->transform($model);
|
||||||
foreach ($result as $key => $value) {
|
foreach ($result as $key => $value) {
|
||||||
@@ -920,7 +986,7 @@ class Conductor
|
|||||||
* @param Model $model The model to transform.
|
* @param Model $model The model to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
public function transform(Model $model)
|
public function transform(Model $model): array
|
||||||
{
|
{
|
||||||
$result = $model->toArray();
|
$result = $model->toArray();
|
||||||
|
|
||||||
@@ -939,7 +1005,7 @@ class Conductor
|
|||||||
* @param array $data The model array to transform.
|
* @param array $data The model array to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
public function transformFinal(array $data)
|
public function transformFinal(array $data): array
|
||||||
{
|
{
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
@@ -950,7 +1016,7 @@ class Conductor
|
|||||||
* @param Model $model The model in question.
|
* @param Model $model The model in question.
|
||||||
* @return boolean Is the model viewable.
|
* @return boolean Is the model viewable.
|
||||||
*/
|
*/
|
||||||
public static function viewable(Model $model)
|
public static function viewable(Model $model): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -960,7 +1026,7 @@ class Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Is the model creatable.
|
* @return boolean Is the model creatable.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -971,7 +1037,7 @@ class Conductor
|
|||||||
* @param Model $model The model in question.
|
* @param Model $model The model in question.
|
||||||
* @return boolean Is the model updatable.
|
* @return boolean Is the model updatable.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -982,7 +1048,7 @@ class Conductor
|
|||||||
* @param Model $model The model in question.
|
* @param Model $model The model in question.
|
||||||
* @return boolean Is the model destroyable.
|
* @return boolean Is the model destroyable.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ use Carbon\Carbon;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\InvalidCastException;
|
use Illuminate\Database\Eloquent\InvalidCastException;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class EventConductor extends Conductor
|
class EventConductor extends Conductor
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,7 @@ class EventConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Event';
|
protected $class = \App\Models\Event::class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default sorting field
|
* The default sorting field
|
||||||
@@ -35,8 +36,9 @@ class EventConductor extends Conductor
|
|||||||
* @param Builder $builder The builder in use.
|
* @param Builder $builder The builder in use.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function scope(Builder $builder)
|
public function scope(Builder $builder): void
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/events') === false) {
|
if ($user === null || $user->hasPermission('admin/events') === false) {
|
||||||
$builder
|
$builder
|
||||||
@@ -51,9 +53,10 @@ class EventConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow model to be visible.
|
* @return boolean Allow model to be visible.
|
||||||
*/
|
*/
|
||||||
public static function viewable(Model $model)
|
public static function viewable(Model $model): bool
|
||||||
{
|
{
|
||||||
if (strtolower($model->status) === 'draft' || Carbon::parse($model->publish_at)->isFuture() === true) {
|
if (strtolower($model->status) === 'draft' || Carbon::parse($model->publish_at)->isFuture() === true) {
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/events') === false) {
|
if ($user === null || $user->hasPermission('admin/events') === false) {
|
||||||
return false;
|
return false;
|
||||||
@@ -68,8 +71,9 @@ class EventConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Allow creating model.
|
* @return boolean Allow creating model.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/events') === true);
|
return ($user !== null && $user->hasPermission('admin/events') === true);
|
||||||
}
|
}
|
||||||
@@ -80,8 +84,9 @@ class EventConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/events') === true);
|
return ($user !== null && $user->hasPermission('admin/events') === true);
|
||||||
}
|
}
|
||||||
@@ -92,8 +97,9 @@ class EventConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/events') === true);
|
return ($user !== null && $user->hasPermission('admin/events') === true);
|
||||||
}
|
}
|
||||||
@@ -106,10 +112,11 @@ class EventConductor extends Conductor
|
|||||||
*/
|
*/
|
||||||
public function includeAttachments(Model $model)
|
public function includeAttachments(Model $model)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
return $model->attachments()->get()->map(function ($attachment) use ($user) {
|
return $model->getAttachments()->map(function ($attachment) use ($user) {
|
||||||
if ($attachment->private === false || ($user !== null && ($user->hasPermission('admin/events') === true || $attachment->users->contains($user) === true))) {
|
if ($attachment->private === false || ($user !== null && $user->hasPermission('admin/events') === true)) {
|
||||||
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
|
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -119,10 +126,15 @@ class EventConductor extends Conductor
|
|||||||
* Transform the Hero field.
|
* Transform the Hero field.
|
||||||
*
|
*
|
||||||
* @param mixed $value The current value.
|
* @param mixed $value The current value.
|
||||||
* @return array The new value.
|
* @return array|null The new value.
|
||||||
*/
|
*/
|
||||||
public function transformHero(mixed $value)
|
public function transformHero(mixed $value): array|null
|
||||||
{
|
{
|
||||||
return MediaConductor::includeModel(request(), 'hero', Media::find($value));
|
$cacheKey = "media:{$value}";
|
||||||
|
$media = Cache::remember($cacheKey, now()->addDays(28), function () use ($value) {
|
||||||
|
return Media::find($value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return MediaConductor::includeModel(request(), 'hero', $media);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Conductors;
|
namespace App\Conductors;
|
||||||
|
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\User;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
class MediaConductor extends Conductor
|
class MediaConductor extends Conductor
|
||||||
{
|
{
|
||||||
@@ -12,7 +14,7 @@ class MediaConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Media';
|
protected $class = \App\Models\Media::class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default sorting field
|
* The default sorting field
|
||||||
@@ -25,16 +27,16 @@ class MediaConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $includes = ['user'];
|
protected $includes = ['user', 'jobs'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default filters to use in a request.
|
* The default filters to use in a request.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $defaultFilters = [
|
// protected $defaultFilters = [
|
||||||
'status' => 'OK'
|
// 'status' => 'OK'
|
||||||
];
|
// ];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,13 +45,14 @@ class MediaConductor extends Conductor
|
|||||||
* @param Model $model The model in question.
|
* @param Model $model The model in question.
|
||||||
* @return array The array of field names.
|
* @return array The array of field names.
|
||||||
*/
|
*/
|
||||||
public function fields(Model $model)
|
public function fields(Model $model): array
|
||||||
{
|
{
|
||||||
$fields = parent::fields($model);
|
$fields = parent::fields($model);
|
||||||
|
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/media') === false) {
|
if ($user === null || $user->hasPermission('admin/media') === false) {
|
||||||
$fields = arrayRemoveItem($fields, ['permission', 'storage']);
|
$fields = arrayRemoveItem($fields, ['security_data', 'storage']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
@@ -61,13 +64,21 @@ class MediaConductor extends Conductor
|
|||||||
* @param Builder $builder The builder in use.
|
* @param Builder $builder The builder in use.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function scope(Builder $builder)
|
public function scope(Builder $builder): void
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null) {
|
if ($user === null) {
|
||||||
$builder->where('permission', '');
|
$builder->where('security_type', '')
|
||||||
|
->orWhere('security_type', 'password');
|
||||||
} else {
|
} else {
|
||||||
$builder->where('permission', '')->orWhereIn('permission', $user->permissions);
|
$builder->where(function ($query) use ($user) {
|
||||||
|
$query->where('security_type', '')
|
||||||
|
->orWhere('security_type', 'password')
|
||||||
|
->orWhere(function ($subquery) use ($user) {
|
||||||
|
$subquery->where('security_type', 'permission')
|
||||||
|
->whereIn('security_data', $user->permissions);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,13 +88,16 @@ class MediaConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow model to be visible.
|
* @return boolean Allow model to be visible.
|
||||||
*/
|
*/
|
||||||
public static function viewable(Model $model)
|
public static function viewable(Model $model): bool
|
||||||
{
|
{
|
||||||
if ($model->permission !== '') {
|
if (strcasecmp('permission', $model->security_type) === 0) {
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission($model->permission) === false) {
|
if ($user === null || $user->hasPermission($model->security_data) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} elseif ($model->security_type !== '' && strcasecmp('password', $model->security_type) !== 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -94,7 +108,7 @@ class MediaConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Allow creating model.
|
* @return boolean Allow creating model.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null);
|
return ($user !== null);
|
||||||
@@ -106,10 +120,12 @@ class MediaConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && (strcasecmp($model->user_id, $user->id) === 0 || $user->hasPermission('admin/media') === true));
|
return ($user !== null && (strcasecmp($model->user_id, $user->id) === 0 ||
|
||||||
|
$user->hasPermission('admin/media') === true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,8 +134,9 @@ class MediaConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && ($model->user_id === $user->id || $user->hasPermission('admin/media') === true));
|
return ($user !== null && ($model->user_id === $user->id || $user->hasPermission('admin/media') === true));
|
||||||
}
|
}
|
||||||
@@ -130,7 +147,7 @@ class MediaConductor extends Conductor
|
|||||||
* @param array $data The model data to transform.
|
* @param array $data The model data to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
public function transformFinal(array $data)
|
public function transformFinal(array $data): array
|
||||||
{
|
{
|
||||||
unset($data['user_id']);
|
unset($data['user_id']);
|
||||||
return $data;
|
return $data;
|
||||||
@@ -144,6 +161,24 @@ class MediaConductor extends Conductor
|
|||||||
*/
|
*/
|
||||||
public function includeUser(Model $model)
|
public function includeUser(Model $model)
|
||||||
{
|
{
|
||||||
return UserConductor::includeModel(request(), 'user', User::find($model['user_id']));
|
$user = Cache::remember("user:{$model['user_id']}", now()->addDays(28), function () use ($model) {
|
||||||
|
return User::find($model['user_id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
return UserConductor::includeModel(request(), 'user', $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include job models in Media
|
||||||
|
*
|
||||||
|
* @param Model $model The reference model.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function includeJobs(Model $model)
|
||||||
|
{
|
||||||
|
$jobs = $model->jobs()
|
||||||
|
->select(['id','created_at','updated_at','user_id','status','status_text','progress'])
|
||||||
|
->orderBy('created_at', 'desc')->get();
|
||||||
|
return $jobs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
76
app.old/Conductors/MediaJobConductor.php
Normal file
76
app.old/Conductors/MediaJobConductor.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Conductors;
|
||||||
|
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class MediaJobConductor extends Conductor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Model Class
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $class = \App\Models\MediaJob::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default sorting field
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $sort = 'created_at';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The included fields
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $includes = ['user'];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if the current model is creatable.
|
||||||
|
*
|
||||||
|
* @return boolean Allow creating model.
|
||||||
|
*/
|
||||||
|
public static function creatable(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if the current model is updatable.
|
||||||
|
*
|
||||||
|
* @param Model $model The model.
|
||||||
|
* @return boolean Allow updating model.
|
||||||
|
*/
|
||||||
|
public static function updatable(Model $model): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if the current model is destroyable.
|
||||||
|
*
|
||||||
|
* @param Model $model The model.
|
||||||
|
* @return boolean Allow deleting model.
|
||||||
|
*/
|
||||||
|
public static function destroyable(Model $model): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the final model data
|
||||||
|
*
|
||||||
|
* @param array $data The model data to transform.
|
||||||
|
* @return array The transformed model.
|
||||||
|
*/
|
||||||
|
public function transformFinal(array $data): array
|
||||||
|
{
|
||||||
|
unset($data['user_id']);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Conductors;
|
namespace App\Conductors;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\User;
|
|
||||||
|
|
||||||
class ShortlinkConductor extends Conductor
|
class ShortlinkConductor extends Conductor
|
||||||
{
|
{
|
||||||
@@ -12,7 +10,7 @@ class ShortlinkConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Shortlink';
|
protected $class = \App\Models\Shortlink::class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default sorting field
|
* The default sorting field
|
||||||
@@ -26,8 +24,9 @@ class ShortlinkConductor extends Conductor
|
|||||||
*
|
*
|
||||||
* @return boolean Allow creating model.
|
* @return boolean Allow creating model.
|
||||||
*/
|
*/
|
||||||
public static function creatable()
|
public static function creatable(): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
||||||
}
|
}
|
||||||
@@ -38,8 +37,9 @@ class ShortlinkConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,9 @@ class ShortlinkConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ class SubscriptionConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Subscription';
|
protected $class = \App\Models\Subscription::class;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,10 +19,14 @@ class SubscriptionConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
|
return ($user !== null && (
|
||||||
|
(strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) ||
|
||||||
|
$user->hasPermission('admin/subscriptions') === true
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,9 +35,11 @@ class SubscriptionConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
|
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 &&
|
||||||
|
$user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ class UserConductor extends Conductor
|
|||||||
* The Model Class
|
* The Model Class
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\User';
|
protected $class = \App\Models\User::class;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,8 +19,9 @@ class UserConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return string[] The fields visible.
|
* @return string[] The fields visible.
|
||||||
*/
|
*/
|
||||||
public function fields(Model $model)
|
public function fields(Model $model): array
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user === null || $user->hasPermission('admin/users') === false) {
|
if ($user === null || $user->hasPermission('admin/users') === false) {
|
||||||
return ['id', 'display_name'];
|
return ['id', 'display_name'];
|
||||||
@@ -35,18 +36,24 @@ class UserConductor extends Conductor
|
|||||||
* @param Model $model The model to transform.
|
* @param Model $model The model to transform.
|
||||||
* @return array The transformed model.
|
* @return array The transformed model.
|
||||||
*/
|
*/
|
||||||
public function transform(Model $model)
|
public function transform(Model $model): array
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$data = $model->toArray();
|
$data = $model->toArray();
|
||||||
|
$limit = $this->fields($model);
|
||||||
|
|
||||||
if ($user === null || ($user->hasPermission('admin/users') === false && strcasecmp($user->id, $model->id) !== 0)) {
|
if (
|
||||||
$fields = ['id', 'display_name'];
|
$user === null || (
|
||||||
$data = arrayLimitKeys($data, $fields);
|
$user->hasPermission('admin/users') === false && strcasecmp($user->id, $model->id) !== 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$limit = ['id', 'display_name'];
|
||||||
} else {
|
} else {
|
||||||
$data['permissions'] = $user->permissions;
|
$data['permissions'] = $user->permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = arrayLimitKeys($data, $limit);
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +63,9 @@ class UserConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow updating model.
|
* @return boolean Allow updating model.
|
||||||
*/
|
*/
|
||||||
public static function updatable(Model $model)
|
public static function updatable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
if ($user !== null) {
|
if ($user !== null) {
|
||||||
return ($user->hasPermission('admin/users') === true || strcasecmp($user->id, $model->id) === 0);
|
return ($user->hasPermission('admin/users') === true || strcasecmp($user->id, $model->id) === 0);
|
||||||
@@ -72,8 +80,9 @@ class UserConductor extends Conductor
|
|||||||
* @param Model $model The model.
|
* @param Model $model The model.
|
||||||
* @return boolean Allow deleting model.
|
* @return boolean Allow deleting model.
|
||||||
*/
|
*/
|
||||||
public static function destroyable(Model $model)
|
public static function destroyable(Model $model): bool
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
return ($user !== null && $user->hasPermission('admin/users') === true);
|
return ($user !== null && $user->hasPermission('admin/users') === true);
|
||||||
}
|
}
|
||||||
46
app.old/Console/Commands/CleanupTempFiles.php
Normal file
46
app.old/Console/Commands/CleanupTempFiles.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class CleanupTempFiles extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'app:cleanup-temp-files';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Delete temporary files that are older that 1 day';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
$keepTime = (1 * 24 * 60 * 60); // 1 Day
|
||||||
|
$currentTimeStamp = time();
|
||||||
|
$deletedFileCount = 0;
|
||||||
|
|
||||||
|
foreach (glob(storage_path('app/tmp/*')) as $filename) {
|
||||||
|
$fileModifiedTimeStamp = filemtime($filename);
|
||||||
|
if (($currentTimeStamp - $fileModifiedTimeStamp) > $keepTime) {
|
||||||
|
unlink($filename);
|
||||||
|
$deletedFileCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->comment('Deleted ' . $deletedFileCount . ' files');
|
||||||
|
}
|
||||||
|
}
|
||||||
42
app.old/Console/Commands/RemoveStaleMediaJobs.php
Normal file
42
app.old/Console/Commands/RemoveStaleMediaJobs.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class RemoveStaleMediaJobs extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'app:remove-stale-media-jobs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Remove media_jobs that have not been modified for 48 hours';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
$threshold = now()->subHours(48);
|
||||||
|
|
||||||
|
$staleJobs = MediaJob::where('updated_at', '<=', $threshold)->get();
|
||||||
|
|
||||||
|
foreach ($staleJobs as $job) {
|
||||||
|
$job->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info(count($staleJobs) . ' stale media_jobs removed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app.old/Console/Kernel.php
Normal file
34
app.old/Console/Kernel.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console;
|
||||||
|
|
||||||
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
|
class Kernel extends ConsoleKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the application's command schedule.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Console\Scheduling\Schedule $schedule The schedule.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function schedule(Schedule $schedule): void
|
||||||
|
{
|
||||||
|
// $schedule->command('inspire')->hourly();
|
||||||
|
$schedule->command('app:cleanup-temp-files')->everyThirtyMinutes();
|
||||||
|
$schedule->command('app:remove-stale-media-jobs')->everyThirtyMinutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the commands for the application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function commands(): void
|
||||||
|
{
|
||||||
|
$this->load(__DIR__ . '/Commands');
|
||||||
|
|
||||||
|
require base_path('routes/console.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,6 +58,8 @@ class Enum
|
|||||||
/**
|
/**
|
||||||
* Returns a message from the enum subclass
|
* Returns a message from the enum subclass
|
||||||
*
|
*
|
||||||
|
* @param integer $messageIndex The message index to retrieve.
|
||||||
|
* @param string $defaultMessage Message to use if index does not exist.
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getMessage(int $messageIndex, string $defaultMessage = 'Unknown'): string
|
public static function getMessage(int $messageIndex, string $defaultMessage = 'Unknown'): string
|
||||||
98
app.old/Exceptions/Handler.php
Normal file
98
app.old/Exceptions/Handler.php
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Throwable;
|
||||||
|
use PDOException;
|
||||||
|
use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Symfony\Component\ErrorHandler\Exception\FlattenException;
|
||||||
|
|
||||||
|
class Handler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $dontFlash = [
|
||||||
|
'current_password',
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the exception handling callbacks for the application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
// $this->renderable(function (HttpException $e, $request) {
|
||||||
|
// if ($request->is('api/*')) {
|
||||||
|
// $message = $e->getMessage();
|
||||||
|
// if ($message === '') {
|
||||||
|
// $message = HttpResponseCodes::$statusTexts[$e->getStatusCode()];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return response()->json([
|
||||||
|
// 'message' => $message
|
||||||
|
// ], $e->getStatusCode());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
$this->renderable(function (NotFoundHttpException $e, $request) {
|
||||||
|
if ($request->is('api/*') === true) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Resource not found'
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->renderable(function (PDOException $e, $request) {
|
||||||
|
if ($request->is('api/*') === true) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'The server is currently unavailable'
|
||||||
|
], 503);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->reportable(function (Throwable $e) {
|
||||||
|
if ($this->shouldReport($e) === true) {
|
||||||
|
if (App::runningUnitTests() === false) {
|
||||||
|
$this->sendEmail($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send email
|
||||||
|
*
|
||||||
|
* @param Throwable $exception Throwable object.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sendEmail(Throwable $exception)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$e = FlattenException::createFromThrowable($exception);
|
||||||
|
$handler = new HtmlErrorRenderer(true);
|
||||||
|
$css = $handler->getStylesheet();
|
||||||
|
$content = $handler->getBody($e);
|
||||||
|
|
||||||
|
Mail::send('emails.exception', compact('css', 'content'), function ($message) {
|
||||||
|
$message
|
||||||
|
->to('webmaster@stemmechanics.com.au')
|
||||||
|
->subject('Exception Generated')
|
||||||
|
;
|
||||||
|
});
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
Log::error($ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ class SubscriptionFilter extends FilterAbstract
|
|||||||
*
|
*
|
||||||
* @var mixed
|
* @var mixed
|
||||||
*/
|
*/
|
||||||
protected $class = '\App\Models\Subscription';
|
protected $class = \App\Models\Subscription::class;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,3 +38,41 @@ function arrayLimitKeys(array $arr, array $keys): array
|
|||||||
{
|
{
|
||||||
return array_intersect_key($arr, array_flip($keys));
|
return array_intersect_key($arr, array_flip($keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array value or default value if it does not exist
|
||||||
|
*
|
||||||
|
* @param string $key The key value to return if exists.
|
||||||
|
* @param array $arr The array to check.
|
||||||
|
* @param mixed $value The value to return if key does not exist.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function arrayDefaultValue(string $key, array $arr, mixed $value): mixed
|
||||||
|
{
|
||||||
|
if (array_key_exists($key, $arr) === true) {
|
||||||
|
return $arr[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if an item exists in an array, case insensitive
|
||||||
|
*
|
||||||
|
* @param string $val The value to check.
|
||||||
|
* @param array $arr The array to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function existsInArray(string $val, array $arr): bool
|
||||||
|
{
|
||||||
|
$exists = false;
|
||||||
|
|
||||||
|
foreach ($arr as $el) {
|
||||||
|
if (strcasecmp($val, $el) === 0) {
|
||||||
|
$exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exists;
|
||||||
|
}
|
||||||
92
app.old/Helpers/Temp.php
Normal file
92
app.old/Helpers/Temp.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/* Temp File Helper Functions */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a temporary file path.
|
||||||
|
*
|
||||||
|
* @param string $extension The file extension to use.
|
||||||
|
* @param string $part The file part number.
|
||||||
|
* @return string The filtered array.
|
||||||
|
*/
|
||||||
|
function generateTempFilePath(string $extension = '', string $part = ''): string
|
||||||
|
{
|
||||||
|
$temporaryDir = storage_path('app/tmp');
|
||||||
|
if (is_dir($temporaryDir) === false) {
|
||||||
|
mkdir($temporaryDir, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $temporaryDir . DIRECTORY_SEPARATOR . uniqid('upload_', true) . ($extension !== '' ? ".{$extension}" : '') .
|
||||||
|
($part !== '' ? ".part-{$part}" : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Temp file information
|
||||||
|
*
|
||||||
|
* @param string $filePath The temp file name.
|
||||||
|
* @return array The temp file name details.
|
||||||
|
*/
|
||||||
|
function tempFileInfo(string $filePath): array
|
||||||
|
{
|
||||||
|
$part = '';
|
||||||
|
|
||||||
|
// Extract the part if it's present
|
||||||
|
if (preg_match('/\.part-(\d+)$/', $filePath, $matches) !== false) {
|
||||||
|
$part = $matches[1];
|
||||||
|
$filePath = substr($filePath, 0, -strlen($matches[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = pathinfo($filePath);
|
||||||
|
|
||||||
|
$directory = $info['dirname'];
|
||||||
|
$name = $info['filename'];
|
||||||
|
$extension = '';
|
||||||
|
|
||||||
|
// If there's an extension, separate it
|
||||||
|
if (isset($info['extension']) === true) {
|
||||||
|
$extension = $info['extension'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'dirname' => $directory,
|
||||||
|
'basename' => $name . ($extension !== '' ? ".{$extension}" : ''),
|
||||||
|
'filename' => $name,
|
||||||
|
'extension' => $extension,
|
||||||
|
'part' => $part,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a temporary file exists.
|
||||||
|
*
|
||||||
|
* @param string $dir The file parent directory.
|
||||||
|
* @param string $name The file name.
|
||||||
|
* @param string $extension The file extension to use.
|
||||||
|
* @param string $part The file part number.
|
||||||
|
* @return boolean If the file exists.
|
||||||
|
*/
|
||||||
|
function tempFileExists(string $dir, string $name, string $extension = '', string $part = ''): bool
|
||||||
|
{
|
||||||
|
$filename = constructTempFileName($dir, $name, $extension, $part);
|
||||||
|
$exists = file_exists($filename);
|
||||||
|
|
||||||
|
return $exists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the temp file name based on the information
|
||||||
|
*
|
||||||
|
* @param string $dir The file parent directory.
|
||||||
|
* @param string $name The file name.
|
||||||
|
* @param string $extension The file extension to use.
|
||||||
|
* @param string $part The file part number.
|
||||||
|
* @return string The file path.
|
||||||
|
*/
|
||||||
|
function constructTempFileName(string $dir, string $name, string $extension = '', string $part = ''): string
|
||||||
|
{
|
||||||
|
$filename = $dir . DIRECTORY_SEPARATOR . $name . ($extension !== '' ? ".{$extension}" : '') .
|
||||||
|
($part !== "" ? ".part-{$part}" : '');
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
27
app.old/Helpers/TypeValue.php
Normal file
27
app.old/Helpers/TypeValue.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/* Type Value Helper Functions */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is value true
|
||||||
|
*
|
||||||
|
* @param mixed $value Value to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function isTrue(mixed $value): bool
|
||||||
|
{
|
||||||
|
if (is_bool($value) === true && $value === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_numeric($value) === true && intval($value) === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) === true && in_array(strtolower($value), ['true', '1'], true) === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
121
app.old/Http/Controllers/Api/AnalyticsController.php
Normal file
121
app.old/Http/Controllers/Api/AnalyticsController.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Conductors\AnalyticsConductor;
|
||||||
|
use App\Enum\HttpResponseCodes;
|
||||||
|
use App\Http\Requests\AnalyticsRequest;
|
||||||
|
use App\Models\AnalyticsItemRequest;
|
||||||
|
use App\Models\AnalyticsSession;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class AnalyticsController extends ApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AnalyticsController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth:sanctum')
|
||||||
|
->only([
|
||||||
|
'index',
|
||||||
|
'update',
|
||||||
|
'delete'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->user() !== null && $request->user()?->hasPermission('admin/analytics') === true) {
|
||||||
|
$request->rename([
|
||||||
|
'type' => 'requests.type',
|
||||||
|
'path' => 'requests.path'
|
||||||
|
]);
|
||||||
|
|
||||||
|
list($collection, $total) = AnalyticsConductor::request($request);
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
$collection,
|
||||||
|
['resourceName' => 'session',
|
||||||
|
'isCollection' => true,
|
||||||
|
'appendData' => ['total' => $total]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @param \App\Models\AnalyticsSession $session The analytics session.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show(Request $request, AnalyticsSession $session)
|
||||||
|
{
|
||||||
|
if ($request->user() !== null && $request->user()?->hasPermission('admin/analytics') === true) {
|
||||||
|
$session->load(['requests' => function ($query) {
|
||||||
|
$query->select('session_id', 'type', 'path', 'created_at');
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($session->requests as $requestItem) {
|
||||||
|
$requestItem->makeHidden('session_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
$session,
|
||||||
|
['resourceName' => 'session']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\AnalyticsRequest $request The user request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(AnalyticsRequest $request)
|
||||||
|
{
|
||||||
|
if (AnalyticsConductor::creatable() === true) {
|
||||||
|
$analytics = null;
|
||||||
|
$user = $request->user();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'type' => $request->input('type'),
|
||||||
|
'path' => $request->input('path', ''),
|
||||||
|
'useragent' => $request->userAgent(),
|
||||||
|
'ip' => $request->ip()
|
||||||
|
];
|
||||||
|
|
||||||
|
if (
|
||||||
|
$user !== null &&
|
||||||
|
$user->hasPermission('admin/analytics') === true &&
|
||||||
|
$request->has('session') === true
|
||||||
|
) {
|
||||||
|
$data['session_id'] = $request->input('session_id');
|
||||||
|
$analytics = AnalyticsItemRequest::create($data);
|
||||||
|
} else {
|
||||||
|
$analytics = AnalyticsItemRequest::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
AnalyticsConductor::model($request, $analytics),
|
||||||
|
['respondCode' => HttpResponseCodes::HTTP_CREATED]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}//end if
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use App\Enum\HttpResponseCodes;
|
use App\Enum\HttpResponseCodes;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -23,10 +24,13 @@ class ApiController extends Controller
|
|||||||
* @param array $data Response data.
|
* @param array $data Response data.
|
||||||
* @param integer $respondCode Response status code.
|
* @param integer $respondCode Response status code.
|
||||||
* @param array $headers Response headers.
|
* @param array $headers Response headers.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondJson(array $data, int $respondCode = HttpResponseCodes::HTTP_OK, array $headers = [])
|
public function respondJson(
|
||||||
{
|
array $data,
|
||||||
|
int $respondCode = HttpResponseCodes::HTTP_OK,
|
||||||
|
array $headers = []
|
||||||
|
): JsonResponse {
|
||||||
return response()->json($data, $respondCode, $headers);
|
return response()->json($data, $respondCode, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,10 +38,11 @@ class ApiController extends Controller
|
|||||||
* Return forbidden message
|
* Return forbidden message
|
||||||
*
|
*
|
||||||
* @param string $message Response message.
|
* @param string $message Response message.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondForbidden(string $message = 'You do not have permission to access the resource.')
|
public function respondForbidden(
|
||||||
{
|
string $message = 'You do not have permission to access the resource.'
|
||||||
|
): JsonResponse {
|
||||||
return response()->json(['message' => $message], HttpResponseCodes::HTTP_FORBIDDEN);
|
return response()->json(['message' => $message], HttpResponseCodes::HTTP_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,9 +50,9 @@ class ApiController extends Controller
|
|||||||
* Return forbidden message
|
* Return forbidden message
|
||||||
*
|
*
|
||||||
* @param string $message Response message.
|
* @param string $message Response message.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondNotFound(string $message = 'The resource was not found.')
|
public function respondNotFound(string $message = 'The resource was not found.'): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json(['message' => $message], HttpResponseCodes::HTTP_NOT_FOUND);
|
return response()->json(['message' => $message], HttpResponseCodes::HTTP_NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -56,49 +61,74 @@ class ApiController extends Controller
|
|||||||
* Return too large message
|
* Return too large message
|
||||||
*
|
*
|
||||||
* @param string $message Response message.
|
* @param string $message Response message.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondTooLarge(string $message = 'The request entity is too large.')
|
public function respondTooLarge(string $message = 'The request entity is too large.'): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json(['message' => $message], HttpResponseCodes::HTTP_REQUEST_ENTITY_TOO_LARGE);
|
return response()->json(['message' => $message], HttpResponseCodes::HTTP_REQUEST_ENTITY_TOO_LARGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return no content
|
* Return no content.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
*
|
||||||
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondNoContent()
|
public function respondNoContent(): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json([], HttpResponseCodes::HTTP_NO_CONTENT);
|
return response()->json([], HttpResponseCodes::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return created
|
* Return no content
|
||||||
* @return \Illuminate\Http\JsonResponse
|
*
|
||||||
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondCreated()
|
public function respondNotImplemented(): JsonResponse
|
||||||
|
{
|
||||||
|
return response()->json([], HttpResponseCodes::HTTP_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return created.
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function respondCreated(): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json([], HttpResponseCodes::HTTP_CREATED);
|
return response()->json([], HttpResponseCodes::HTTP_CREATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return accepted
|
* Return accepted.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
*
|
||||||
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondAccepted()
|
public function respondAccepted(): JsonResponse
|
||||||
{
|
{
|
||||||
return response()->json([], HttpResponseCodes::HTTP_ACCEPTED);
|
return response()->json([], HttpResponseCodes::HTTP_ACCEPTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return server error.
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function respondServerError(): JsonResponse
|
||||||
|
{
|
||||||
|
return response()->json([], HttpResponseCodes::HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return single error message
|
* Return single error message
|
||||||
*
|
*
|
||||||
* @param string $message Error message.
|
* @param string $message Error message.
|
||||||
* @param integer $responseCode Resource code.
|
* @param integer $responseCode Resource code.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondError(string $message, int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY)
|
public function respondError(
|
||||||
{
|
string $message,
|
||||||
|
int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY
|
||||||
|
): JsonResponse {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => $message
|
'message' => $message
|
||||||
], $responseCode);
|
], $responseCode);
|
||||||
@@ -109,10 +139,12 @@ class ApiController extends Controller
|
|||||||
*
|
*
|
||||||
* @param array $errors Error messages.
|
* @param array $errors Error messages.
|
||||||
* @param integer $responseCode Resource code.
|
* @param integer $responseCode Resource code.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function respondWithErrors(array $errors, int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY)
|
public function respondWithErrors(
|
||||||
{
|
array $errors,
|
||||||
|
int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY
|
||||||
|
): JsonResponse {
|
||||||
$keys = array_keys($errors);
|
$keys = array_keys($errors);
|
||||||
$error = $errors[$keys[0]];
|
$error = $errors[$keys[0]];
|
||||||
|
|
||||||
@@ -130,18 +162,20 @@ class ApiController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Return resource data
|
* Return resource data
|
||||||
*
|
*
|
||||||
* @param array|Model|Collection $data Resource data.
|
* @param array|Model|Collection $data Resource data.
|
||||||
* @param array $options Respond options.
|
* @param array $options Respond options.
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @param callable|null $validationFn Optional validation function to check the data before responding.
|
||||||
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
protected function respondAsResource(
|
protected function respondAsResource(
|
||||||
mixed $data,
|
mixed $data,
|
||||||
array $options = [],
|
array $options = [],
|
||||||
$validationFn = null
|
$validationFn = null
|
||||||
) {
|
): JsonResponse {
|
||||||
$isCollection = $options['isCollection'] ?? false;
|
$isCollection = ($options['isCollection'] ?? false);
|
||||||
$appendData = $options['appendData'] ?? null;
|
$appendData = ($options['appendData'] ?? null);
|
||||||
$resourceName = $options['resourceName'] ?? null;
|
$resourceName = ($options['resourceName'] ?? '');
|
||||||
|
$transformResourceName = ($options['transformResourceName'] ?? true);
|
||||||
$respondCode = ($options['respondCode'] ?? HttpResponseCodes::HTTP_OK);
|
$respondCode = ($options['respondCode'] ?? HttpResponseCodes::HTTP_OK);
|
||||||
|
|
||||||
if ($data === null || ($data instanceof Collection && $data->count() === 0)) {
|
if ($data === null || ($data instanceof Collection && $data->count() === 0)) {
|
||||||
@@ -155,11 +189,11 @@ class ApiController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($resourceName) === true || empty($resourceName) === true) {
|
if (empty($resourceName) === true) {
|
||||||
$resourceName = $this->resourceName;
|
$resourceName = $this->resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($resourceName) === true || empty($resourceName) === true) {
|
if (empty($resourceName) === true) {
|
||||||
$resourceName = get_class($this);
|
$resourceName = get_class($this);
|
||||||
$resourceName = substr($resourceName, (strrpos($resourceName, '\\') + 1));
|
$resourceName = substr($resourceName, (strrpos($resourceName, '\\') + 1));
|
||||||
$resourceName = substr($resourceName, 0, strpos($resourceName, 'Controller'));
|
$resourceName = substr($resourceName, 0, strpos($resourceName, 'Controller'));
|
||||||
@@ -172,15 +206,14 @@ class ApiController extends Controller
|
|||||||
} elseif (is_array($data) === true) {
|
} elseif (is_array($data) === true) {
|
||||||
$dataArray = $data;
|
$dataArray = $data;
|
||||||
} elseif ($data instanceof Model) {
|
} elseif ($data instanceof Model) {
|
||||||
$is_multiple = false;
|
|
||||||
$dataArray = $data->toArray();
|
$dataArray = $data->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
$resource = [];
|
$resource = [];
|
||||||
if ($isCollection === true) {
|
if ($isCollection === true) {
|
||||||
$resource = [Str::plural($resourceName) => $dataArray];
|
$resource = [$transformResourceName === true ? Str::plural($resourceName) : $resourceName => $dataArray];
|
||||||
} else {
|
} else {
|
||||||
$resource = [Str::singular($resourceName) => $dataArray];
|
$resource = [$transformResourceName === true ? Str::singular($resourceName) : $resourceName => $dataArray];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($appendData !== null) {
|
if ($appendData !== null) {
|
||||||
@@ -189,4 +222,22 @@ class ApiController extends Controller
|
|||||||
|
|
||||||
return response()->json($resource, $respondCode);
|
return response()->json($resource, $respondCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Controller Model Class name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getModelClass(): string
|
||||||
|
{
|
||||||
|
$controllerClass = static::class;
|
||||||
|
|
||||||
|
$modelName = 'App\\Models\\' . Str::replaceLast('Controller', '', Str::afterLast($controllerClass, '\\'));
|
||||||
|
|
||||||
|
if (class_exists($modelName) === false) {
|
||||||
|
return $modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $modelName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
139
app.old/Http/Controllers/Api/ArticleController.php
Normal file
139
app.old/Http/Controllers/Api/ArticleController.php
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Conductors\MediaConductor;
|
||||||
|
use App\Conductors\ArticleConductor;
|
||||||
|
use App\Enum\HttpResponseCodes;
|
||||||
|
use App\Http\Requests\ArticleRequest;
|
||||||
|
use App\Models\Media;
|
||||||
|
use App\Models\Article;
|
||||||
|
use App\Traits\HasAttachments;
|
||||||
|
use App\Traits\HasGallery;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ArticleController extends ApiController
|
||||||
|
{
|
||||||
|
use HasAttachments;
|
||||||
|
use HasGallery;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ApplicationController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth:sanctum')
|
||||||
|
->only([
|
||||||
|
'store',
|
||||||
|
'update',
|
||||||
|
'delete'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
list($collection, $total) = ArticleConductor::request($request);
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
$collection,
|
||||||
|
['isCollection' => true,
|
||||||
|
'appendData' => ['total' => $total]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @param \App\Models\Article $article The article model.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Article $article)
|
||||||
|
{
|
||||||
|
if (ArticleConductor::viewable($article) === true) {
|
||||||
|
return $this->respondAsResource(ArticleConductor::model($request, $article));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\ArticleRequest $request The user request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(ArticleRequest $request)
|
||||||
|
{
|
||||||
|
if (ArticleConductor::creatable() === true) {
|
||||||
|
$article = Article::create($request->except(['attachments', 'gallery']));
|
||||||
|
|
||||||
|
if ($request->has('attachments') === true) {
|
||||||
|
$article->addAttachments($request->get('attachments'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('gallery') === true) {
|
||||||
|
$article->galleryAddMany($request->get('gallery'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
ArticleConductor::model($request, $article),
|
||||||
|
['respondCode' => HttpResponseCodes::HTTP_CREATED]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}//end if
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\ArticleRequest $request The article update request.
|
||||||
|
* @param \App\Models\Article $article The specified article.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(ArticleRequest $request, Article $article)
|
||||||
|
{
|
||||||
|
if (ArticleConductor::updatable($article) === true) {
|
||||||
|
if ($request->has('attachments') === true) {
|
||||||
|
$article->deleteAttachments();
|
||||||
|
$article->addAttachments($request->get('attachments'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('gallery') === true) {
|
||||||
|
$article->gallery()->delete();
|
||||||
|
$article->galleryAddMany($request->get('gallery'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$article->update($request->except(['attachments', 'gallery']));
|
||||||
|
return $this->respondAsResource(ArticleConductor::model($request, $article));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\Article $article The specified article.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy(Article $article)
|
||||||
|
{
|
||||||
|
if (ArticleConductor::destroyable($article) === true) {
|
||||||
|
$article->delete();
|
||||||
|
return $this->respondNoContent();
|
||||||
|
} else {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ class AuthController extends ApiController
|
|||||||
* @param Request $request Current request data.
|
* @param Request $request Current request data.
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function me(Request $request)
|
public function me(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$user = $request->user()->makeVisible(['permissions']);
|
$user = $request->user()->makeVisible(['permissions']);
|
||||||
return $this->respondAsResource($user);
|
return $this->respondAsResource($user);
|
||||||
@@ -49,7 +49,11 @@ class AuthController extends ApiController
|
|||||||
{
|
{
|
||||||
$user = User::where('email', '=', $request->input('email'))->first();
|
$user = User::where('email', '=', $request->input('email'))->first();
|
||||||
|
|
||||||
if ($user !== null && strlen($user->password) > 0 && Hash::check($request->input('password'), $user->password) === true) {
|
if (
|
||||||
|
$user !== null &&
|
||||||
|
strlen($user->password) > 0 &&
|
||||||
|
Hash::check($request->input('password'), $user->password) === true
|
||||||
|
) {
|
||||||
if ($user->email_verified_at === null) {
|
if ($user->email_verified_at === null) {
|
||||||
return $this->respondWithErrors([
|
return $this->respondWithErrors([
|
||||||
'email' => 'Email address has not been verified.'
|
'email' => 'Email address has not been verified.'
|
||||||
@@ -89,7 +93,7 @@ class AuthController extends ApiController
|
|||||||
* @param Request $request Current request data.
|
* @param Request $request Current request data.
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function logout(Request $request)
|
public function logout(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
@@ -10,7 +10,10 @@ use App\Conductors\UserConductor;
|
|||||||
use App\Http\Requests\EventRequest;
|
use App\Http\Requests\EventRequest;
|
||||||
use App\Models\Media;
|
use App\Models\Media;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
class EventController extends ApiController
|
class EventController extends ApiController
|
||||||
{
|
{
|
||||||
@@ -66,7 +69,12 @@ class EventController extends ApiController
|
|||||||
public function store(EventRequest $request)
|
public function store(EventRequest $request)
|
||||||
{
|
{
|
||||||
if (EventConductor::creatable() === true) {
|
if (EventConductor::creatable() === true) {
|
||||||
$event = Event::create($request->all());
|
$event = Event::create($request->except(['attachments']));
|
||||||
|
|
||||||
|
if ($request->has('attachments') === true) {
|
||||||
|
$event->addAttachments($request->get('attachments'));
|
||||||
|
}
|
||||||
|
|
||||||
return $this->respondAsResource(
|
return $this->respondAsResource(
|
||||||
EventConductor::model($request, $event),
|
EventConductor::model($request, $event),
|
||||||
['respondCode' => HttpResponseCodes::HTTP_CREATED]
|
['respondCode' => HttpResponseCodes::HTTP_CREATED]
|
||||||
@@ -86,7 +94,12 @@ class EventController extends ApiController
|
|||||||
public function update(EventRequest $request, Event $event)
|
public function update(EventRequest $request, Event $event)
|
||||||
{
|
{
|
||||||
if (EventConductor::updatable($event) === true) {
|
if (EventConductor::updatable($event) === true) {
|
||||||
$event->update($request->all());
|
if ($request->has('attachments') === true) {
|
||||||
|
$event->deleteAttachments();
|
||||||
|
$event->addAttachments($request->get('attachments'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$event->update($request->except(['attachments']));
|
||||||
return $this->respondAsResource(EventConductor::model($request, $event));
|
return $this->respondAsResource(EventConductor::model($request, $event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,128 +123,12 @@ class EventController extends ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of attachments related to this model.
|
* List users of Event
|
||||||
*
|
* @param Request $request The HTTP request.
|
||||||
* @param Request $request The user request.
|
* @param Event $event Event model.
|
||||||
* @param Event $event The event model.
|
|
||||||
* @return JsonResponse Returns the event attachments.
|
|
||||||
*/
|
|
||||||
public function getAttachments(Request $request, Event $event)
|
|
||||||
{
|
|
||||||
if (EventConductor::viewable($event) === true) {
|
|
||||||
$medium = $event->attachments->map(function ($attachment) {
|
|
||||||
return $attachment->media;
|
|
||||||
});
|
|
||||||
|
|
||||||
return $this->respondAsResource(MediaConductor::collection($request, $medium), ['isCollection' => true, 'resourceName' => 'attachment']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->respondForbidden();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store an attachment related to this model.
|
|
||||||
*
|
|
||||||
* @param Request $request The user request.
|
|
||||||
* @param Event $event The event model.
|
|
||||||
* @return JsonResponse The response.
|
|
||||||
*/
|
|
||||||
public function storeAttachment(Request $request, Event $event)
|
|
||||||
{
|
|
||||||
if (EventConductor::updatable($event) === true) {
|
|
||||||
if ($request->has("medium") === true && Media::find($request->medium) !== null) {
|
|
||||||
$event->attachments()->create(['media_id' => $request->medium]);
|
|
||||||
return $this->respondCreated();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->respondWithErrors(['media' => 'The media ID was not found']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->respondForbidden();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update/replace attachments related to this model.
|
|
||||||
*
|
|
||||||
* @param Request $request The user request.
|
|
||||||
* @param Event $event The related model.
|
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function updateAttachments(Request $request, Event $event)
|
public function userList(Request $request, Event $event): JsonResponse
|
||||||
{
|
|
||||||
if (EventConductor::updatable($event) === true) {
|
|
||||||
$mediaIds = $request->attachments;
|
|
||||||
if (is_array($mediaIds) === false) {
|
|
||||||
$mediaIds = explode(',', $request->attachments);
|
|
||||||
}
|
|
||||||
|
|
||||||
$mediaIds = array_map('trim', $mediaIds); // trim each media ID
|
|
||||||
$attachments = $event->attachments;
|
|
||||||
|
|
||||||
// Delete attachments that are not in $mediaIds
|
|
||||||
foreach ($attachments as $attachment) {
|
|
||||||
if (in_array($attachment->media_id, $mediaIds) === false) {
|
|
||||||
$attachment->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new attachments for media IDs that are not already in $article->attachments()
|
|
||||||
foreach ($mediaIds as $mediaId) {
|
|
||||||
$found = false;
|
|
||||||
|
|
||||||
foreach ($attachments as $attachment) {
|
|
||||||
if ($attachment->media_id === $mediaId) {
|
|
||||||
$found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($found === false) {
|
|
||||||
$event->attachments()->create(['media_id' => $mediaId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->respondNoContent();
|
|
||||||
}//end if
|
|
||||||
|
|
||||||
return $this->respondForbidden();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a specific related attachment.
|
|
||||||
*
|
|
||||||
* @param Request $request The user request.
|
|
||||||
* @param Event $event The model.
|
|
||||||
* @param Media $medium The attachment medium.
|
|
||||||
* @return JsonResponse
|
|
||||||
*/
|
|
||||||
public function deleteAttachment(Request $request, Event $event, Media $medium)
|
|
||||||
{
|
|
||||||
if (EventConductor::updatable($event) === true) {
|
|
||||||
$attachments = $event->attachments;
|
|
||||||
$deleted = false;
|
|
||||||
|
|
||||||
foreach ($attachments as $attachment) {
|
|
||||||
if ($attachment->media_id === $medium->id) {
|
|
||||||
$attachment->delete();
|
|
||||||
$deleted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($deleted === true) {
|
|
||||||
// Attachment was deleted successfully
|
|
||||||
return $this->respondNoContent();
|
|
||||||
} else {
|
|
||||||
// Attachment with matching media ID was not found
|
|
||||||
return $this->respondNotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->respondForbidden();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function userList(Request $request, Event $event)
|
|
||||||
{
|
{
|
||||||
$authUser = $request->user();
|
$authUser = $request->user();
|
||||||
$eventUsers = $event->users;
|
$eventUsers = $event->users;
|
||||||
@@ -247,16 +144,28 @@ class EventController extends ApiController
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->respondAsResource(UserConductor::collection($request, $eventUsers), ['isCollection' => true, 'resourceName' => 'users']);
|
return $this->respondAsResource(
|
||||||
|
UserConductor::collection($request, $eventUsers),
|
||||||
|
[
|
||||||
|
'isCollection' => true,
|
||||||
|
'resourceName' => 'users'
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->respondNotFound();
|
return $this->respondNotFound();
|
||||||
}
|
}//end if
|
||||||
|
|
||||||
return $this->respondForbidden();
|
return $this->respondForbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userAdd(Request $request, Event $event)
|
/**
|
||||||
|
* Add user to Event
|
||||||
|
* @param Request $request The HTTP request.
|
||||||
|
* @param Event $event Event model.
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function userAdd(Request $request, Event $event): JsonResponse
|
||||||
{
|
{
|
||||||
$authUser = $request->user();
|
$authUser = $request->user();
|
||||||
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
|
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
|
||||||
@@ -288,12 +197,26 @@ class EventController extends ApiController
|
|||||||
return $this->respondForbidden();
|
return $this->respondForbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userUpdate(Request $request, Event $event)
|
/**
|
||||||
|
* Update user
|
||||||
|
* @param Request $request The HTTP request.
|
||||||
|
* @param Event $event Event model.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function userUpdate(Request $request, Event $event): void
|
||||||
{
|
{
|
||||||
// only admin/events permitted
|
// only admin/events permitted
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userDelete(Request $request, Event $event, User $user)
|
/**
|
||||||
|
* Delete user from event
|
||||||
|
*
|
||||||
|
* @param Request $request The HTTP request.
|
||||||
|
* @param Event $event Event model.
|
||||||
|
* @param User $user User model.
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function userDelete(Request $request, Event $event, User $user): JsonResponse
|
||||||
{
|
{
|
||||||
$authUser = $request->user();
|
$authUser = $request->user();
|
||||||
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
|
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
|
||||||
26
app.old/Http/Controllers/Api/InfoController.php
Normal file
26
app.old/Http/Controllers/Api/InfoController.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Enum\HttpResponseCodes;
|
||||||
|
use App\Models\Media;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class InfoController extends ApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$info = [
|
||||||
|
"version" => "1.0.0",
|
||||||
|
"max_upload_size" => Media::getMaxUploadSize()
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->respondJson($info);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,12 @@ class LogController extends ApiController
|
|||||||
|
|
||||||
$before = $request->get('before');
|
$before = $request->get('before');
|
||||||
if ($before !== null) {
|
if ($before !== null) {
|
||||||
$before = preg_split("/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/", $before, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
|
$before = preg_split(
|
||||||
|
"/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/",
|
||||||
|
$before,
|
||||||
|
-1,
|
||||||
|
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
|
||||||
|
);
|
||||||
if (count($before) !== 6) {
|
if (count($before) !== 6) {
|
||||||
$before = null;
|
$before = null;
|
||||||
}
|
}
|
||||||
@@ -53,7 +58,12 @@ class LogController extends ApiController
|
|||||||
|
|
||||||
$after = $request->get('after');
|
$after = $request->get('after');
|
||||||
if ($after !== null) {
|
if ($after !== null) {
|
||||||
$after = preg_split("/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/", $after, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
|
$after = preg_split(
|
||||||
|
"/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/",
|
||||||
|
$after,
|
||||||
|
-1,
|
||||||
|
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
|
||||||
|
);
|
||||||
if (count($after) !== 6) {
|
if (count($after) !== 6) {
|
||||||
$after = null;
|
$after = null;
|
||||||
}
|
}
|
||||||
@@ -77,30 +87,59 @@ class LogController extends ApiController
|
|||||||
$logContent = file_get_contents($logFile['path']);
|
$logContent = file_get_contents($logFile['path']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$logArray = preg_split("/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: (?:(?!\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: )[\s\S])*)/", $logContent, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
|
$logArray = preg_split(
|
||||||
|
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||||
|
"/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: (?:(?!\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: )[\s\S])*)/",
|
||||||
|
$logContent,
|
||||||
|
-1,
|
||||||
|
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
|
||||||
|
);
|
||||||
|
|
||||||
$logContent = '';
|
$logContent = '';
|
||||||
$logLineCount = 0;
|
$logLineCount = 0;
|
||||||
$logLineSkip = false;
|
$logLineSkip = false;
|
||||||
foreach (array_reverse($logArray) as $logLine) {
|
foreach (array_reverse($logArray) as $logLine) {
|
||||||
$lineDate = preg_split("/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}): /", $logLine, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
|
$lineDate = preg_split(
|
||||||
|
"/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}): /",
|
||||||
|
$logLine,
|
||||||
|
-1,
|
||||||
|
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
|
||||||
|
);
|
||||||
if (count($lineDate) >= 6) {
|
if (count($lineDate) >= 6) {
|
||||||
$logLineSkip = false;
|
$logLineSkip = false;
|
||||||
|
|
||||||
// Is line before
|
// Is line before
|
||||||
if ($before !== null && ($lineDate[0] > $before[0] || $lineDate[1] > $before[1] || $lineDate[2] > $before[2] || $lineDate[3] > $before[3] || $lineDate[4] > $before[4] || $lineDate[5] > $before[5])) {
|
if (
|
||||||
|
$before !== null && (
|
||||||
|
$lineDate[0] > $before[0] ||
|
||||||
|
$lineDate[1] > $before[1] ||
|
||||||
|
$lineDate[2] > $before[2] ||
|
||||||
|
$lineDate[3] > $before[3] ||
|
||||||
|
$lineDate[4] > $before[4] ||
|
||||||
|
$lineDate[5] > $before[5]
|
||||||
|
)
|
||||||
|
) {
|
||||||
$logLineSkip = true;
|
$logLineSkip = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is line after
|
// Is line after
|
||||||
if ($after !== null && ($after[0] > $lineDate[0] || $after[1] > $lineDate[1] || $after[2] > $lineDate[2] || $after[3] > $lineDate[3] || $after[4] > $lineDate[4] || $after[5] > $lineDate[5])) {
|
if (
|
||||||
|
$after !== null && (
|
||||||
|
$after[0] > $lineDate[0] ||
|
||||||
|
$after[1] > $lineDate[1] ||
|
||||||
|
$after[2] > $lineDate[2] ||
|
||||||
|
$after[3] > $lineDate[3] ||
|
||||||
|
$after[4] > $lineDate[4] ||
|
||||||
|
$after[5] > $lineDate[5]
|
||||||
|
)
|
||||||
|
) {
|
||||||
$logLineSkip = true;
|
$logLineSkip = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$logLineCount += 1;
|
$logLineCount += 1;
|
||||||
}
|
}//end if
|
||||||
|
|
||||||
if ($logLineCount > $lines) {
|
if ($logLineCount > $lines) {
|
||||||
break;
|
break;
|
||||||
443
app.old/Http/Controllers/Api/MediaController.php
Normal file
443
app.old/Http/Controllers/Api/MediaController.php
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Conductors\MediaConductor;
|
||||||
|
use App\Conductors\MediaJobConductor;
|
||||||
|
use App\Enum\HttpResponseCodes;
|
||||||
|
use App\Http\Requests\MediaRequest;
|
||||||
|
use App\Models\Media;
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Laravel\Sanctum\PersonalAccessToken;
|
||||||
|
|
||||||
|
class MediaController extends ApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ApplicationController constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth:sanctum')
|
||||||
|
->only(['store','update','destroy']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
list($collection, $total) = MediaConductor::request($request);
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
$collection,
|
||||||
|
['isCollection' => true,
|
||||||
|
'appendData' => ['total' => $total]
|
||||||
|
],
|
||||||
|
function ($options) {
|
||||||
|
return $options['total'] === 0;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @param \App\Models\Media $medium The request media.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show(Request $request, Media $medium)
|
||||||
|
{
|
||||||
|
if (MediaConductor::viewable($medium) === true) {
|
||||||
|
return $this->respondAsResource(MediaConductor::model($request, $medium));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a new media resource
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\MediaRequest $request The uploaded media.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(MediaRequest $request)
|
||||||
|
{
|
||||||
|
// allowed to create a media item
|
||||||
|
if (MediaConductor::creatable() === false) {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for file
|
||||||
|
$file = $request->file('file');
|
||||||
|
if ($file === null) {
|
||||||
|
return $this->respondWithErrors(['file' => 'The browser did not upload the file correctly to the server.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->storeOrUpdate($request, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the media resource in storage.
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\MediaRequest $request The update request.
|
||||||
|
* @param \App\Models\Media $medium The specified media.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(MediaRequest $request, Media $medium)
|
||||||
|
{
|
||||||
|
// allowed to update a media item
|
||||||
|
if (MediaConductor::updatable($medium) === false) {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->storeOrUpdate($request, $medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a new media resource
|
||||||
|
*
|
||||||
|
* @param \App\Http\Requests\MediaRequest $request The uploaded media.
|
||||||
|
* @param \App\Models\Media|null $medium The specified media.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function storeOrUpdate(MediaRequest $request, Media|null $medium)
|
||||||
|
{
|
||||||
|
$file = $request->file('file');
|
||||||
|
if ($file !== null) {
|
||||||
|
// validate file object
|
||||||
|
if ($file->isValid() !== true) {
|
||||||
|
switch ($file->getError()) {
|
||||||
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
|
return $this->respondTooLarge();
|
||||||
|
case UPLOAD_ERR_PARTIAL:
|
||||||
|
return $this->respondWithErrors([$file => 'The file upload was interrupted.']);
|
||||||
|
default:
|
||||||
|
return $this->respondWithErrors(
|
||||||
|
[$file => 'An error occurred uploading the file to the server.']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file->getSize() > Media::getMaxUploadSize()) {
|
||||||
|
return $this->respondTooLarge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create/get media job
|
||||||
|
$mediaJob = null;
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
if ($request->missing('job_id') === true) {
|
||||||
|
/** @var \App\Models\User */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$mediaJob = new MediaJob();
|
||||||
|
$mediaJob->user_id = $user->id;
|
||||||
|
if ($medium !== null) {
|
||||||
|
$mediaJob->media_id = $medium->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('title') === true || $file !== null) {
|
||||||
|
$data['title'] = $request->get('title', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('name') === true || $file !== null) {
|
||||||
|
$data['name'] = (
|
||||||
|
$request->has('chunk') === true ? $request->get('name', '') : $file->getClientOriginalName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file !== null) {
|
||||||
|
$data['size'] = $request->has('chunk') === true ? intval($request->get('size', 0)) : $file->getSize();
|
||||||
|
$data['mime_type'] = (
|
||||||
|
$request->has('chunk') === true ? $request->get('mime_type', '') : $file->getMimeType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('storage') === true || $file !== null) {
|
||||||
|
$data['storage'] = $request->get('storage', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('security_type') === true || $file !== null) {
|
||||||
|
$data['security']['type'] = $request->get('security_type', '');
|
||||||
|
$data['security']['data'] = $request->get('security_data', '');
|
||||||
|
|
||||||
|
if ($data['security']['type'] === '') {
|
||||||
|
$data['security']['data'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($medium === null || strcasecmp($data['security']['type'], $medium->security_type) !== 0) {
|
||||||
|
if ($request->has('storage') === false) {
|
||||||
|
$mime_type = $request->get('mime_type', $medium === null ? '' : $medium->mime_type);
|
||||||
|
$data['storage'] = Media::recommendedStorage($mime_type, $data['security']['type']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
array_key_exists('storage', $data) === true && (
|
||||||
|
array_key_exists('security', $data) === true &&
|
||||||
|
array_key_exists('type', $data['security']) === true
|
||||||
|
) &&
|
||||||
|
array_key_exists('mime_type', $data) === true &&
|
||||||
|
$data['mime_type'] !== ""
|
||||||
|
) {
|
||||||
|
$error = Media::verifyStorage($data['mime_type'], $data['security']['type'], $data['storage']);
|
||||||
|
// Log::error($data['mime_type'] . ' - ' . $data['security']['type'] . ' - ' . $data['storage']);
|
||||||
|
switch ($error) {
|
||||||
|
case Media::STORAGE_VALID:
|
||||||
|
break;
|
||||||
|
case Media::STORAGE_MIME_MISSING:
|
||||||
|
return $this->respondWithErrors(['mime_type' => 'The file type is required.']);
|
||||||
|
case Media::STORAGE_NOT_FOUND:
|
||||||
|
return $this->respondWithErrors(['storage' => 'Storage was not found.']);
|
||||||
|
case Media::STORAGE_INVALID_SECURITY:
|
||||||
|
return $this->respondWithErrors(
|
||||||
|
['storage' => 'Storage invalid for this security requirement.']
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return $this->respondWithErrors(['storage' => 'Storage verification error occurred.']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('transform') === true) {
|
||||||
|
$transform = [];
|
||||||
|
|
||||||
|
foreach (explode(',', $request->get('transform', '')) as $value) {
|
||||||
|
if (is_string($value) === true) {
|
||||||
|
if (preg_match('/^rotate-(-?\d+)$/', $value, $matches) !== false) {
|
||||||
|
$transform['rotate'] = $matches[1];
|
||||||
|
} elseif (preg_match('/^flip-([vh]|vh|hv)$/', $value, $matches) !== false) {
|
||||||
|
$transform['flip'] = $matches[1];
|
||||||
|
} elseif (preg_match('/^crop-(\d+)-(\d+)$/', $value, $matches) !== false) {
|
||||||
|
$transform['crop'] = ['width' => $matches[1], 'height' => $matches[2]];
|
||||||
|
} elseif (preg_match('/^crop-(\d+)-(\d+)-(\d+)-(\d+)$/', $value, $matches) !== false) {
|
||||||
|
$transform['crop'] = [
|
||||||
|
'width' => $matches[1],
|
||||||
|
'height' => $matches[2],
|
||||||
|
'x' => $matches[3],
|
||||||
|
'y' => $matches[4]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($transform) > 0) {
|
||||||
|
$data['transform'] = $transform;
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
$mediaJob->setStatusWaiting();
|
||||||
|
} else {
|
||||||
|
$mediaJob = MediaJob::find($request->get('job_id'));
|
||||||
|
if ($mediaJob === null || $mediaJob->exists() === false) {
|
||||||
|
$this->respondNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($mediaJob->data, true);
|
||||||
|
if ($data === null) {
|
||||||
|
Log::error(`{$mediaJob->id} contains no data`);
|
||||||
|
return $this->respondServerError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('name', $data) === false) {
|
||||||
|
Log::error(`{$mediaJob->id} data does not contain the name key`);
|
||||||
|
return $this->respondServerError();
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
if ($mediaJob === null) {
|
||||||
|
Log::error(`media job does not exist`);
|
||||||
|
return $this->respondServerError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// save uploaded file
|
||||||
|
if ($file !== null) {
|
||||||
|
if ($data['name'] === '') {
|
||||||
|
Log::error(`filename does not exist`);
|
||||||
|
return $this->respondServerError();
|
||||||
|
}
|
||||||
|
|
||||||
|
$temporaryFilePath = generateTempFilePath(
|
||||||
|
pathinfo($data['name'], PATHINFO_EXTENSION),
|
||||||
|
$request->get('chunk', '')
|
||||||
|
);
|
||||||
|
copy($file->path(), $temporaryFilePath);
|
||||||
|
|
||||||
|
if ($request->has('chunk') === true) {
|
||||||
|
$data['chunks'][$request->get('chunk', '1')] = $temporaryFilePath;
|
||||||
|
$data['chunk_count'] = $request->get('chunk_count', 1);
|
||||||
|
} else {
|
||||||
|
$data['file'] = $temporaryFilePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$mediaJob->data = json_encode($data, true);
|
||||||
|
$mediaJob->save();
|
||||||
|
$mediaJob->process();
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
MediaJobConductor::model($request, $mediaJob),
|
||||||
|
['resourceName' => 'media_job', 'respondCode' => HttpResponseCodes::HTTP_ACCEPTED]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\Media $medium Specified media file.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy(Media $medium)
|
||||||
|
{
|
||||||
|
if (MediaConductor::destroyable($medium) === true) {
|
||||||
|
$medium->delete();
|
||||||
|
return $this->respondNoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @param \App\Models\Media $media Specified media.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function download(Request $request, Media $media): Response
|
||||||
|
{
|
||||||
|
$headers = [];
|
||||||
|
|
||||||
|
/* Check file exists */
|
||||||
|
if (Storage::disk($media->storage)->exists($media->name) === false) {
|
||||||
|
return $this->respondNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
$updated_at = Carbon::parse(Storage::disk($media->storage)->lastModified($media->name));
|
||||||
|
|
||||||
|
$headerPragma = 'no-cache';
|
||||||
|
$headerCacheControl = 'max-age=0, must-revalidate';
|
||||||
|
$headerExpires = $updated_at->toRfc2822String();
|
||||||
|
|
||||||
|
/* construct user if can */
|
||||||
|
$user = $request->user();
|
||||||
|
if ($user === null && $request->has('token') === true) {
|
||||||
|
$accessToken = PersonalAccessToken::findToken(urldecode($request->input('token')));
|
||||||
|
|
||||||
|
if (
|
||||||
|
$accessToken !== null && (config('sanctum.expiration') === null ||
|
||||||
|
$accessToken->created_at->lte(now()->subMinutes(config('sanctum.expiration'))) === false)
|
||||||
|
) {
|
||||||
|
$user = $accessToken->tokenable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($media->security_type === '') {
|
||||||
|
/* no security */
|
||||||
|
$headerPragma = 'public';
|
||||||
|
$headerExpires = $updated_at->addMonth()->toRfc2822String();
|
||||||
|
} elseif (strcasecmp('password', $media->security_type) === 0) {
|
||||||
|
/* password */
|
||||||
|
if (
|
||||||
|
($user === null || $user->hasPermission('admin/media') === false) &&
|
||||||
|
($request->has('password') === false || $request->get('password') !== $media->security_data)
|
||||||
|
) {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
} elseif (strcasecmp('permission', $media->security_type) === 0) {
|
||||||
|
/* permission */
|
||||||
|
if (
|
||||||
|
$user === null || (
|
||||||
|
$user->hasPermission('admin/media') === false &&
|
||||||
|
$user->hasPermission($media->security_data) === false
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
// deepcode ignore InsecureHash: Browsers expect Etag to be a md5 hash
|
||||||
|
$headerEtag = md5($updated_at->format('U'));
|
||||||
|
$headerLastModified = $updated_at->toRfc2822String();
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'Cache-Control' => $headerCacheControl,
|
||||||
|
'Content-Disposition' => sprintf('inline; filename="%s"', basename($media->name)),
|
||||||
|
'Etag' => $headerEtag,
|
||||||
|
'Expires' => $headerExpires,
|
||||||
|
'Last-Modified' => $headerLastModified,
|
||||||
|
'Pragma' => $headerPragma,
|
||||||
|
];
|
||||||
|
|
||||||
|
$server = request()->server;
|
||||||
|
|
||||||
|
$requestModifiedSince = $server->has('HTTP_IF_MODIFIED_SINCE') &&
|
||||||
|
$server->get('HTTP_IF_MODIFIED_SINCE') === $headerLastModified;
|
||||||
|
|
||||||
|
$requestNoneMatch = $server->has('HTTP_IF_NONE_MATCH') &&
|
||||||
|
$server->get('HTTP_IF_NONE_MATCH') === $headerEtag;
|
||||||
|
|
||||||
|
if ($requestModifiedSince === true || $requestNoneMatch === true) {
|
||||||
|
return response()->make('', 304, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers['Content-Type'] = Storage::disk($media->storage)->mimeType($media->name);
|
||||||
|
$headers['Content-Length'] = Storage::disk($media->storage)->size($media->name);
|
||||||
|
$headers['Content-Disposition'] = 'attachment; filename="' . basename($media->name) . '"';
|
||||||
|
|
||||||
|
$stream = Storage::disk($media->storage)->readStream($media->name);
|
||||||
|
return response()->stream(
|
||||||
|
function () use ($stream) {
|
||||||
|
while (ob_get_level() > 0) {
|
||||||
|
ob_end_flush();
|
||||||
|
}
|
||||||
|
fpassthru($stream);
|
||||||
|
},
|
||||||
|
200,
|
||||||
|
$headers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a File item in a request is valid
|
||||||
|
*
|
||||||
|
* @param UploadedFile $file The file to validate.
|
||||||
|
* @param string $errorKey The error key to use.
|
||||||
|
* @return JsonResponse|null
|
||||||
|
*/
|
||||||
|
private function validateFileObject(UploadedFile $file, string $errorKey = 'file'): JsonResponse|null
|
||||||
|
{
|
||||||
|
if ($file->isValid() !== true) {
|
||||||
|
switch ($file->getError()) {
|
||||||
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
|
return $this->respondTooLarge();
|
||||||
|
case UPLOAD_ERR_PARTIAL:
|
||||||
|
return $this->respondWithErrors([$errorKey => 'The file upload was interrupted.']);
|
||||||
|
default:
|
||||||
|
return $this->respondWithErrors(
|
||||||
|
[$errorKey => 'An error occurred uploading the file to the server.']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file->getSize() > Media::getMaxUploadSize()) {
|
||||||
|
return $this->respondTooLarge();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
app.old/Http/Controllers/Api/MediaJobController.php
Normal file
52
app.old/Http/Controllers/Api/MediaJobController.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Conductors\MediaJobConductor;
|
||||||
|
use App\Http\Controllers\Api\ApiController;
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class MediaJobController extends ApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
list($collection, $total) = MediaJobConductor::request($request);
|
||||||
|
|
||||||
|
return $this->respondAsResource(
|
||||||
|
$collection,
|
||||||
|
['isCollection' => true,
|
||||||
|
'appendData' => ['total' => $total],
|
||||||
|
'resourceName' => 'media_job'
|
||||||
|
],
|
||||||
|
function ($options) {
|
||||||
|
return $options['total'] === 0;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request The endpoint request.
|
||||||
|
* @param \App\Models\MediaJob $mediaJob The request media job.
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function show(Request $request, MediaJob $mediaJob)
|
||||||
|
{
|
||||||
|
if (MediaJobConductor::viewable($mediaJob) === true) {
|
||||||
|
return $this->respondAsResource(
|
||||||
|
MediaJobConductor::model($request, $mediaJob),
|
||||||
|
['resourceName' => 'media_job']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->respondForbidden();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,7 +101,10 @@ class OCRController extends ApiController
|
|||||||
$tesseractImageFilterFunc = function ($filter, $options = null) use ($curlResult, $curlSize, $ocr) {
|
$tesseractImageFilterFunc = function ($filter, $options = null) use ($curlResult, $curlSize, $ocr) {
|
||||||
$result = '';
|
$result = '';
|
||||||
$img = imagecreatefromstring($curlResult);
|
$img = imagecreatefromstring($curlResult);
|
||||||
if ($img !== false && (($options !== null && imagefilter($img, $filter, $options) === true) || ($options === null && imagefilter($img, $filter) === true))) {
|
if (
|
||||||
|
$img !== false && (($options !== null && imagefilter($img, $filter, $options) === true) ||
|
||||||
|
($options === null && imagefilter($img, $filter) === true))
|
||||||
|
) {
|
||||||
ob_start();
|
ob_start();
|
||||||
imagepng($img);
|
imagepng($img);
|
||||||
$imgData = ob_get_contents();
|
$imgData = ob_get_contents();
|
||||||
@@ -2,17 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Conductors\MediaConductor;
|
|
||||||
use App\Conductors\ShortlinkConductor;
|
use App\Conductors\ShortlinkConductor;
|
||||||
use App\Enum\HttpResponseCodes;
|
use App\Enum\HttpResponseCodes;
|
||||||
use App\Http\Requests\MediaRequest;
|
|
||||||
use App\Http\Requests\ShortlinkRequest;
|
use App\Http\Requests\ShortlinkRequest;
|
||||||
use App\Models\Media;
|
|
||||||
use App\Models\Shortlink;
|
use App\Models\Shortlink;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Laravel\Sanctum\PersonalAccessToken;
|
|
||||||
|
|
||||||
class ShortlinkController extends ApiController
|
class ShortlinkController extends ApiController
|
||||||
{
|
{
|
||||||
@@ -85,8 +79,8 @@ class ShortlinkController extends ApiController
|
|||||||
/**
|
/**
|
||||||
* Update the media resource in storage.
|
* Update the media resource in storage.
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\ShortlinkRequest $request The update request.
|
* @param \App\Http\Requests\ShortlinkRequest $request The update request.
|
||||||
* @param \App\Models\Shortlink $medium The specified shortlink.
|
* @param \App\Models\Shortlink $shortlink The specified shortlink.
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function update(ShortlinkRequest $request, Shortlink $shortlink)
|
public function update(ShortlinkRequest $request, Shortlink $shortlink)
|
||||||
@@ -102,7 +96,7 @@ class ShortlinkController extends ApiController
|
|||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*
|
*
|
||||||
* @param \App\Models\Shortlink $medium Specified shortlink.
|
* @param \App\Models\Shortlink $shortlink Specified shortlink.
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function destroy(Shortlink $shortlink)
|
public function destroy(Shortlink $shortlink)
|
||||||
@@ -73,7 +73,10 @@ class UserController extends ApiController
|
|||||||
{
|
{
|
||||||
if (UserConductor::creatable() === true) {
|
if (UserConductor::creatable() === true) {
|
||||||
$user = User::create($request->all());
|
$user = User::create($request->all());
|
||||||
return $this->respondAsResource(UserConductor::model($request, $user), ['respondCode' => HttpResponseCodes::HTTP_CREATED]);
|
return $this->respondAsResource(
|
||||||
|
UserConductor::model($request, $user),
|
||||||
|
['respondCode' => HttpResponseCodes::HTTP_CREATED]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return $this->respondForbidden();
|
return $this->respondForbidden();
|
||||||
}
|
}
|
||||||
@@ -145,9 +148,9 @@ class UserController extends ApiController
|
|||||||
* Register a new user
|
* Register a new user
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\UserRegisterRequest $request The register user request.
|
* @param \App\Http\Requests\UserRegisterRequest $request The register user request.
|
||||||
* @return \Illuminate\Http\Response
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function register(UserRegisterRequest $request)
|
public function register(UserRegisterRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$userData = $request->only([
|
$userData = $request->only([
|
||||||
@@ -286,9 +289,9 @@ class UserController extends ApiController
|
|||||||
* Resend a new verify email
|
* Resend a new verify email
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\UserResendVerifyEmailRequest $request The resend verify email request.
|
* @param \App\Http\Requests\UserResendVerifyEmailRequest $request The resend verify email request.
|
||||||
* @return \Illuminate\Http\Response
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function resendVerifyEmail(UserResendVerifyEmailRequest $request)
|
public function resendVerifyEmail(UserResendVerifyEmailRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
UserCode::clearExpired();
|
UserCode::clearExpired();
|
||||||
|
|
||||||
@@ -342,9 +345,13 @@ class UserController extends ApiController
|
|||||||
* @param User $user The specified user.
|
* @param User $user The specified user.
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
*/
|
*/
|
||||||
public function eventList(Request $request, User $user)
|
public function eventList(Request $request, User $user): JsonResponse
|
||||||
{
|
{
|
||||||
if ($request->user() !== null && ($request->user() === $user || $request->user()->hasPermission('admin/events') === true)) {
|
if (
|
||||||
|
$request->user() !== null && (
|
||||||
|
$request->user() === $user || $request->user()->hasPermission('admin/events') === true
|
||||||
|
)
|
||||||
|
) {
|
||||||
$collection = $user->events;
|
$collection = $user->events;
|
||||||
$total = $collection->count();
|
$total = $collection->count();
|
||||||
|
|
||||||
13
app.old/Http/Controllers/Controller.php
Normal file
13
app.old/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
|
|
||||||
|
class Controller extends BaseController
|
||||||
|
{
|
||||||
|
use AuthorizesRequests;
|
||||||
|
use ValidatesRequests;
|
||||||
|
}
|
||||||
73
app.old/Http/Kernel.php
Normal file
73
app.old/Http/Kernel.php
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
|
|
||||||
|
class Kernel extends HttpKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The application's global HTTP middleware stack.
|
||||||
|
*
|
||||||
|
* These middleware are run during every request to your application.
|
||||||
|
*
|
||||||
|
* @var array<int, class-string|string>
|
||||||
|
*/
|
||||||
|
protected $middleware = [
|
||||||
|
// \App\Http\Middleware\TrustHosts::class,
|
||||||
|
\App\Http\Middleware\TrustProxies::class,
|
||||||
|
\Illuminate\Http\Middleware\HandleCors::class,
|
||||||
|
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||||
|
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||||
|
// \App\Http\Middleware\TrimStrings::class,
|
||||||
|
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application's route middleware groups.
|
||||||
|
*
|
||||||
|
* @var array<string, array<int, class-string|string>>
|
||||||
|
*/
|
||||||
|
protected $middlewareGroups = [
|
||||||
|
'web' => [
|
||||||
|
\App\Http\Middleware\EncryptCookies::class,
|
||||||
|
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||||
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
],
|
||||||
|
|
||||||
|
'api' => [
|
||||||
|
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||||
|
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||||
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
// \App\Http\Middleware\ForceJsonResponse::class,
|
||||||
|
\App\Http\Middleware\UnmangleRequest::class,
|
||||||
|
'useSanctumGuard',
|
||||||
|
\App\Http\Middleware\LogRequest::class,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application's middleware aliases.
|
||||||
|
*
|
||||||
|
* Aliases may be used to conveniently assign middleware to routes and groups.
|
||||||
|
*
|
||||||
|
* @var array<string, class-string|string>
|
||||||
|
*/
|
||||||
|
protected $middlewareAliases = [
|
||||||
|
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||||
|
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||||
|
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
|
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||||
|
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||||
|
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||||
|
'unmangle' => \App\Http\Middleware\UnmangleRequest::class,
|
||||||
|
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||||
|
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||||
|
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||||
|
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||||
|
'useSanctumGuard' => \App\Http\Middleware\UseSanctumGuard::class
|
||||||
|
];
|
||||||
|
}
|
||||||
23
app.old/Http/Middleware/Authenticate.php
Normal file
23
app.old/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||||
|
|
||||||
|
class Authenticate extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the path the user should be redirected to when they are not authenticated.
|
||||||
|
*
|
||||||
|
* @param mixed $request Request.
|
||||||
|
* @return ?string
|
||||||
|
*/
|
||||||
|
protected function redirectTo(mixed $request): ?string
|
||||||
|
{
|
||||||
|
if ($request->expectsJson() === false) {
|
||||||
|
return route('login');
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
app.old/Http/Middleware/EncryptCookies.php
Normal file
17
app.old/Http/Middleware/EncryptCookies.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||||
|
|
||||||
|
class EncryptCookies extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The names of the cookies that should not be encrypted.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -10,11 +11,9 @@ class ForceJsonResponse
|
|||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next)
|
public function handle(Request $request, Closure $next): Response
|
||||||
{
|
{
|
||||||
$request->headers->set('Accept', 'application/json');
|
$request->headers->set('Accept', 'application/json');
|
||||||
return $next($request);
|
return $next($request);
|
||||||
36
app.old/Http/Middleware/LogRequest.php
Normal file
36
app.old/Http/Middleware/LogRequest.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Models\AnalyticsItemRequest;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class LogRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Illuminate\Http\Request $request HTTP Request.
|
||||||
|
* @param \Closure $next Closure.
|
||||||
|
* @return Symfony\Component\HttpFoundation\Response
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
// Make it an after middleware
|
||||||
|
$response = $next($request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
AnalyticsItemRequest::create([
|
||||||
|
'type' => 'apirequest',
|
||||||
|
'path' => $request->path(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
} catch (\Error $e) {
|
||||||
|
report($e);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
app.old/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app.old/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||||
|
|
||||||
|
class PreventRequestsDuringMaintenance extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The URIs that should be reachable while maintenance mode is enabled.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
33
app.old/Http/Middleware/RedirectIfAuthenticated.php
Normal file
33
app.old/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use App\Providers\RouteServiceProvider;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class RedirectIfAuthenticated
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Request $request Request.
|
||||||
|
* @param \Closure $next Closure.
|
||||||
|
* @param string|null ...$guards Guards.
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||||
|
{
|
||||||
|
$guards = empty($guards) === true ? [null] : $guards;
|
||||||
|
|
||||||
|
foreach ($guards as $guard) {
|
||||||
|
if (Auth::guard($guard)->check() === true) {
|
||||||
|
return redirect(RouteServiceProvider::HOME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app.old/Http/Middleware/TrimStrings.php
Normal file
19
app.old/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||||
|
|
||||||
|
class TrimStrings extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The names of the attributes that should not be trimmed.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
'current_password',
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
];
|
||||||
|
}
|
||||||
20
app.old/Http/Middleware/TrustHosts.php
Normal file
20
app.old/Http/Middleware/TrustHosts.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||||
|
|
||||||
|
class TrustHosts extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the host patterns that should be trusted.
|
||||||
|
*
|
||||||
|
* @return array<int, string|null>
|
||||||
|
*/
|
||||||
|
public function hosts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$this->allSubdomainsOfApplicationUrl(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app.old/Http/Middleware/TrustProxies.php
Normal file
25
app.old/Http/Middleware/TrustProxies.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TrustProxies extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The trusted proxies for this application.
|
||||||
|
*
|
||||||
|
* @var array<int, string>|string|null
|
||||||
|
*/
|
||||||
|
protected $proxies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The headers that should be used to detect proxies.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
// @codingStandardsIgnoreStart
|
||||||
|
protected $headers = (Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB);
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
}
|
||||||
47
app.old/Http/Middleware/UnmangleRequest.php
Normal file
47
app.old/Http/Middleware/UnmangleRequest.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use App\Providers\RouteServiceProvider;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class UnmangleRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Request $request Request.
|
||||||
|
* @param \Closure $next Next.
|
||||||
|
* @param string|null ...$guards Guards.
|
||||||
|
* @return Response response.
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||||
|
{
|
||||||
|
if (isset($_SERVER['QUERY_STRING']) === true) {
|
||||||
|
$params = $request->all();
|
||||||
|
|
||||||
|
$string = $_SERVER['QUERY_STRING'];
|
||||||
|
$parts = explode('&', $string);
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
$key = $part;
|
||||||
|
$splitPos = strpos($key, '=');
|
||||||
|
if ($splitPos !== false) {
|
||||||
|
$key = urldecode(substr($key, 0, $splitPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
$replace_key = str_replace('.', '_', $key);
|
||||||
|
if (strpos($key, '.') !== false && array_key_exists($replace_key, $params) === true) {
|
||||||
|
$params[$key] = $params[$replace_key];
|
||||||
|
unset($params[$replace_key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->replace($params);
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
app.old/Http/Middleware/UseSanctumGuard.php
Normal file
24
app.old/Http/Middleware/UseSanctumGuard.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class UseSanctumGuard
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Request $request Request object.
|
||||||
|
* @param \Closure $next Closure object.
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
Auth::shouldUse('sanctum');
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app.old/Http/Middleware/ValidateSignature.php
Normal file
22
app.old/Http/Middleware/ValidateSignature.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||||
|
|
||||||
|
class ValidateSignature extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The names of the query string parameters that should be ignored.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
// 'fbclid',
|
||||||
|
// 'utm_campaign',
|
||||||
|
// 'utm_content',
|
||||||
|
// 'utm_medium',
|
||||||
|
// 'utm_source',
|
||||||
|
// 'utm_term',
|
||||||
|
];
|
||||||
|
}
|
||||||
17
app.old/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app.old/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||||
|
|
||||||
|
class VerifyCsrfToken extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The URIs that should be excluded from CSRF verification.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ class AnalyticsRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function postRules()
|
public function postRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'type' => 'required|string',
|
'type' => 'required|string',
|
||||||
@@ -23,7 +23,7 @@ class AnalyticsRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function putRules()
|
public function putRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
@@ -11,7 +11,7 @@ class ArticleRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function postRules()
|
public function postRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'slug' => 'required|string|min:6|unique:articles',
|
'slug' => 'required|string|min:6|unique:articles',
|
||||||
@@ -28,7 +28,7 @@ class ArticleRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function putRules()
|
public function putRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'slug' => [
|
'slug' => [
|
||||||
@@ -11,7 +11,7 @@ class AuthLoginRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|string|min:6|max:255',
|
'email' => 'required|string|min:6|max:255',
|
||||||
@@ -12,11 +12,15 @@ class BaseRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function authorize()
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
if (request()->isMethod('post') === true && method_exists($this, 'postAuthorize') === true) {
|
if (request()->isMethod('post') === true && method_exists($this, 'postAuthorize') === true) {
|
||||||
return $this->postAuthorize();
|
return $this->postAuthorize();
|
||||||
} elseif ((request()->isMethod('put') === true || request()->isMethod('patch') === true) && method_exists($this, 'putAuthorize') === true) {
|
} elseif (
|
||||||
|
(
|
||||||
|
request()->isMethod('put') === true || request()->isMethod('patch') === true
|
||||||
|
) && method_exists($this, 'putAuthorize') === true
|
||||||
|
) {
|
||||||
return $this->putAuthorize();
|
return $this->putAuthorize();
|
||||||
} elseif (request()->isMethod('delete') === true && method_exists($this, 'destroyAuthorize') === true) {
|
} elseif (request()->isMethod('delete') === true && method_exists($this, 'destroyAuthorize') === true) {
|
||||||
return $this->deleteAuthorize();
|
return $this->deleteAuthorize();
|
||||||
@@ -30,7 +34,7 @@ class BaseRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
@@ -40,7 +44,11 @@ class BaseRequest extends FormRequest
|
|||||||
|
|
||||||
if (method_exists($this, 'postRules') === true && request()->isMethod('post') === true) {
|
if (method_exists($this, 'postRules') === true && request()->isMethod('post') === true) {
|
||||||
$rules = $this->mergeRules($rules, $this->postRules());
|
$rules = $this->mergeRules($rules, $this->postRules());
|
||||||
} elseif (method_exists($this, 'putRules') === true && (request()->isMethod('put') === true || request()->isMethod('patch') === true)) {
|
} elseif (
|
||||||
|
method_exists($this, 'putRules') === true && (
|
||||||
|
request()->isMethod('put') === true || request()->isMethod('patch') === true
|
||||||
|
)
|
||||||
|
) {
|
||||||
$rules = $this->mergeRules($rules, $this->putRules());
|
$rules = $this->mergeRules($rules, $this->putRules());
|
||||||
} elseif (method_exists($this, 'destroyRules') === true && request()->isMethod('delete') === true) {
|
} elseif (method_exists($this, 'destroyRules') === true && request()->isMethod('delete') === true) {
|
||||||
$rules = $this->mergeRules($rules, $this->destroyRules());
|
$rules = $this->mergeRules($rules, $this->destroyRules());
|
||||||
@@ -56,7 +64,7 @@ class BaseRequest extends FormRequest
|
|||||||
* @param array $collection2 The second collection of rules to merge.
|
* @param array $collection2 The second collection of rules to merge.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function mergeRules(array $collection1, array $collection2)
|
private function mergeRules(array $collection1, array $collection2): array
|
||||||
{
|
{
|
||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ class ContactSendRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => 'required|max:255',
|
'name' => 'required|max:255',
|
||||||
@@ -11,7 +11,7 @@ class EventRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function baseRules()
|
public function baseRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => 'min:6',
|
'title' => 'min:6',
|
||||||
@@ -23,7 +23,7 @@ class EventRequest extends BaseRequest
|
|||||||
'end_at' => 'date|after:start_date',
|
'end_at' => 'date|after:start_date',
|
||||||
'publish_at' => 'date|nullable',
|
'publish_at' => 'date|nullable',
|
||||||
'status' => [
|
'status' => [
|
||||||
Rule::in(['draft', 'soon', 'open', 'closed', 'cancelled']),
|
Rule::in(['draft', 'soon', 'open', 'closed', 'cancelled', 'scheduled', 'full']),
|
||||||
],
|
],
|
||||||
'registration_type' => [
|
'registration_type' => [
|
||||||
Rule::in(['none', 'email', 'link', 'message']),
|
Rule::in(['none', 'email', 'link', 'message']),
|
||||||
@@ -34,6 +34,7 @@ class EventRequest extends BaseRequest
|
|||||||
Rule::when(strcasecmp('message', $this->attributes->get('registration_type')) == 0, 'required|message'),
|
Rule::when(strcasecmp('message', $this->attributes->get('registration_type')) == 0, 'required|message'),
|
||||||
],
|
],
|
||||||
'hero' => 'uuid|exists:media,id',
|
'hero' => 'uuid|exists:media,id',
|
||||||
|
'location_url' => 'sometimes|string|max:255',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ class EventRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
protected function postRules()
|
protected function postRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => 'required',
|
'title' => 'required',
|
||||||
33
app.old/Http/Requests/MediaRequest.php
Normal file
33
app.old/Http/Requests/MediaRequest.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class MediaRequest extends BaseRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* POST request rules
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function postRules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'job_id' => [
|
||||||
|
Rule::requiredIf(function () {
|
||||||
|
return request()->has('chunk') && request('chunk') != 1;
|
||||||
|
}),
|
||||||
|
'string',
|
||||||
|
],
|
||||||
|
'name' => [
|
||||||
|
Rule::requiredIf(function () {
|
||||||
|
return request()->has('chunk') && request('chunk') == 1;
|
||||||
|
}),
|
||||||
|
'string',
|
||||||
|
],
|
||||||
|
'chunk' => 'required_with:chunk_count|integer|min:1|max:999|lte:chunk_count',
|
||||||
|
'chunk_count' => 'required_with:chunk|integer|min:1',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ class ShortlinkRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function postRules()
|
public function postRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'code' => 'required|string|max:255|min:2|unique:shortlinks',
|
'code' => 'required|string|max:255|min:2|unique:shortlinks',
|
||||||
@@ -24,7 +24,7 @@ class ShortlinkRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function putRules()
|
public function putRules(): array
|
||||||
{
|
{
|
||||||
$shortlink = $this->route('shortlink');
|
$shortlink = $this->route('shortlink');
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class SubscriptionRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function postRules()
|
public function postRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|email|unique:subscriptions',
|
'email' => 'required|email|unique:subscriptions',
|
||||||
@@ -24,7 +24,7 @@ class SubscriptionRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function destroyRules()
|
public function destroyRules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|email',
|
'email' => 'required|email',
|
||||||
@@ -37,7 +37,7 @@ class SubscriptionRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function messages()
|
public function messages(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email.unique' => 'This email address has already subscribed',
|
'email.unique' => 'This email address has already subscribed',
|
||||||
@@ -12,7 +12,7 @@ class UserForgotPasswordRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|exists:users,email',
|
'email' => 'required|exists:users,email',
|
||||||
@@ -12,7 +12,7 @@ class UserRegisterRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'display_name' => ['required','string','max:255', new Uniqueish('users')],
|
'display_name' => ['required','string','max:255', new Uniqueish('users')],
|
||||||
@@ -15,14 +15,18 @@ class UserRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function postRules()
|
public function postRules(): array
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$isAdminUser = $user->hasPermission('admin/users');
|
$isAdminUser = $user->hasPermission('admin/users');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'first_name' => ($isAdminUser === true ? 'required_with:last_name,display_name,phone' : 'required') . '|string|max:255|min:2',
|
'first_name' => (
|
||||||
'last_name' => ($isAdminUser === true ? 'required_with:first_name,display_name,phone' : 'required') . '|string|max:255|min:2',
|
$isAdminUser === true ? 'required_with:last_name,display_name,phone' : 'required'
|
||||||
|
) . '|string|max:255|min:2',
|
||||||
|
'last_name' => (
|
||||||
|
$isAdminUser === true ? 'required_with:first_name,display_name,phone' : 'required'
|
||||||
|
) . '|string|max:255|min:2',
|
||||||
'display_name' => [
|
'display_name' => [
|
||||||
$isAdminUser === true ? 'required_with:first_name,last_name,phone' : 'required',
|
$isAdminUser === true ? 'required_with:first_name,last_name,phone' : 'required',
|
||||||
'string',
|
'string',
|
||||||
@@ -40,7 +44,7 @@ class UserRequest extends BaseRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function putRules()
|
public function putRules(): array
|
||||||
{
|
{
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$ruleUser = $this->route('user');
|
$ruleUser = $this->route('user');
|
||||||
@@ -12,7 +12,7 @@ class UserResendVerifyEmailRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'email' => 'required|exists:users,email',
|
'email' => 'required|exists:users,email',
|
||||||
@@ -12,7 +12,7 @@ class UserResetPasswordRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'code' => 'required|digits:6',
|
'code' => 'required|digits:6',
|
||||||
@@ -12,7 +12,7 @@ class UserVerifyEmailRequest extends FormRequest
|
|||||||
*
|
*
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'code' => 'required|digits:6',
|
'code' => 'required|digits:6',
|
||||||
393
app.old/Jobs/MediaWorkerJob.php
Normal file
393
app.old/Jobs/MediaWorkerJob.php
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\Media;
|
||||||
|
use App\Models\MediaJob;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use FFMpeg;
|
||||||
|
use FFMpeg\Coordinate\Dimension;
|
||||||
|
use FFMpeg\FFProbe;
|
||||||
|
use FFMpeg\Format\VideoInterface;
|
||||||
|
use Intervention\Image\Facades\Image;
|
||||||
|
|
||||||
|
/** @property on $format */
|
||||||
|
class MediaWorkerJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
use InteractsWithQueue;
|
||||||
|
use Queueable;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MediaJob item
|
||||||
|
*
|
||||||
|
* @var MediaJob
|
||||||
|
*/
|
||||||
|
protected $mediaJob;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*
|
||||||
|
* @param MediaJob $mediaJob The mediaJob model.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(MediaJob $mediaJob)
|
||||||
|
{
|
||||||
|
$this->mediaJob = $mediaJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
$media = $this->mediaJob->media()->first();
|
||||||
|
$newMedia = false;
|
||||||
|
$data = json_decode($this->mediaJob->data, true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// FILE
|
||||||
|
if (array_key_exists('file', $data) === true) {
|
||||||
|
if (file_exists($data['file']) === false) {
|
||||||
|
$this->throwMediaJobFailure('temporary upload file no longer exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert HEIC files to JPG
|
||||||
|
$fileExtension = File::extension($data['file']);
|
||||||
|
if ($fileExtension === 'heic') {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'converting image');
|
||||||
|
|
||||||
|
// Get the path without the file name
|
||||||
|
$uploadedFileDirectory = dirname($data['file']);
|
||||||
|
|
||||||
|
// Convert the HEIC file to JPG
|
||||||
|
$jpgFileName = pathinfo($data['file'], PATHINFO_FILENAME) . '.jpg';
|
||||||
|
$jpgFilePath = $uploadedFileDirectory . '/' . $jpgFileName;
|
||||||
|
if (file_exists($jpgFilePath) === true) {
|
||||||
|
$this->throwMediaJobFailure('file already exists on server');
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::make($data['file'])->save($jpgFilePath);
|
||||||
|
|
||||||
|
// Update the uploaded file path and file name
|
||||||
|
unlink($data['file']);
|
||||||
|
$data['file'] = $jpgFileName;
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
// get security
|
||||||
|
$security = [];
|
||||||
|
if ($media === null) {
|
||||||
|
if (array_key_exists('security', $data) === true) {
|
||||||
|
$security = $data['security'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$security['type'] = $media->security_type;
|
||||||
|
$security['data'] = $media->security_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get storage
|
||||||
|
$storage = '';
|
||||||
|
if ($media === null) {
|
||||||
|
if (array_key_exists('storage', $data) === true) {
|
||||||
|
$storage = $data['storage'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$storage = $media->storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($storage === '') {
|
||||||
|
if (count($security) === 0 || $security['type'] === '') {
|
||||||
|
if (strpos($data['mime_type'], 'image/') === 0) {
|
||||||
|
$storage = 'local';
|
||||||
|
} else {
|
||||||
|
$storage = 'cdn';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$storage = 'private';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file already exists
|
||||||
|
$exists = Storage::disk($storage)->exists($data['name']);
|
||||||
|
if ($exists === true) {
|
||||||
|
if (array_key_exists('noreplace', $data) === true && isTrue($data['noreplace']) === true) {
|
||||||
|
$this->throwMediaJobFailure('file already exists on server');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($exists === true) {
|
||||||
|
$pathInfo = pathinfo($data['name']);
|
||||||
|
$basename = $pathInfo['filename'];
|
||||||
|
$extension = $pathInfo['extension'];
|
||||||
|
$index = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
$index++;
|
||||||
|
$data['name'] = $basename . '-' . $index . '.' . $extension;
|
||||||
|
} while (Storage::disk($storage)->exists($data['name']) === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($media === null) {
|
||||||
|
$newMedia = true;
|
||||||
|
$media = new Media([
|
||||||
|
'user_id' => $this->mediaJob->user_id,
|
||||||
|
'title' => $data['title'],
|
||||||
|
'name' => $data['name'],
|
||||||
|
'mime_type' => $data['mime_type'],
|
||||||
|
'size' => $data['size'],
|
||||||
|
'security_type' => $data['security']['type'],
|
||||||
|
'security_data' => $data['security']['data'],
|
||||||
|
'storage' => $storage,
|
||||||
|
]);
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
$media->setStagingFile($data['file']);
|
||||||
|
} else {
|
||||||
|
if ($media === null) {
|
||||||
|
$this->throwMediaJobFailure('The media item no longer exists');
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
if (array_key_exists('transform', $data) === true) {
|
||||||
|
$media->createStagingFile();
|
||||||
|
|
||||||
|
// Modifications
|
||||||
|
if (strpos($media->mime_type, 'image/') === 0) {
|
||||||
|
$modified = false;
|
||||||
|
$image = Image::make($media->getStagingFilePath());
|
||||||
|
|
||||||
|
// ROTATE
|
||||||
|
if (array_key_exists("rotate", $data['transform']) === true) {
|
||||||
|
$rotate = intval($data['transform']['rotate']);
|
||||||
|
if ($rotate !== 0) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'rotating image');
|
||||||
|
$image = $image->rotate($rotate);
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FLIP-H/V
|
||||||
|
if (array_key_exists('flip', $data['transform']) === true) {
|
||||||
|
if (stripos($data['transform']['flip'], 'h') !== false) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'flipping image');
|
||||||
|
$image = $image->flip('h');
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripos($data['transform']['flip'], 'v') !== false) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'flipping image');
|
||||||
|
$image = $image->flip('v');
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CROP
|
||||||
|
if (array_key_exists("crop", $data['transform']) === true) {
|
||||||
|
$cropData = $data['transform']['crop'];
|
||||||
|
$width = intval(arrayDefaultValue("width", $cropData, $image->getWidth()));
|
||||||
|
$height = intval(arrayDefaultValue("height", $cropData, $image->getHeight()));
|
||||||
|
$x = intval(arrayDefaultValue("x", $cropData, 0));
|
||||||
|
$y = intval(arrayDefaultValue("y", $cropData, 0));
|
||||||
|
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'cropping image');
|
||||||
|
$image = $image->crop($width, $height, $x, $y);
|
||||||
|
$modified = true;
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
if ($modified === true) {
|
||||||
|
$image->save();
|
||||||
|
}
|
||||||
|
} elseif (strpos($data['mime_type'], 'video/') === 0) {
|
||||||
|
$stagingFilePath = $media->getStagingFilePath();
|
||||||
|
$ffmpeg = FFMpeg\FFMpeg::create();
|
||||||
|
$video = $ffmpeg->open($stagingFilePath);
|
||||||
|
$format = $this->detectVideoFormat($stagingFilePath);
|
||||||
|
$modified = false;
|
||||||
|
|
||||||
|
if ($format === null) {
|
||||||
|
$this->mediaJob->setStatusFailed('Unsupported video format');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var FFMpeg\Media\Video::filters */
|
||||||
|
$filters = $video->filters();
|
||||||
|
|
||||||
|
// ROTATE
|
||||||
|
if (array_key_exists("rotate", $data['transform']) === true) {
|
||||||
|
$rotate = intval($data['transform']['rotate']);
|
||||||
|
$rotate = (($rotate % 360 + 360) % 360); // remove excess rotations
|
||||||
|
$rotate = intval(round($rotate / 90) * 90); // round to nearest 90%
|
||||||
|
|
||||||
|
if ($rotate > 0) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'rotating video');
|
||||||
|
|
||||||
|
if ($rotate === 90) {
|
||||||
|
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_270);
|
||||||
|
$modified = true;
|
||||||
|
} elseif ($rotate === 180) {
|
||||||
|
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_180);
|
||||||
|
$modified = true;
|
||||||
|
} elseif ($rotate === 270) {
|
||||||
|
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_90);
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FLIP-H/V
|
||||||
|
if (array_key_exists('flip', $data['transform']) === true) {
|
||||||
|
if (stripos($data['transform']['flip'], 'h') !== false) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'flipping video');
|
||||||
|
$filters->hflip()->synchronize();
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripos($data['transform']['flip'], 'v') !== false) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'flipping video');
|
||||||
|
$filters->vflip()->synchronize();
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CROP
|
||||||
|
if (array_key_exists("crop", $data['transform']) === true) {
|
||||||
|
$cropData = $data['transform']['crop'];
|
||||||
|
$videoStream = $video->getStreams()->videos()->first();
|
||||||
|
|
||||||
|
$width = intval(arrayDefaultValue("width", $cropData, $videoStream->get('width')));
|
||||||
|
$height = intval(arrayDefaultValue("height", $cropData, $videoStream->get('height')));
|
||||||
|
$x = intval(arrayDefaultValue("x", $cropData, 0));
|
||||||
|
$y = intval(arrayDefaultValue("y", $cropData, 0));
|
||||||
|
|
||||||
|
$cropDimension = new Dimension($width, $height);
|
||||||
|
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'cropping video');
|
||||||
|
$filters->crop($cropDimension, $x, $y)->synchronize();
|
||||||
|
$modified = true;
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
$tempFilePath = generateTempFilePath(pathinfo($stagingFilePath, PATHINFO_EXTENSION));
|
||||||
|
if (method_exists($format, 'on') === true) {
|
||||||
|
$mediaJob = $this->mediaJob;
|
||||||
|
$format->on('progress', function ($video, $format, $percentage) use ($mediaJob) {
|
||||||
|
$mediaJob->setStatusProcessing($percentage, 100, 'transcoded');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($modified === true) {
|
||||||
|
$video->save($format, $tempFilePath);
|
||||||
|
$media->changeStagingFile($tempFilePath);
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
}//end if
|
||||||
|
|
||||||
|
// Update attributes
|
||||||
|
if (array_key_exists('title', $data) === true) {
|
||||||
|
$media->title = $data['title'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relocate file (if requested)
|
||||||
|
if (array_key_exists('security', $data) === true && array_key_exists('type', $data['security']) === true) {
|
||||||
|
$media->security_type = $data['security']['type'];
|
||||||
|
$media->security_data = $data['security']['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('storage', $data) === true) {
|
||||||
|
if ($media->storage !== $data['storage']) {
|
||||||
|
$media->createStagingFile();
|
||||||
|
Storage::disk($media->storage)->delete($media->name);
|
||||||
|
$media->storage = $data['storage'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish media object
|
||||||
|
if ($media->hasStagingFile() === true) {
|
||||||
|
$this->mediaJob->setStatusProcessing(0, 0, 'transferring to cdn');
|
||||||
|
$media->deleteFile();
|
||||||
|
$media->saveStagingFile(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$media->save();
|
||||||
|
$this->mediaJob->media_id = $media->id;
|
||||||
|
$this->mediaJob->setStatusComplete();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
if ($this->mediaJob->status !== 'failed') {
|
||||||
|
$this->mediaJob->setStatusFailed('Unexpected server error occurred');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($media !== null) {
|
||||||
|
$media->deleteStagingFile();
|
||||||
|
if ($newMedia === true) {
|
||||||
|
$media->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::error($e->getMessage() . "\n" . $e->getFile() . " - " . $e->getLine() . "\n" . $e->getTraceAsString());
|
||||||
|
$this->fail($e);
|
||||||
|
}//end try
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects the format of a video using FFProbe
|
||||||
|
*
|
||||||
|
* @param string $videoPath The video file path.
|
||||||
|
* @return VideoInterface | null
|
||||||
|
*/
|
||||||
|
public function detectVideoFormat(string $videoPath): VideoInterface | null
|
||||||
|
{
|
||||||
|
$ffprobe = FFProbe::create();
|
||||||
|
|
||||||
|
$videoStream = $ffprobe
|
||||||
|
->streams($videoPath) // Provide the path to the video file
|
||||||
|
->videos() // Filter video streams
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$codecName = $videoStream->get('codec_name');
|
||||||
|
|
||||||
|
$codecToFormatClass = [
|
||||||
|
'h264' => 'FFMpeg\Format\Video\X264',
|
||||||
|
'wmv2' => 'FFMpeg\Format\Video\WMV',
|
||||||
|
'vp9' => 'FFMpeg\Format\Video\WebM',
|
||||||
|
'theora' => 'FFMpeg\Format\Video\Ogg',
|
||||||
|
'mpeg4' => 'FFMpeg\Format\Video\Mpeg4',
|
||||||
|
// Add more mappings as needed
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isset($codecToFormatClass[$codecName]) === false) {
|
||||||
|
Log::info("Unsupported codec: $codecName");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$formatClassName = $codecToFormatClass[$codecName];
|
||||||
|
|
||||||
|
if (class_exists($formatClassName) === false) {
|
||||||
|
Log::info("Format class does not exist: $formatClassName");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new $formatClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set failure status of MediaJob and throw exception.
|
||||||
|
*
|
||||||
|
* @param string $error The failure message.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function throwMediaJobFailure(string $error): void
|
||||||
|
{
|
||||||
|
$this->mediaJob->setStatusFailed($error);
|
||||||
|
throw new \Exception($error);
|
||||||
|
}
|
||||||
|
}
|
||||||
57
app.old/Jobs/SendEmailJob.php
Normal file
57
app.old/Jobs/SendEmailJob.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
|
class SendEmailJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
use InteractsWithQueue;
|
||||||
|
use Queueable;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mail to receipt
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $to;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mailable item
|
||||||
|
*
|
||||||
|
* @var Mailable
|
||||||
|
*/
|
||||||
|
public $mailable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*
|
||||||
|
* @param string $to The email receipient.
|
||||||
|
* @param Mailable $mailable The mailable.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(string $to, Mailable $mailable)
|
||||||
|
{
|
||||||
|
$this->to = $to;
|
||||||
|
$this->mailable = $mailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
Mail::to($this->to)->send($this->mailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,9 +55,9 @@ class ChangeEmailVerify extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '👋🏻 Lets change your email!',
|
subject: '👋🏻 Lets change your email!',
|
||||||
@@ -67,9 +67,9 @@ class ChangeEmailVerify extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.change_email_verify',
|
view: 'emails.user.change_email_verify',
|
||||||
@@ -55,9 +55,9 @@ class ChangedEmail extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '👍 Your email has been changed!',
|
subject: '👍 Your email has been changed!',
|
||||||
@@ -67,9 +67,9 @@ class ChangedEmail extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.changed_email',
|
view: 'emails.user.changed_email',
|
||||||
@@ -37,9 +37,9 @@ class ChangedPassword extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '👍 Your password has been changed!',
|
subject: '👍 Your password has been changed!',
|
||||||
@@ -49,9 +49,9 @@ class ChangedPassword extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.changed_password',
|
view: 'emails.user.changed_password',
|
||||||
@@ -54,9 +54,9 @@ class Contact extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: config('contact.contact_subject'),
|
subject: config('contact.contact_subject'),
|
||||||
@@ -66,9 +66,9 @@ class Contact extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.contact',
|
view: 'emails.user.contact',
|
||||||
@@ -46,9 +46,9 @@ class EmailVerify extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '👋🏻 Welcome to STEMMechanics!',
|
subject: '👋🏻 Welcome to STEMMechanics!',
|
||||||
@@ -58,9 +58,9 @@ class EmailVerify extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.email_verify',
|
view: 'emails.user.email_verify',
|
||||||
59
app.old/Mail/ExceptionMail.php
Normal file
59
app.old/Mail/ExceptionMail.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ExceptionMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message envelope.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
|
*/
|
||||||
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
|
return new Envelope(
|
||||||
|
subject: 'Exception Mail',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message content definition.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
|
*/
|
||||||
|
public function content(): Content
|
||||||
|
{
|
||||||
|
return new Content(
|
||||||
|
view: 'view.name',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attachments for the message.
|
||||||
|
*
|
||||||
|
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,9 +46,9 @@ class ForgotPassword extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '🤦 Forgot your password?',
|
subject: '🤦 Forgot your password?',
|
||||||
@@ -58,9 +58,9 @@ class ForgotPassword extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.forgot_password',
|
view: 'emails.user.forgot_password',
|
||||||
@@ -37,9 +37,9 @@ class SubscriptionConfirm extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: '🗞️ You\'re on the mailing list!',
|
subject: '🗞️ You\'re on the mailing list!',
|
||||||
@@ -49,9 +49,9 @@ class SubscriptionConfirm extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.subscription_confirm',
|
view: 'emails.user.subscription_confirm',
|
||||||
@@ -37,9 +37,9 @@ class SubscriptionUnsubscribed extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message envelope.
|
* Get the message envelope.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Envelope
|
* @return Illuminate\Mail\Mailables\Envelope
|
||||||
*/
|
*/
|
||||||
public function envelope()
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: 'You have been unsubscribed',
|
subject: 'You have been unsubscribed',
|
||||||
@@ -49,9 +49,9 @@ class SubscriptionUnsubscribed extends Mailable
|
|||||||
/**
|
/**
|
||||||
* Get the message content definition.
|
* Get the message content definition.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Mail\Mailables\Content
|
* @return Illuminate\Mail\Mailables\Content
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content(): Content
|
||||||
{
|
{
|
||||||
return new Content(
|
return new Content(
|
||||||
view: 'emails.user.subscription_unsubscribed',
|
view: 'emails.user.subscription_unsubscribed',
|
||||||
73
app.old/Models/AnalyticsItemRequest.php
Normal file
73
app.old/Models/AnalyticsItemRequest.php
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class AnalyticsItemRequest extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $table = 'analytics_requests';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'type',
|
||||||
|
'path'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Boot.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
static::creating(function (AnalyticsItemRequest $analytics) {
|
||||||
|
if (isset($analytics->session_id) !== true) {
|
||||||
|
$request = request();
|
||||||
|
if ($request !== null) {
|
||||||
|
$session = AnalyticsSession::where('ip', $request->ip())
|
||||||
|
->where('useragent', $request->userAgent())
|
||||||
|
->where('ended_at', '>=', now()->subMinutes(30))
|
||||||
|
->first();
|
||||||
|
if ($session === null) {
|
||||||
|
$session = AnalyticsSession::create([
|
||||||
|
'ip' => $request->ip(),
|
||||||
|
'useragent' => $request->userAgent(),
|
||||||
|
'ended_at' => now()
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$session->update(['ended_at' => now()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$analytics->session_id = $session->id;
|
||||||
|
}
|
||||||
|
}//end if
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Analytics Session model.
|
||||||
|
*
|
||||||
|
* @return BelongsTo
|
||||||
|
*/
|
||||||
|
public function session(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AnalyticsSession::class, 'id', 'session_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app.old/Models/AnalyticsSession.php
Normal file
44
app.old/Models/AnalyticsSession.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
|
class AnalyticsSession extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'ip',
|
||||||
|
'useragent',
|
||||||
|
'ended_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the "useragent" attribute.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUseragentAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['useragent'] = $value !== null ? $value : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the related requests for this session.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function requests(): HasMany {
|
||||||
|
return $this->hasMany(AnalyticsItemRequest::class, 'session_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,15 +2,19 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Traits\HasAttachments;
|
||||||
|
use App\Traits\HasGallery;
|
||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class Article extends Model
|
class Article extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use Uuids;
|
use Uuids;
|
||||||
|
use HasGallery;
|
||||||
|
use HasAttachments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -30,20 +34,10 @@ class Article extends Model
|
|||||||
/**
|
/**
|
||||||
* Get the article user
|
* Get the article user
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all of the article's attachments.
|
|
||||||
*
|
|
||||||
* @return MorphMany
|
|
||||||
*/
|
|
||||||
public function attachments()
|
|
||||||
{
|
|
||||||
return $this->morphMany('App\Models\Attachment', 'attachable');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
86
app.old/Models/Attachment.php
Normal file
86
app.old/Models/Attachment.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class Attachment extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'media_id',
|
||||||
|
'private',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default attributes.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $attributes = [
|
||||||
|
'private' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the media for this attachment.
|
||||||
|
*
|
||||||
|
* @return BelongsTo
|
||||||
|
*/
|
||||||
|
public function media(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Media::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get associated Media object.
|
||||||
|
*
|
||||||
|
* @return null|Media
|
||||||
|
*/
|
||||||
|
public function getMediaAttribute(): ?Media
|
||||||
|
{
|
||||||
|
$mediaId = '0';
|
||||||
|
$media = null;
|
||||||
|
|
||||||
|
if (Cache::has("attachment:{$this->id}:media") === true) {
|
||||||
|
$mediaId = Cache::get("attachment:{$this->id}:media");
|
||||||
|
} else {
|
||||||
|
$media = $this->media()->first();
|
||||||
|
if ($media === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mediaId = $media->id;
|
||||||
|
Cache::put("attachment:{$this->id}:media", $mediaId, now()->addDays(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Cache::remember("media:{$mediaId}", now()->addDays(28), function () use ($media) {
|
||||||
|
if ($media !== null) {
|
||||||
|
return $media;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->media()->first();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the media for this item.
|
||||||
|
*
|
||||||
|
* @param Media $media The media model.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setMediaAttribute(Media $media): void
|
||||||
|
{
|
||||||
|
$this->media()->associate($media)->save();
|
||||||
|
Cache::put("attachment:{$this->id}:media", $media->id, now()->addDays(28));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Traits\HasAttachments;
|
||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -10,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
|
|||||||
|
|
||||||
class Event extends Model
|
class Event extends Model
|
||||||
{
|
{
|
||||||
|
use HasAttachments;
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use Uuids;
|
use Uuids;
|
||||||
|
|
||||||
@@ -33,25 +35,16 @@ class Event extends Model
|
|||||||
'content',
|
'content',
|
||||||
'price',
|
'price',
|
||||||
'ages',
|
'ages',
|
||||||
|
'open_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all of the article's attachments.
|
|
||||||
*
|
|
||||||
* @return MorphMany
|
|
||||||
*/
|
|
||||||
public function attachments()
|
|
||||||
{
|
|
||||||
return $this->morphMany('App\Models\Attachment', 'attachable');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the associated users.
|
* Get all the associated users.
|
||||||
*
|
*
|
||||||
* @return BelongsToMany
|
* @return BelongsToMany
|
||||||
*/
|
*/
|
||||||
public function users()
|
public function users(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(User::class, 'event_user', 'event_id', 'user_id');
|
return $this->belongsToMany(User::class, 'event_user', 'event_id', 'user_id');
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
|||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class EventUser extends Model
|
class EventUser extends Model
|
||||||
{
|
{
|
||||||
@@ -25,9 +26,9 @@ class EventUser extends Model
|
|||||||
/**
|
/**
|
||||||
* Get the event for this attachment.
|
* Get the event for this attachment.
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function event()
|
public function event(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Event::class);
|
return $this->belongsTo(Event::class);
|
||||||
}
|
}
|
||||||
@@ -35,9 +36,9 @@ class EventUser extends Model
|
|||||||
/**
|
/**
|
||||||
* Get the user for this attachment.
|
* Get the user for this attachment.
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
107
app.old/Models/Gallery.php
Normal file
107
app.old/Models/Gallery.php
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Traits\Uuids;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class Gallery extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
use Uuids;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'media_id',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boot the model.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected static function boot(): void
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
$clearCache = function ($gallery) {
|
||||||
|
Cache::forget("gallery:{$gallery->id}:media");
|
||||||
|
};
|
||||||
|
|
||||||
|
static::saving($clearCache);
|
||||||
|
static::deleting($clearCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get gallery addendum model.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Database\Eloquent\Relations\MorphTo Addenum model.
|
||||||
|
*/
|
||||||
|
public function addendum(): MorphTo
|
||||||
|
{
|
||||||
|
return $this->morphTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the media for this item.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo The media model.
|
||||||
|
*/
|
||||||
|
public function media(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Media::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the media for this item.
|
||||||
|
*
|
||||||
|
* @return null|Media The media model.
|
||||||
|
*/
|
||||||
|
public function getMediaAttribute(): ?Media
|
||||||
|
{
|
||||||
|
$mediaId = '0';
|
||||||
|
$media = null;
|
||||||
|
|
||||||
|
if (Cache::has("gallery:{$this->id}:media") === true) {
|
||||||
|
$mediaId = Cache::get("gallery:{$this->id}:media");
|
||||||
|
} else {
|
||||||
|
$media = $this->media()->first();
|
||||||
|
if ($media === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mediaId = $media->id;
|
||||||
|
Cache::put("gallery:{$this->id}:media", $mediaId, now()->addDays(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Cache::remember("media:{$mediaId}", now()->addDays(28), function () use ($media) {
|
||||||
|
if ($media !== null) {
|
||||||
|
return $media;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->media()->first();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the media for this item.
|
||||||
|
*
|
||||||
|
* @param Media $media The media model.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setMediaAttribute(Media $media): void
|
||||||
|
{
|
||||||
|
$this->media()->associate($media)->save();
|
||||||
|
Cache::put("gallery:{$this->id}:media", $media->id, now()->addDays(28));
|
||||||
|
}
|
||||||
|
}
|
||||||
1064
app.old/Models/Media.php
Normal file
1064
app.old/Models/Media.php
Normal file
File diff suppressed because it is too large
Load Diff
239
app.old/Models/MediaJob.php
Normal file
239
app.old/Models/MediaJob.php
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Jobs\MediaWorkerJob;
|
||||||
|
use App\Traits\Uuids;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class MediaJob extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
use Uuids;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default attributes.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $attributes = [
|
||||||
|
'user_id' => null,
|
||||||
|
'media_id' => null,
|
||||||
|
'status' => '',
|
||||||
|
'status_text' => '',
|
||||||
|
'progress' => 0,
|
||||||
|
'progress_max' => 0,
|
||||||
|
'data' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status to failed.
|
||||||
|
*
|
||||||
|
* @param string $statusText The failed reason.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusFailed(string $statusText = ''): void
|
||||||
|
{
|
||||||
|
$this->setStatus('failed', $statusText, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status to queued.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusQueued(): void
|
||||||
|
{
|
||||||
|
$this->setStatus('queued', '', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status to waiting.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusWaiting(): void
|
||||||
|
{
|
||||||
|
$this->setStatus('waiting', '', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status to processing.
|
||||||
|
*
|
||||||
|
* @param integer $progress The processing progress value.
|
||||||
|
* @param integer $progressMax The processing progress maximum value.
|
||||||
|
* @param string $statusText The processing status text.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusProcessing(int $progress = 0, int $progressMax = 0, string $statusText = ''): void
|
||||||
|
{
|
||||||
|
if ($statusText === '') {
|
||||||
|
$statusText = $this->status_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setStatus('processing', $statusText, $progress, $progressMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status to complete.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusComplete(): void
|
||||||
|
{
|
||||||
|
$this->setStatus('complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJon status to invalid.
|
||||||
|
*
|
||||||
|
* @param string $text The status text.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setStatusInvalid(string $text = ''): void
|
||||||
|
{
|
||||||
|
$this->setStatus('invalid', $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MediaJob status details.
|
||||||
|
*
|
||||||
|
* @param string $status The status string.
|
||||||
|
* @param string $text The status text.
|
||||||
|
* @param integer $progress The status progress value.
|
||||||
|
* @param integer $progress_max The status progress maximum value.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function setStatus(string $status, string $text = '', int $progress = 0, int $progress_max = 0): void
|
||||||
|
{
|
||||||
|
$this->status = $status;
|
||||||
|
$this->status_text = $text;
|
||||||
|
$this->progress = $progress;
|
||||||
|
$this->progress_max = $progress_max;
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the MediaJob.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function process(): void
|
||||||
|
{
|
||||||
|
$data = json_decode($this->data, true);
|
||||||
|
if ($data !== null) {
|
||||||
|
if (array_key_exists('chunks', $data) === true) {
|
||||||
|
if (array_key_exists('chunk_count', $data) === false) {
|
||||||
|
$this->setStatusInvalid('chunk_count is missing');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('name', $data) === false) {
|
||||||
|
$this->setStatusInvalid('name is missing');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$numChunks = count($data['chunks']);
|
||||||
|
$maxChunks = intval($data['chunk_count']);
|
||||||
|
if ($numChunks >= $maxChunks) {
|
||||||
|
// merge file and dispatch
|
||||||
|
$this->setStatusProcessing(0, $maxChunks, 'combining chunks');
|
||||||
|
|
||||||
|
$newFile = generateTempFilePath(pathinfo($data['name'], PATHINFO_EXTENSION));
|
||||||
|
$failed = false;
|
||||||
|
|
||||||
|
for ($index = 1; $index <= $maxChunks; $index++) {
|
||||||
|
if (array_key_exists($index, $data['chunks']) === false) {
|
||||||
|
$failed = `{$index} chunk is missing`;
|
||||||
|
} else {
|
||||||
|
$tempFileName = $data['chunks'][$index];
|
||||||
|
|
||||||
|
if ($failed === false) {
|
||||||
|
$chunkContents = file_get_contents($tempFileName);
|
||||||
|
if ($chunkContents === false) {
|
||||||
|
$failed = `{$index} chunk is empty`;
|
||||||
|
} else {
|
||||||
|
file_put_contents($newFile, $chunkContents, FILE_APPEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink($tempFileName);
|
||||||
|
$this->setStatusProcessing($index, $maxChunks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['chunks']);
|
||||||
|
$this->data = json_encode($data);
|
||||||
|
|
||||||
|
if ($failed !== false) {
|
||||||
|
$this->setStatusInvalid($failed);
|
||||||
|
} else {
|
||||||
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||||
|
$mime = finfo_file($finfo, $newFile);
|
||||||
|
finfo_close($finfo);
|
||||||
|
|
||||||
|
$data['file'] = $newFile;
|
||||||
|
$data['size'] = filesize($newFile);
|
||||||
|
$data['mime_type'] = $mime;
|
||||||
|
|
||||||
|
if (
|
||||||
|
array_key_exists('storage', $data) === true &&
|
||||||
|
array_key_exists('security_type', $data) === true &&
|
||||||
|
array_key_exists('mime_type', $data) === true &&
|
||||||
|
$data['mime_type'] !== ""
|
||||||
|
) {
|
||||||
|
$error = Media::verifyStorage($data['mime_type'], $data['security_type'], $data['storage']);
|
||||||
|
switch ($error) {
|
||||||
|
case Media::STORAGE_VALID:
|
||||||
|
break;
|
||||||
|
case Media::STORAGE_MIME_MISSING:
|
||||||
|
$this->setStatusInvalid('The file type cannot be determined.');
|
||||||
|
return;
|
||||||
|
case Media::STORAGE_NOT_FOUND:
|
||||||
|
$this->setStatusInvalid('Storage was not found.');
|
||||||
|
return;
|
||||||
|
case Media::STORAGE_INVALID_SECURITY:
|
||||||
|
$this->setStatusInvalid('Storage invalid for security value.');
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
$this->setStatusInvalid('Storage verification error occurred.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->data = json_encode($data);
|
||||||
|
$this->setStatusQueued();
|
||||||
|
MediaWorkerJob::dispatch($this)->onQueue('media');
|
||||||
|
}//end if
|
||||||
|
}//end if
|
||||||
|
} else {
|
||||||
|
$this->setStatusQueued();
|
||||||
|
MediaWorkerJob::dispatch($this)->onQueue('media');
|
||||||
|
}//end if
|
||||||
|
}//end if
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the job owner
|
||||||
|
*
|
||||||
|
* @return BelongsTo
|
||||||
|
*/
|
||||||
|
public function user(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the media item
|
||||||
|
*
|
||||||
|
* @return BelongsTo
|
||||||
|
*/
|
||||||
|
public function media(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Media::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
|||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class Permission extends Model
|
class Permission extends Model
|
||||||
{
|
{
|
||||||
@@ -25,9 +26,9 @@ class Permission extends Model
|
|||||||
/**
|
/**
|
||||||
* Get the User associated with this model
|
* Get the User associated with this model
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enum\HttpResponseCodes;
|
use App\Enum\HttpResponseCodes;
|
||||||
use App\Jobs\MoveMediaJob;
|
|
||||||
use App\Jobs\OptimizeMediaJob;
|
use App\Jobs\OptimizeMediaJob;
|
||||||
use App\Jobs\StoreUploadedFileJob;
|
|
||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
246
app.old/Models/User.php
Normal file
246
app.old/Models/User.php
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
|
||||||
|
use App\Traits\Uuids;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
use OwenIt\Auditing\Contracts\Auditable;
|
||||||
|
|
||||||
|
class User extends Authenticatable implements Auditable
|
||||||
|
{
|
||||||
|
use HasApiTokens;
|
||||||
|
use HasFactory;
|
||||||
|
use Notifiable;
|
||||||
|
use Uuids;
|
||||||
|
use \OwenIt\Auditing\Auditable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'first_name',
|
||||||
|
'last_name',
|
||||||
|
'email',
|
||||||
|
'phone',
|
||||||
|
'password',
|
||||||
|
'display_name',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be hidden for serialization.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'remember_token',
|
||||||
|
'permissions'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast.
|
||||||
|
*
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'email_verified_at' => 'datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
// protected $hidden = [
|
||||||
|
// 'permissions'
|
||||||
|
// ];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes to append.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $appends = [
|
||||||
|
'permissions'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default attributes.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $attributes = [
|
||||||
|
'phone' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boot the model.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected static function boot(): void
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
$clearCache = function ($user) {
|
||||||
|
Cache::forget(
|
||||||
|
"user:{$user->id}",
|
||||||
|
"user:{$user->id}:permissions"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
static::saving($clearCache);
|
||||||
|
static::deleting($clearCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of permissions of the user
|
||||||
|
*
|
||||||
|
* @return Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function permissions(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(Permission::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the permission attribute
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getPermissionsAttribute(): array
|
||||||
|
{
|
||||||
|
$cacheKey = "user:{$this->id}:permissions";
|
||||||
|
return Cache::remember($cacheKey, now()->addDays(28), function () {
|
||||||
|
return $this->permissions()->pluck('permission')->toArray();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the permission attribute
|
||||||
|
*
|
||||||
|
* @param array $newPermissions The new permissions to set to the user.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setPermissionsAttribute(array $newPermissions): void
|
||||||
|
{
|
||||||
|
$existingPermissions = $this->permissions->pluck('permission')->toArray();
|
||||||
|
|
||||||
|
$this->revokePermission(array_diff($this->permissions, $newPermissions));
|
||||||
|
$this->givePermission(array_diff($newPermissions, $this->permissions));
|
||||||
|
|
||||||
|
$cacheKey = "user:{$this->id}:permissions";
|
||||||
|
Cache::delete($cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if user has permission
|
||||||
|
*
|
||||||
|
* @param string $permission Permission to test.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function hasPermission(string $permission): bool
|
||||||
|
{
|
||||||
|
return in_array($permission, $this->permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give permissions to the user
|
||||||
|
*
|
||||||
|
* @param string|array $permissions The permission(s) to give.
|
||||||
|
* @return Illuminate\Database\Eloquent\Collection
|
||||||
|
*/
|
||||||
|
public function givePermission($permissions): Collection
|
||||||
|
{
|
||||||
|
if (is_array($permissions) === false) {
|
||||||
|
$permissions = [$permissions];
|
||||||
|
}
|
||||||
|
|
||||||
|
$newPermissions = array_map(function ($permission) {
|
||||||
|
return ['permission' => $permission];
|
||||||
|
}, array_diff($permissions, $this->permissions));
|
||||||
|
|
||||||
|
$cacheKey = "user:{$this->id}:permissions";
|
||||||
|
Cache::forget($cacheKey);
|
||||||
|
|
||||||
|
return $this->permissions()->createMany($newPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke permissions from the user
|
||||||
|
*
|
||||||
|
* @param string|array $permissions The permission(s) to revoke.
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function revokePermission($permissions): int
|
||||||
|
{
|
||||||
|
if (is_array($permissions) === false) {
|
||||||
|
$permissions = [$permissions];
|
||||||
|
}
|
||||||
|
|
||||||
|
$cacheKey = "user:{$this->id}:permissions";
|
||||||
|
Cache::forget($cacheKey);
|
||||||
|
|
||||||
|
return $this->permissions()
|
||||||
|
->whereIn('permission', $permissions)
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of files of the user
|
||||||
|
*
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function media(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(Media::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of files of the user
|
||||||
|
*
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function articles(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(Article::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get associated user codes
|
||||||
|
*
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function codes(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(UserCode::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of logins of the user
|
||||||
|
*
|
||||||
|
* @return HasMany
|
||||||
|
*/
|
||||||
|
public function logins(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(UserLogins::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the events associated with the user.
|
||||||
|
*
|
||||||
|
* @return BelongsToMany
|
||||||
|
*/
|
||||||
|
public function events(): BelongsToMany
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Event::class, 'event_user', 'user_id', 'event_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class UserCode extends Model
|
class UserCode extends Model
|
||||||
{
|
{
|
||||||
@@ -26,7 +27,7 @@ class UserCode extends Model
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function boot()
|
protected static function boot(): void
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
@@ -49,7 +50,7 @@ class UserCode extends Model
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function regenerate()
|
public function regenerate(): void
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
$code = random_int(100000, 999999);
|
$code = random_int(100000, 999999);
|
||||||
@@ -65,7 +66,7 @@ class UserCode extends Model
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function clearExpired()
|
public static function clearExpired(): void
|
||||||
{
|
{
|
||||||
UserCode::where('updated_at', '<=', now()->subDays(5))->delete();
|
UserCode::where('updated_at', '<=', now()->subDays(5))->delete();
|
||||||
}
|
}
|
||||||
@@ -73,9 +74,9 @@ class UserCode extends Model
|
|||||||
/**
|
/**
|
||||||
* Get associated user
|
* Get associated user
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
|||||||
use App\Traits\Uuids;
|
use App\Traits\Uuids;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class UserLogins extends Model
|
class UserLogins extends Model
|
||||||
{
|
{
|
||||||
@@ -29,9 +30,9 @@ class UserLogins extends Model
|
|||||||
/**
|
/**
|
||||||
* Get the file user
|
* Get the file user
|
||||||
*
|
*
|
||||||
* @return BelongsTo
|
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function user()
|
public function user(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
53
app.old/Providers/AppServiceProvider.php
Normal file
53
app.old/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class AppServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
Request::macro('rename', function ($param, $newParam = null) {
|
||||||
|
if (is_array($param) === false) {
|
||||||
|
if ($newParam === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$param = [$param => $newParam];
|
||||||
|
}
|
||||||
|
|
||||||
|
$paramArray = $this->all();
|
||||||
|
foreach ($param as $oldParam => $newParam) {
|
||||||
|
if (isset($paramArray[$oldParam]) === true) {
|
||||||
|
$paramArray[$newParam] = $paramArray[$oldParam];
|
||||||
|
unset($paramArray[$oldParam]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->replace($paramArray);
|
||||||
|
});
|
||||||
|
|
||||||
|
Storage::macro('public', function ($diskName) {
|
||||||
|
$public = config("filesystems.disks.{$diskName}.public", false);
|
||||||
|
return $public;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
29
app.old/Providers/AuthServiceProvider.php
Normal file
29
app.old/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
// use Illuminate\Support\Facades\Gate;
|
||||||
|
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||||
|
|
||||||
|
class AuthServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The model to policy mappings for the application.
|
||||||
|
*
|
||||||
|
* @var array<class-string, class-string>
|
||||||
|
*/
|
||||||
|
protected $policies = [
|
||||||
|
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register any authentication / authorization services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app.old/Providers/BroadcastServiceProvider.php
Normal file
21
app.old/Providers/BroadcastServiceProvider.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Broadcast;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class BroadcastServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
Broadcast::routes();
|
||||||
|
|
||||||
|
require base_path('routes/channels.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
46
app.old/Providers/EventServiceProvider.php
Normal file
46
app.old/Providers/EventServiceProvider.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||||
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
|
use Illuminate\Queue\Events\JobProcessed;
|
||||||
|
use Illuminate\Support\Facades\Queue;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class EventServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The event to listener mappings for the application.
|
||||||
|
*
|
||||||
|
* @var array<class-string, array<int, class-string>>
|
||||||
|
*/
|
||||||
|
protected $listen = [
|
||||||
|
Registered::class => [
|
||||||
|
SendEmailVerificationNotification::class,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register any events for your application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if events and listeners should be automatically discovered.
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function shouldDiscoverEvents(): bool
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
app.old/Providers/RouteServiceProvider.php
Normal file
90
app.old/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Cache\RateLimiting\Limit;
|
||||||
|
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class RouteServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The path to the "home" route for your application.
|
||||||
|
*
|
||||||
|
* Typically, users are redirected here after authentication.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public const HOME = '/home';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define your route model bindings, pattern filters, and other route configuration.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
// RateLimiter::for('api', function (Request $request) {
|
||||||
|
// return Limit::perMinute(60)->by($request->user()?->id !== null ?: $request->ip());
|
||||||
|
// });
|
||||||
|
|
||||||
|
$rateLimitEnabled = true;
|
||||||
|
/** @var \App\Models\User */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if (app()->environment('testing') === true) {
|
||||||
|
$rateLimitEnabled = false;
|
||||||
|
} elseif ($user !== null && $user->hasPermission('admin/ratelimit') === true) {
|
||||||
|
// Admin users with the "admin/ratelimit" permission are not rate limited
|
||||||
|
$rateLimitEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rateLimitEnabled === true) {
|
||||||
|
RateLimiter::for('api', function (Request $request) {
|
||||||
|
return Limit::perMinute(800)->by(isset($request->user()->id) === true ?: $request->ip());
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
RateLimiter::for('api', function () {
|
||||||
|
return Limit::none();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->routes(function () {
|
||||||
|
Route::middleware('api')
|
||||||
|
->prefix('api')
|
||||||
|
->group(base_path('routes/api.php'));
|
||||||
|
|
||||||
|
Route::middleware('web')
|
||||||
|
->group(base_path('routes/web.php'));
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::macro('apiAddendumResource', function ($addendum, $uri, $controller) {
|
||||||
|
$singularUri = Str::singular($uri);
|
||||||
|
$signularAddendum = Str::singular((strtolower($addendum)));
|
||||||
|
$pluralAddendum = Str::plural($signularAddendum);
|
||||||
|
|
||||||
|
Route::get("{$uri}/{{$singularUri}}/{$pluralAddendum}", [$controller, "{$signularAddendum}Index"])
|
||||||
|
->name("{$singularUri}.{$signularAddendum}.index");
|
||||||
|
|
||||||
|
Route::post("{$uri}/{{$singularUri}}/{$pluralAddendum}", [$controller, "{$signularAddendum}Store"])
|
||||||
|
->name("{$singularUri}.{$signularAddendum}.store");
|
||||||
|
|
||||||
|
Route::match(
|
||||||
|
['put', 'patch'],
|
||||||
|
"{$uri}/{{$singularUri}}/{$pluralAddendum}",
|
||||||
|
[$controller, "{$signularAddendum}Update"]
|
||||||
|
)
|
||||||
|
->name("{$singularUri}.{$signularAddendum}.update");
|
||||||
|
|
||||||
|
Route::delete(
|
||||||
|
"{$uri}/{{$singularUri}}/{$pluralAddendum}/{medium}",
|
||||||
|
[$controller,"{$signularAddendum}Delete"]
|
||||||
|
)
|
||||||
|
->name("{$singularUri}.{$signularAddendum}.destroy");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user