Compare commits
1648 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f4548e112 | |||
| 12fa505972 | |||
| 4e4930ba62 | |||
| 76301bc30d | |||
| 964e105cf9 | |||
| 6fd24c7e14 | |||
| 231bc1e2de | |||
| 37d04b7176 | |||
| e62a802926 | |||
| 69e981364a | |||
| abb4221539 | |||
| e4ebabdaba | |||
| da1e383295 | |||
| b64ed254e0 | |||
| ba291edc42 | |||
| ec2ea955d8 | |||
| c197644ba7 | |||
| 29b30cc5d3 | |||
| 6af27516dc | |||
| a89f17a145 | |||
| de0565f5b3 | |||
| 68c708bdef | |||
| 5581950fee | |||
| 58e366a063 | |||
| b06c527767 | |||
| 26f28a862a | |||
| 94c981e22c | |||
| e8da7e2df2 | |||
| d635c86e00 | |||
| 406ff6984b | |||
| c6ddc501c5 | |||
| 4839181beb | |||
| 63a05c89a7 | |||
| 385c4f69f7 | |||
| 486cd8c8c9 | |||
| eb5d93b3c2 | |||
| a5ff623484 | |||
| b5a4389815 | |||
| 7b5b559baa | |||
| 67a9929745 | |||
| 64c4433b98 | |||
| 22bc088f6f | |||
| d3e8e06638 | |||
| 1b933f7add | |||
| 3fe891a05b | |||
| f4c5b712f4 | |||
| 4c8dc7818d | |||
| 5c43a1f87c | |||
| d3b265de8e | |||
| 263151658f | |||
| aa86e07cd2 | |||
| d92fa5de65 | |||
| c589140ea0 | |||
| 52894615ce | |||
| 8546bbdd65 | |||
| cc2c8f76d0 | |||
| 1ffa69c43c | |||
| f85ebd7ffd | |||
| 78d355f136 | |||
| ec0346e4a8 | |||
| fc5eb37776 | |||
| 1d7853cbfe | |||
| af0a95be12 | |||
| d67975cb62 | |||
| 663b2fd844 | |||
| bcace9d019 | |||
| b59bf3e7dc | |||
| 3957d670d0 | |||
| 833dace2b4 | |||
| 56e31d2303 | |||
| ec365b0804 | |||
| aef0ac68c3 | |||
| f12f9a816f | |||
| a000d6454f | |||
| ca8864c061 | |||
| 423f4f9126 | |||
| 456c7d8d91 | |||
| 54cfe3f6e6 | |||
| 5e0b18104d | |||
| 8b5d3f7fbd | |||
| 744f43676d | |||
| ec0b9b198f | |||
| 94300d81d6 | |||
| bc9ea5a2ec | |||
| 4635a6efc3 | |||
| 9608414eae | |||
| 5efddf6f5b | |||
| 305dc049a4 | |||
| 3ac0702094 | |||
| 47d8e2f8b9 | |||
| 83dd9ce20e | |||
| a8eb76fd8d | |||
| cd7db5c4a8 | |||
| da7313bc9d | |||
| 4ec361c718 | |||
| 738ef442fd | |||
| d29b3bfb9a | |||
| 6fdce3c536 | |||
| 912bbf0e32 | |||
| 01c4fe6113 | |||
| 0fa9f57971 | |||
| 1ab29ec3a4 | |||
| 7e475a0786 | |||
| 26b3c62ab8 | |||
| d0acf5b8a6 | |||
| 74fbc23823 | |||
| a23dee52f2 | |||
| 4d03f1e110 | |||
| 963911f2e1 | |||
| 9d484077ae | |||
| 9858b0f37f | |||
| 09033b19a7 | |||
| 5fdeb9c413 | |||
| 22d3734075 | |||
| eca6b03f44 | |||
| bbdbec7197 | |||
| 6c450d1338 | |||
| a8cd1027f3 | |||
| d99b306ae9 | |||
| 74136761df | |||
| f597d64339 | |||
| 0072f1500e | |||
| 64bed01a91 | |||
| f6319e11e7 | |||
| 5d9f988df3 | |||
| f8c72fb0ac | |||
| 886514a25f | |||
| fa765667f2 | |||
| 434bdcd6d4 | |||
| be5f3f38f8 | |||
| 08c3a25b39 | |||
| 34cd4b6244 | |||
| d89c8682be | |||
| 6f024849e9 | |||
| e048f0955f | |||
| 479b2b4fd3 | |||
| 84f14a05bd | |||
| 8d52fa51b1 | |||
| 229d8b9bf5 | |||
| eb8d43a804 | |||
| f82266fade | |||
| b4b6f7a35f | |||
| 0bc995b87f | |||
| 59725f2031 | |||
| 00bc9ac806 | |||
| f200960a57 | |||
| c700127f1a | |||
| ae2f9571b4 | |||
| a77dcad336 | |||
| 7ace9324b4 | |||
| d2e889e927 | |||
| 803bdb457c | |||
| 7c9b1f6e38 | |||
| d545537a43 | |||
| 4d8904938d | |||
| 0c09f2b2c0 | |||
| bffba02511 | |||
| 901f4df7ee | |||
| 9337cba340 | |||
| 2b0c67c263 | |||
| da71f031f5 | |||
| d2e585baa7 | |||
| a102c085df | |||
| cb40a82e79 | |||
| 4253acad4c | |||
| 7e6ff3cbe6 | |||
| e7ef3bf515 | |||
| a25efe53aa | |||
| de059a715a | |||
| 318aff1ef0 | |||
| e96b9b2f4f | |||
| 3ae4a5caf0 | |||
| 559f0d2f90 | |||
| 9b6a36c8aa | |||
| 1a4aebf805 | |||
| 6ad7100aa3 | |||
| 5529669884 | |||
| b57283d8d1 | |||
| 7658f7c41d | |||
| 70e5e0f9df | |||
| dec4691c73 | |||
| 48903b1402 | |||
| 7376c21f10 | |||
| f921400579 | |||
| ad6d09b6ad | |||
| 43b338d612 | |||
| 67655ad84b | |||
| ea2b1b0748 | |||
| 856c57cb12 | |||
| 90584ab803 | |||
| 184f54a6cd | |||
| f24031b974 | |||
| 0a7aaa54b6 | |||
| 3167ee91d1 | |||
| e8f1190628 | |||
| 44f18d210e | |||
| e8deecc9b4 | |||
| a79fe69bf4 | |||
| d49c33fbe3 | |||
| de29c1d8a0 | |||
| f9172594b2 | |||
| 94d8a547b8 | |||
| b39a7c6f0c | |||
| a3d847151a | |||
| 594f506641 | |||
| dd458dfa7f | |||
| b917489f00 | |||
| 75dfedcb82 | |||
| 6216b4fc0d | |||
| 4356cb7b9b | |||
| d8df52cc8f | |||
| 10dc1f1368 | |||
| 8f7bce7aad | |||
| 4d66f7c93f | |||
| 381003eeab | |||
| c3d4c821f3 | |||
| d8038ac483 | |||
| d268f25f16 | |||
| 01c69c8f8f | |||
| 9622e05cf5 | |||
| afaf53cdfc | |||
| f031309f8f | |||
| 20ec420ba3 | |||
| a70b94e707 | |||
| 0d7cf55a3a | |||
| 008bf036b5 | |||
| cc5ad456e6 | |||
| 3e29457094 | |||
| 0b3ac2a9cd | |||
| 0f1e5181a6 | |||
| e544007185 | |||
| 4b690e8e1f | |||
| 371afde52d | |||
| 7a6a2e3d92 | |||
| 3f8ac59f4c | |||
| 74e7b1cfa5 | |||
| ae0a6d66f3 | |||
| 321839e074 | |||
| 120cfd13c5 | |||
| 09f2739298 | |||
| e9fc455a30 | |||
| 8af4126de1 | |||
| 5d1c48c071 | |||
| 3044af9410 | |||
| 4f0f0af83b | |||
| 198afee946 | |||
| def0af652d | |||
| 20e4ba0590 | |||
| 72fd9977e5 | |||
| 10f35c682b | |||
| 6e84c29ce4 | |||
| 389a06aac5 | |||
| 4b96721393 | |||
| e42ee0c0e1 | |||
| 277a0fd16a | |||
| c163d6774f | |||
| 9e73eaf955 | |||
| 1b2094f4e2 | |||
| ec863df007 | |||
| cc3b8e0681 | |||
| ff145abbe7 | |||
| e6106aa7cf | |||
| b45a8f4b5f | |||
| c9f8a84d48 | |||
| ac1543d568 | |||
| 9d354ca657 | |||
| 3f2139349e | |||
| f56dd582f9 | |||
| 225ab47b8e | |||
| 4c350bd5a3 | |||
| e7fb29fced | |||
| a2d11b43de | |||
| f80cf666b1 | |||
| ce5be8ac24 | |||
| 1777bb4b93 | |||
| 5c6c655cdc | |||
| 60eb602156 | |||
| 76b114d820 | |||
| ce33deed86 | |||
| 1e6c172f18 | |||
| a1ce9b9285 | |||
| 6ec3693030 | |||
| 71729f0b16 | |||
| 1c229a8e08 | |||
| 07b1e3fb90 | |||
| 6294516271 | |||
| f3331b5045 | |||
| 6a06a91fa2 | |||
| 0cba5ba67e | |||
| b815352a45 | |||
| 2f299dbb20 | |||
| f76fbe75e0 | |||
| cc1e356c35 | |||
| 8094f3c0e1 | |||
| 900beaa955 | |||
| 6521c02526 | |||
| 2412333152 | |||
| 4a2d2f7336 | |||
| d03baa4613 | |||
| 41437e4d8f | |||
| 7d220dd8c2 | |||
| a99ec062e6 | |||
| 8fe6395287 | |||
| b4d51599ee | |||
| 9350a20189 | |||
| 889d5da71e | |||
| 5546ab08c2 | |||
| ef183f256c | |||
| 3a96e501cc | |||
| 6b1784f2ee | |||
| 1a872b1643 | |||
| deef9ad181 | |||
| 0dc7e8b8dc | |||
| a5f075548a | |||
| 1706ddd511 | |||
| a220986d16 | |||
| 2a8ac81eed | |||
| d3cb3c03d2 | |||
| c60bc5cdbe | |||
| 6cfbf835c7 | |||
| 047b77e038 | |||
| 766b370264 | |||
| da33277234 | |||
| 3e832e5e94 | |||
| 82e795b642 | |||
| 95516b0343 | |||
| 83fb6826ee | |||
| b1e92ab866 | |||
| 96241cb67c | |||
| b680dab5c9 | |||
| 984840dc82 | |||
| 84e447af09 | |||
| c7ddabcc8b | |||
| bee80fcf8a | |||
| 0aff35b622 | |||
| 46a6a84ecb | |||
| 374812f8fe | |||
| 94e00b8a3e | |||
| f2b78d18a4 | |||
| 17eccfcd8b | |||
| 01e4382d20 | |||
| 1c664af326 | |||
| 392d34422a | |||
| 35e7a3163c | |||
| 96fafa6952 | |||
| a55693211f | |||
| 1acd24fdbe | |||
| 59b7d5db4b | |||
| 16aa47509b | |||
| d1bb3ef6bf | |||
| 5cd9dd4a67 | |||
| fc405d9d73 | |||
| 5786ff5035 | |||
| 8a206a6d92 | |||
| 67b3ab820f | |||
| b06501dd02 | |||
| e3049fffd4 | |||
| 5ecdb7e07c | |||
| 4ed3347f52 | |||
| 364775dcfe | |||
| bfebcdc7ed | |||
| 480e4f3a69 | |||
| 78a0417ee9 | |||
| b83d148b37 | |||
| ad794248fe | |||
| b804791ff6 | |||
| c45bf870b7 | |||
| a0bd8b6049 | |||
| ae4f278df1 | |||
| bc0ff706b0 | |||
| 28abb8d8cc | |||
| 24d948a3f6 | |||
| c1c9c3554e | |||
| fcea564afa | |||
| f44abd0b28 | |||
| 854903805b | |||
| 868f117b67 | |||
| b6cac4baae | |||
| 4fcb3df1d9 | |||
| b60e22bcb4 | |||
| 61312c2eec | |||
| b0063b1d4a | |||
| fffcbdc44d | |||
| 8d1fa362f7 | |||
| 31a2765b30 | |||
| e79a5b7efe | |||
| ca531e85f3 | |||
| 0941c0944a | |||
| 9b80843c77 | |||
| 8684a3efc3 | |||
| fccfce2ae8 | |||
| 935d2ce29a | |||
| 437ddc01b4 | |||
| f19e58b352 | |||
| eb6f330e67 | |||
| f19899543d | |||
| 3a2611f8e1 | |||
| 53ad312700 | |||
| 89d375daad | |||
| d46f9776fe | |||
| f9a47c8a9f | |||
| e395ee1878 | |||
| 4971c54b05 | |||
| 4c5b82ae37 | |||
| fd7082c30f | |||
| 8d0b72293f | |||
| f3d98f90c0 | |||
| 4eccb5ffc6 | |||
| 86049624c7 | |||
| 3972782033 | |||
| 33b86057d1 | |||
| 3c3b922eae | |||
| e8d0147075 | |||
| c2bcc2e2d9 | |||
| 55f9886412 | |||
| a77ece01a6 | |||
| 1c1101aeac | |||
| de04ead55d | |||
| bc18fac97e | |||
| 3a0b03348e | |||
| b18baf74d2 | |||
| 28c7355697 | |||
| 0dd0baa511 | |||
| c3a296c19f | |||
| f6cc923e01 | |||
| aab29fbb6b | |||
| d9d3ff27ae | |||
| 614d05acb5 | |||
| e4a82edd3f | |||
| eceaa72781 | |||
| ddf45c5ee9 | |||
| ff100c0b9f | |||
| 037cc4d098 | |||
| ff6e6ef88c | |||
| e8ec11652f | |||
| cd7f276c40 | |||
| fc8bb82a02 | |||
| 5d7f1f77a3 | |||
| 5dea3f4495 | |||
| c6e709cd36 | |||
| daf5a80081 | |||
| 759ab78f80 | |||
| b6d9f736e3 | |||
| 243ab51def | |||
| c5603a0e10 | |||
| 57f6ecb1da | |||
| 64082ada1e | |||
| 068535a80c | |||
| 08f4fe5f35 | |||
| 018b5684fc | |||
| 73a80a5fbc | |||
| 4c8bf9ae19 | |||
| f77d300549 | |||
| 62655be2d0 | |||
| eb938bdba3 | |||
| 129d3b35fb | |||
| 84df23e1f6 | |||
| a439d8abe8 | |||
| 24b7659c23 | |||
| 44dbbeb608 | |||
| 7161b6416e | |||
| 1331bffaca | |||
| 9b422e5c97 | |||
| 0c86855392 | |||
| 962ae5231d | |||
| 590d13061a | |||
| c3a2cdeee9 | |||
| ef77fb91c0 | |||
| 02bd8d7ea1 | |||
| da4ec145d7 | |||
| ef145e47b4 | |||
| adf58a06da | |||
| 63f0b5279d | |||
| c96ccbb6cb | |||
| 950fff31ed | |||
| f05d8281f3 | |||
| d5c9fa823e | |||
| 99741db645 | |||
| 90d5a6d8ab | |||
| 5b8529bc83 | |||
| f76c68f0ed | |||
| 8368fb5c41 | |||
| d1c39a737f | |||
| 425bfa4318 | |||
| 293abbd1d0 | |||
| b64b774bd5 | |||
| 466ab1e3c0 | |||
| daa9e7810e | |||
| 95a0f3dbe5 | |||
| bb465dbfaa | |||
| e5ab12496f | |||
| 4b906e39be | |||
| 0dc8f27240 | |||
| 8cbcc237c0 | |||
| c4135c71d4 | |||
| 172da4d655 | |||
| 6f8ccd4e10 | |||
| 8d36a75342 | |||
| 9457e5b890 | |||
| bce7a278ae | |||
| 97e3af8fc9 | |||
| 914e29210a | |||
| a6041ae525 | |||
| ab1e097b7c | |||
| a781f84aea | |||
| 90a2a808d6 | |||
| 73e2d8e305 | |||
| 0e1e13f54a | |||
| 869c06f454 | |||
| b61ab423ca | |||
| 090a595c99 | |||
| bc417308c7 | |||
| e77e16b9aa | |||
| 0ae297634e | |||
| 0f2f559d7a | |||
| 57b5b12952 | |||
| 9baaaae1a3 | |||
| 1f4118a146 | |||
| f4a3823d88 | |||
| b2a69efc9d | |||
| 00ebc8b64d | |||
| effd273245 | |||
| 7858c72b98 | |||
| 09e2c0beab | |||
| e8864ffb01 | |||
| d893de2b7e | |||
| 7f7cfef81b | |||
| d01972bbe5 | |||
| b9fdb5880a | |||
| 1139ed676a | |||
| 64be353156 | |||
| 750015684d | |||
| 992d16664d | |||
| 900c19b76d | |||
| effd2bce24 | |||
| de8816d837 | |||
| 593554daed | |||
| fecd877e8b | |||
| ba6d8ae8c7 | |||
| 175862d3c9 | |||
| 5eea08088d | |||
| c752c2a125 | |||
| 4ac4f9b0a9 | |||
| 09abcb44bb | |||
| 7f566b9152 | |||
| 30835fe9ba | |||
| 910e98b573 | |||
| 4623e40077 | |||
| 20868b9ede | |||
| efc84efabf | |||
| 7c7fa96334 | |||
| e08acb851c | |||
| bbad84c6cc | |||
| f2acb98afa | |||
| 38affea3f3 | |||
| cea31c5b11 | |||
| 254e2f120b | |||
| 2bfee0c29a | |||
| c08bd8f88b | |||
| 9818c2f033 | |||
| f63fd25ce0 | |||
| 57ecdd6765 | |||
| 9d890b35c6 | |||
| 8fc5c0b5be | |||
| c4e7448d31 | |||
| ffd2687734 | |||
| 6f3eedf5e6 | |||
| 241eb7b031 | |||
| ca399794c3 | |||
| 736d4cc59a | |||
| ad85f8be2f | |||
| be17ef4047 | |||
| c6c006f143 | |||
| 10856516ac | |||
| beac4c8b8a | |||
| b39b39bc8a | |||
| e373be7dde | |||
| ca7c0aa47c | |||
| 48a8cf6b70 | |||
| 7ba1646703 | |||
| daa550cc82 | |||
| e9f9d3c259 | |||
| 63377853b8 | |||
| fc86eefeac | |||
| a98ad76c6a | |||
| 32c768792a | |||
| 793cf27318 | |||
| ba568b7975 | |||
| 4b5bd76225 | |||
| a54403ef01 | |||
| 13262c5125 | |||
| 9ea38fbb3a | |||
| 94619e3284 | |||
| 8b05ef6db4 | |||
| 8e03083b83 | |||
| dc2debcd83 | |||
| b7ab8b9e8f | |||
| c50ab1af67 | |||
| 7773d334ba | |||
| 2a0697022e | |||
| 8d1cc22c58 | |||
| e1eb963962 | |||
| 87c2dc5bb5 | |||
| 06efcd3c46 | |||
| faa791e94c | |||
| e328dec9f9 | |||
| 8e60a7b22b | |||
| 958b6035e1 | |||
| 94e0739a74 | |||
| 4465aef991 | |||
| 822bc6f085 | |||
| 19bd99d159 | |||
| 5c17fefb08 | |||
| ee589ca112 | |||
| f984b45de2 | |||
| d56252c6b3 | |||
| 44b950cb8e | |||
| 985714d504 | |||
| 97ead7120e | |||
| 670021a482 | |||
| 9858cc5baf | |||
| fa5b59cf21 | |||
| 0ef58a9aef | |||
| 0c4e498df3 | |||
| b5b60f22d5 | |||
| 2f0c74aef0 | |||
| f56006fb6b | |||
| 7685de45f2 | |||
| 199e68ff29 | |||
| 81bffccf01 | |||
| 79a13e3618 | |||
| d9b7df5b85 | |||
| 0c933bcc5d | |||
| 4c4b0f722a | |||
| 6c3cafa72f | |||
| 16ae23dbeb | |||
| 4f3064bdb1 | |||
| 2b0627c1f6 | |||
| cfca1514c0 | |||
| 345a4306e8 | |||
| beb0836d69 | |||
| b4ed01243b | |||
| 3772a21a51 | |||
| 1eb16cdb02 | |||
| 05e278d08b | |||
| c21821a864 | |||
| a56f3f85f8 | |||
| ba13b9924b | |||
| 04b6cb763f | |||
| 239824681d | |||
| 0ac82fbbe1 | |||
| 8c5a9fa38f | |||
| 2f8306cba8 | |||
| baa7e7d561 | |||
| ffaacc04ef | |||
| dd32341502 | |||
| f58e3114a2 | |||
| eba494ad8c | |||
| 7e89b58746 | |||
| b7744105a0 | |||
| 65dcb2a9bd | |||
| d5e1dc54c6 | |||
| 69263f0e5b | |||
| a3b2912e89 | |||
| 7f412ec3f5 | |||
| 94e881e5f0 | |||
| 5bb47e290f | |||
| d53a032402 | |||
| 70d95877d8 | |||
| 48821f8391 | |||
| bb00edda4e | |||
| aaa2858337 | |||
| 017530ba4b | |||
| 4895023f3b | |||
| 0ed637f0ce | |||
| 45bf428092 | |||
| e6f2c457a8 | |||
| 04f723327e | |||
| 4a9bd95ed3 | |||
| 78bd950daa | |||
| d3070a0be1 | |||
| a0d461d3e2 | |||
| eb9e276ba7 | |||
| 0a70bcc0a9 | |||
| 35160f88e0 | |||
| c8dad528a8 | |||
| 256e989ba1 | |||
| 0ddb447c4c | |||
| e49c96a35e | |||
| 2d1aeca949 | |||
| e06e4db4b7 | |||
| 51242fcbb2 | |||
| 99be9ddb47 | |||
| be4317361d | |||
| a175b6a38b | |||
| 431da6c903 | |||
| ab6b8f520e | |||
| 24e58d1455 | |||
| f91ad6b2db | |||
| eed253bd2f | |||
| b68fcf1de5 | |||
| 39810f9ba5 | |||
| d21ebc6f0d | |||
| ad818cf886 | |||
| 9793016603 | |||
| 9e06f2d17f | |||
| fb7d533ff7 | |||
| 9dd3827222 | |||
| 5697370dfe | |||
| 7464c3622e | |||
| 5132aa0254 | |||
| d4d19569ee | |||
| 1a541ce220 | |||
| 43c7504f89 | |||
| aebe96913a | |||
| 78d24eb451 | |||
| c5c5ac58e5 | |||
| 1527679f4b | |||
| c2fe3b5459 | |||
| d4a66f9b6c | |||
| 23f1489b2b | |||
| 5108b1f3ed | |||
| 58bc84436c | |||
| 2415408a50 | |||
| 00d7b36c36 | |||
| 67d6f7119d | |||
| 42dbc894e0 | |||
| 94bfe7d9c8 | |||
| d9a114090b | |||
| b10441c928 | |||
| e123eeea9e | |||
| 9676d934d2 | |||
| 759bb822ff | |||
| abd79219dd | |||
| 2b5463475c | |||
| a7a1a377da | |||
| a6b2f5df1d | |||
| da2b64c96d | |||
| 9e9b07f10f | |||
| 82743abadc | |||
| c1937b6ea8 | |||
| 498a443230 | |||
| 7584c30722 | |||
| 34b49ef079 | |||
| d9a53460ff | |||
| 62f4b75156 | |||
| 5364838fc0 | |||
| 8be44f9cf2 | |||
| 68136ea217 | |||
| 1fa6a763bc | |||
| 726308bfd5 | |||
| 22ddb695f2 | |||
| 09b2feac54 | |||
| 57e1df86c8 | |||
| 3d5b1b6c6d | |||
| ec063b4af5 | |||
| bfa42ff84a | |||
| 5f4ee39f2b | |||
| 22aca1af53 | |||
| 45d7e2dc42 | |||
| 71a5d07698 | |||
| fb10c1439a | |||
| c58c592fb0 | |||
| 6932a63217 | |||
| 18f7ca860d | |||
| 1a1ccd6bdc | |||
| 624632d0ca | |||
| 66255291da | |||
| 33b2c7b78a | |||
| ea881ff95e | |||
| 34e1ff88db | |||
| c1916d6fe4 | |||
| f4ffbcf76e | |||
| da9932d147 | |||
| 8a547dab20 | |||
| 14fa5d778d | |||
| 5597992d63 | |||
| da42127a7c | |||
| 595408d21f | |||
| 090410edb5 | |||
| 491a0f3959 | |||
| c8fe002688 | |||
| 25fabcc1be | |||
| 43d4bc8dc4 | |||
| 09cc9b92d1 | |||
| ebcc48ec80 | |||
| bf060d43a7 | |||
| 9b838cedd1 | |||
| 5ca62f3ef8 | |||
| abf194fbcf | |||
| 211f98e971 | |||
| 7f1931af9c | |||
| 7dcb45d7f3 | |||
| 8650923b01 | |||
| 9c304f238a | |||
| 202f5077de | |||
| 4c19b4d831 | |||
| 3ae16ff8ca | |||
| f3bf74a540 | |||
| de6a230838 | |||
| 2e2f59b290 | |||
| cf92dde1ca | |||
| 86c0a3ecad | |||
| 3b3a7e2757 | |||
| c72b36b84a | |||
| ee1afc63f9 | |||
| 8438652e7d | |||
| c16db436d3 | |||
| ac9df2fc08 | |||
| eba24b9242 | |||
| 8c6ecd35ec | |||
| e98823f7fa | |||
| a8ddb2f44a | |||
| f32bf35c22 | |||
| 978a0272a5 | |||
| 283f24b213 | |||
| 97775fb790 | |||
| 7455bf329d | |||
| 24ad74f136 | |||
| 16d65631aa | |||
| 0a7e053985 | |||
| 1d65781d8d | |||
| 0d6fd2643d | |||
| b3cc7b1578 | |||
| 2a796fdc09 | |||
| a0914ccb28 | |||
| efb9d107cf | |||
| 34bde52f74 | |||
| 75da626c85 | |||
| 1d45e0df79 | |||
| 5ebcc3b1a0 | |||
| 6da6411f3b | |||
| 4089b4cd68 | |||
| 96d1aea54a | |||
| 8baef8d7c5 | |||
| 7215746d7a | |||
| 6761ff44cc | |||
| 1f28bf14c1 | |||
| d3b62aa918 | |||
| a1eafc108d | |||
| 7330bf5832 | |||
| d834ef5104 | |||
| ef56f599d2 | |||
| 0f43b3f8f9 | |||
| c570759370 | |||
| 066ec8e26e | |||
| cc6f1cd585 | |||
| ae9085b11f | |||
| e98284fff5 | |||
| 89f01d75d7 | |||
| 8eb68d3901 | |||
| edd61705dc | |||
| 3f20e29901 | |||
| 36ae162626 | |||
| 00f7cb9dbb | |||
| 1ca3dc26eb | |||
| 2f3be267b3 | |||
| 5b8f6910fb | |||
| 9fe26ba814 | |||
| 5e97ed1c7e | |||
| 947fb7af7a | |||
| 44bcc157e5 | |||
| 278bf3da13 | |||
| 446bc81d3a | |||
| 9527aac242 | |||
| c57f1f9d7d | |||
| e372527d13 | |||
| 96be1e1275 | |||
| 8ce17d0585 | |||
| 6af1eaa4e4 | |||
| da01487301 | |||
| 708d7b5fc5 | |||
| 62b5a159a9 | |||
| fc7809192d | |||
| a6d04509a5 | |||
| 0071596274 | |||
| 59f66051f8 | |||
| 9f1e59cf78 | |||
| f1f68b8ef6 | |||
| f22c3cdda9 | |||
| 5e15cc3bbe | |||
| a6690493b0 | |||
| 17a6335d13 | |||
| ca57f6de85 | |||
| aefaabdb1a | |||
| 9211c8d3b1 | |||
| eff1980df5 | |||
| 1553ba5630 | |||
| ec24120d2a | |||
| 50df750202 | |||
| dab4aced48 | |||
| 1774952312 | |||
| d66d6e70a6 | |||
| 4635e9269d | |||
| 574867536d | |||
| 5488a4d118 | |||
| e34f3c7c2c | |||
| ceaff7b645 | |||
| d27a025347 | |||
| 2b2853a183 | |||
| a25263f868 | |||
| 4b9727067b | |||
| 00fc392a12 | |||
| e79111fed5 | |||
| 423b48279b | |||
| 6f29c0a7cf | |||
| 27bc16604b | |||
| 86ae4a3513 | |||
| 1da90fe1ec | |||
| 25ba50d6f7 | |||
| f22e99aec8 | |||
| f027fd5f21 | |||
| 37a038c24f | |||
| 0b60cbc531 | |||
| 3a8f825de5 | |||
| d2df83cf2f | |||
| d481850d4c | |||
| e502968707 | |||
| 12dcac4994 | |||
| 6c55e2bd9d | |||
| 2fd357c346 | |||
| 0a5e58201a | |||
| d687b20467 | |||
| 7dbcedad40 | |||
| b6e8d28ed3 | |||
| 85ce47f5bb | |||
| 55c98cc27a | |||
| 422f3ec81e | |||
| 54fb91c03b | |||
| 6df9742664 | |||
| f23a221750 | |||
| 1837da4508 | |||
| 4637accb51 | |||
| 74f067d893 | |||
| 43773954cd | |||
| 30cafef9f2 | |||
| e1a6b441d7 | |||
| 251f2d82b3 | |||
| e905550778 | |||
| adee99db34 | |||
| eda2eb2283 | |||
| a7123a04ba | |||
| 8a562f1d15 | |||
| d4861a74df | |||
| 8971cc4b8b | |||
| bca6dd41d2 | |||
| 23c1d664fe | |||
| c891342fdb | |||
| 221c4eeb0c | |||
| bbb1fbfbe8 | |||
| 5a874a90ac | |||
| 1c14c2fdef | |||
| 73a038afd4 | |||
| 4d55765e28 | |||
| 2b43f3cb84 | |||
| 52c4885335 | |||
| aa5fe52e89 | |||
| ce107dd688 | |||
| 72affd7a5b | |||
| ba4c51dd68 | |||
| 294fb1f774 | |||
| a846afe733 | |||
| 5fb3cea0bb | |||
| 4ae89c23cd | |||
| 3d32fe662b | |||
| 468674a517 | |||
| ebe4354a85 | |||
| f47bc5ea7d | |||
| 427615f627 | |||
| 829b560794 | |||
| f97a15c5c3 | |||
| 25fcf523e3 | |||
| c1be94c4ad | |||
| 3a05d72124 | |||
| 7ec44e46ce | |||
| 060b17df01 | |||
| 74c78d7577 | |||
| 1ef0c1adac | |||
| c2e649e2bf | |||
| 196db9718e | |||
| 9f5b264e04 | |||
| 3825f5fb61 | |||
| e60dbc883c | |||
| bbbfa91db9 | |||
| 5ec8e2da66 | |||
| 9e59bd5687 | |||
| 1d26ccac4e | |||
| 0e2526f627 | |||
| dd9e9c7a6d | |||
| e19922abd0 | |||
| d27bde6047 | |||
| 61f76dedc6 | |||
| 06737f45ad | |||
| 65e8765bdd | |||
| c6a0212384 | |||
| e03614d91b | |||
| b82770d0a8 | |||
| 55e1326164 | |||
| b0aff68c8b | |||
| 6a99855c8c | |||
| 665aa6eb23 | |||
| 42caacbaf9 | |||
| 3531256c3f | |||
| 9a0db72eb4 | |||
| e11a42cf68 | |||
| 114769c2d9 | |||
| 9594596b8a | |||
| 69cf697aa3 | |||
| 45dbe5cb77 | |||
| a1ff35f6ce | |||
| 077a6949e2 | |||
| 44022f07ca | |||
| 30c1e1e86a | |||
| 9a90813877 | |||
| 1113218c6c | |||
| 2556c80250 | |||
| 8f8a5c639b | |||
| 9e9c37c1e8 | |||
| 6cbdbcb1f1 | |||
| c8835bf5db | |||
| 6dfedac7a7 | |||
| 83794eaf33 | |||
| bd1f43f9ee | |||
| 66ffe21ce2 | |||
| f2e86b7d30 | |||
| 5251e6787d | |||
| 856aee0a72 | |||
| 6b4c71f966 | |||
| dd6d040da5 | |||
| 203b60383f | |||
| 61ced0b221 | |||
| ae7675fee0 | |||
| 66ed26fbf9 | |||
| 98662c2a77 | |||
| 7099358985 | |||
| 9a706b3e3e | |||
| 71c9b03779 | |||
| dc7b9315b5 | |||
| 6c17b141db | |||
| 5d2cca855e | |||
| 61e10be04d | |||
| 20d5587851 | |||
| d8eccf03f1 | |||
| 6e40b58dc5 | |||
| 30dd8bcf2b | |||
| f0a11be0b8 | |||
| b8882fa00e | |||
| af337b7018 | |||
| f60267d208 | |||
| a0c844f4f6 | |||
| 7b84b92e72 | |||
| ce338c632d | |||
| d9f70c16f7 | |||
| d0299de898 | |||
| 9380c9ec81 | |||
| 941582ac2a | |||
| 04560b4475 | |||
| 0b30ad0da2 | |||
| cb6ea2c6fb | |||
| 89a5bbb10e | |||
| 2f59bb74cd | |||
| 6c6a3649ea | |||
| 05b97db747 | |||
| 543e4c0666 | |||
| e28619f769 | |||
| 4d8c2d3f4e | |||
| f53eeb8b33 | |||
| aba6d9b338 | |||
| cd5bef414c | |||
| 4f2d2ae4b8 | |||
| 1bd0ab7389 | |||
| 8799276c6e | |||
| 672aabf4ac | |||
| 796d6909d5 | |||
| a3dea99bbb | |||
| fc351a1896 | |||
| d9164281ab | |||
| cbb5b6e846 | |||
| 08bd39dbba | |||
| 430808e180 | |||
| 6976dc2b26 | |||
| 27063d5bae | |||
| 5be86b9dbb | |||
| afc78524fc | |||
| eb33a2451f | |||
| 891a0a0965 | |||
| 50f0797850 | |||
| 36cdf0e0be | |||
| d9cc3c3ec7 | |||
| 069a1608de | |||
| 60accfd601 | |||
| b1f2051b43 | |||
| 233e4af7f8 | |||
| dc1b808a28 | |||
| 91a423e60e | |||
| bd03a6d206 | |||
| d87da78eb5 | |||
| f3e82c2c80 | |||
| 569f05a99e | |||
| ece7c22df9 | |||
| 4eefd39172 | |||
| daae5d6859 | |||
| df76769a29 | |||
| fe72639925 | |||
| c3e6e1144f | |||
| cacb5d62dc | |||
| a8b47a55bc | |||
| 3159fdec9f | |||
| ea990a5381 | |||
| 134183ef16 | |||
| 67ab2536bc | |||
| 756a2ac25c | |||
| acaceb4103 | |||
| 7e3d66ec53 | |||
| 1ca9bb5aa8 | |||
| c641b733e1 | |||
| 16cf6bc852 | |||
| c51b7d7104 | |||
| 5c0ca92fd7 | |||
| 241e9bc253 | |||
| c8820adb56 | |||
| 0f4c6dd5b0 | |||
| f8ab9f62f6 | |||
| 217ed03b8e | |||
| 77e6058e4c | |||
| 4a60026162 | |||
| 3621292a0e | |||
| 6c296ccf8e | |||
| 6df1c36011 | |||
| 924da00f3e | |||
| 44dae22a3c | |||
| d35e251d6e | |||
| e19d2d6ec9 | |||
| 871255f28c | |||
| 9044aa4ed9 | |||
| 60c7efae3c | |||
| 48fc6ca60e | |||
| 7ac315e1eb | |||
| 374c6845d6 | |||
| c5cbe37007 | |||
| a2346e4666 | |||
| 2479ccc4c6 | |||
| 64dd8f5d65 | |||
| 47420a802a | |||
| 5cdb2b7163 | |||
| d4c080c7e4 | |||
| 065a47a446 | |||
| 5bd9ecb8df | |||
| 1cdec61be6 | |||
| b0ddb26e73 | |||
| 181bafd012 | |||
| e054fc1ef1 | |||
| 9d9ad86dd5 | |||
| afe4e5d62e | |||
| 52950f1322 | |||
| 026c80992e | |||
| 0ee2b74ff3 | |||
| 3a0f7eca54 | |||
| f4d530b4b1 | |||
| 4ccbfb56a4 | |||
| d02904c9a3 | |||
| c8279c0b99 | |||
| f4f184e115 | |||
| b2a86e312b | |||
| 9d56617caf | |||
| de7b8940fe | |||
| 09e94ec176 | |||
| 832ceeba56 | |||
| ea7c3c8485 | |||
| bc36c8074e | |||
| 9fccafa3ac | |||
| fa083098fc | |||
| 7688c437c0 | |||
| 697ac83040 | |||
| a742105c21 | |||
| 7a76ec9e02 | |||
| b2a0e7958b | |||
| 99439f0a5c | |||
| ef91c8123e | |||
| 5eb5742b3d | |||
| 296cf3e34b | |||
| e98c3f92c1 | |||
| d202dfc225 | |||
| 6202f6157a | |||
| b1e8e5389b | |||
| 95f6381da4 | |||
| b07e3b4a91 | |||
| 86bd9a2674 | |||
| 29a36839aa | |||
| 85cb7c92e7 | |||
| e827bc9a07 | |||
| a6f19a1657 | |||
| 6229d0c616 | |||
| bc6c969f21 | |||
| 8f4ede7785 | |||
| 877adb082c | |||
| 90818bb147 | |||
| f767a94c84 | |||
| 89e50b94d3 | |||
| c4d97d095f | |||
| 67fb3f10d5 | |||
| ea8d390596 | |||
| cff382605c | |||
| 52af8afac2 | |||
| 03b0268dc2 | |||
| c09e93e288 | |||
| 694e3b7f3a | |||
| 32c367090b | |||
| abcfe2b757 | |||
| f7687008b7 | |||
| b156264684 | |||
| 3f9a80942e | |||
| dc62e393c3 | |||
| 46be0f6610 | |||
| dd0a16c3d5 | |||
| a15ed6eaee | |||
| 3005565bba | |||
| cf45e7536f | |||
| 1d97d95c10 | |||
| 4a1b1675cb | |||
| 8c5249ba4b | |||
| b936591240 | |||
| 76e664d647 | |||
| 0253c2a756 | |||
| d27613f55c | |||
| ca8d478e87 | |||
| c63c17d49f | |||
| 801e58d52e | |||
| 06e9625c64 | |||
| 5800e8d8e9 | |||
| 623aa58163 | |||
| 45cfec5b29 | |||
| 5a9a231359 | |||
| 1736bf5510 | |||
| ee8931f886 | |||
| 1a1b891309 | |||
| 2eaac3d381 | |||
| f03249898a | |||
| 0981cfa902 | |||
| 37fbcfa22b | |||
| 0ee441a976 | |||
| cf8de3baa9 | |||
| 404ee238a3 | |||
| 5a5d171ba2 | |||
| aadee068b3 | |||
| a46e2ebfd8 | |||
| f710b1aac3 | |||
| f6fe6e70b9 | |||
| bed8861179 | |||
| 180d7b1b5b | |||
| 386416ee5d | |||
| 6b5aa91f3d | |||
| e80b80f5d1 | |||
| 9e35441281 | |||
| e28ad50bec | |||
| f48c5ee252 | |||
| 98a94dec29 | |||
| 7d95e7765d | |||
| ee75b30683 | |||
| ca9d4e3155 | |||
| 633bcbb6c4 | |||
| 2d4af61e6c | |||
| 45329912e6 | |||
| b9d56a8ecc | |||
| 91c1e53e52 | |||
| 73a87a8ea8 | |||
| bb0a614c39 | |||
| f11ea79406 | |||
| e817b20840 | |||
| 516f766a44 | |||
| f5791c79a5 | |||
| f6a1a76095 | |||
| bbb9145744 | |||
| 194853d860 | |||
| 92670d5711 | |||
| 8a2ea971e1 | |||
| 8d924b60d7 | |||
| 34595c266d | |||
| 638ae9bdd5 | |||
| 713ce7836f | |||
| 093c6652a8 | |||
| 17f0ac1eae | |||
| 43616d1874 | |||
| 9dc4f2ca80 | |||
| 73e3ac7dd8 | |||
| 8ff639913d | |||
| 45419586fe | |||
| d8a480b2a8 | |||
| 29d87246a2 | |||
| 58e638d3cb | |||
| b52380f376 | |||
| 4ae74fb7f6 | |||
| 7d1acd3d79 | |||
| 12e107a71b | |||
| fba72e1e8d | |||
| 7bbee053c6 | |||
| 6ea1a3bacf | |||
| 603afe4466 | |||
| 037ee8c07a | |||
| df1cef59d5 | |||
| 3fcd196c04 | |||
| 8ee5e7cd0a | |||
| 1ec85063ee | |||
| 92ba889cae | |||
| f17162c2e2 | |||
| fb233c0aa4 | |||
| 369c819a27 | |||
| f1eb4bd3a5 | |||
| 2f828683da | |||
| 13db151297 | |||
| bb95c231e5 | |||
| dcea14fb99 | |||
| 282fed27da | |||
| cf3ffe9c74 | |||
| 5d01a06245 | |||
| 02cdda56e2 | |||
| ffecd97665 | |||
| 779cf9418e | |||
| 34b4452645 | |||
| da1c4c23e6 | |||
| a5d0a21757 | |||
| 29454f7288 | |||
| e271711c5b | |||
| 4c78da3bbf | |||
| 71bab2c315 | |||
| fceba13b03 | |||
| 8ac3937bf4 | |||
| 1c1729854e | |||
| 14c78d9065 | |||
| b1cb9259da | |||
| 7d2af61989 | |||
| 03b5c2e246 | |||
| 33d5d5e24f | |||
| 3df2a4a70b | |||
| 6b41970e97 | |||
| 92eb6eb1b6 | |||
| 206238e83f | |||
| df882bbcbc | |||
| 6c1c3a99dd | |||
| 54067ec449 | |||
| 4c11e97922 | |||
| 8df9007a8e | |||
| 702b944698 | |||
| 172d24fd3c | |||
| 28b450fd3c | |||
| 485caf1d92 | |||
| 29cd75a6d2 | |||
| b3fe10baa8 | |||
| 093cc9faf0 | |||
| be4e809254 | |||
| dc5e15f919 | |||
| ad7b291062 | |||
| b54c1caa74 | |||
| c3cf123189 | |||
| 3a2900621c | |||
| 442903ea5e | |||
| 639cbf6d53 | |||
| e03b5754a8 | |||
| 4ce86a061f | |||
| fa6e170feb | |||
| 51f72daba1 | |||
| 8ce577db37 | |||
| d3ab152d30 | |||
| a130033480 | |||
| ef95ede833 | |||
| cdb1140f10 | |||
| d06e5f25b0 | |||
| 2777ac96cc | |||
| fd42f1ef24 | |||
| 8b3ff5a82d | |||
| 482ebfbb68 | |||
| 67c4fa2966 | |||
| a3389a31cd | |||
| 8d74a976a1 | |||
| 6d104251b3 | |||
| f16c79bb9a | |||
| 1fe22e4b7b | |||
| c7fa2c04ad | |||
| 8ca882d1c8 | |||
| 5d368990dc | |||
| 4adbd7af4c | |||
| 1935a4aca3 | |||
| c4d96f6ea3 | |||
| f2693ee957 | |||
| 0327e71f0f | |||
| 69c2cf2c4f | |||
| 9f02be0823 | |||
| b5553af8ed | |||
| 4d6f4303f5 | |||
| 8a0afae90f | |||
| a53f89cd2c | |||
| 280c03dcad | |||
| e70fb42f87 | |||
| f633dbba64 | |||
| 1b85eea28e | |||
| fb9a5f928f | |||
| 4459483862 | |||
| a0cf7ecc98 | |||
| c658a0fcb4 | |||
| f40284c413 | |||
| 786799225c | |||
| dc418a7033 | |||
| 15cc4345ab | |||
| 5b02a43957 | |||
| c94a7613ca | |||
| 5fa0c87ab0 | |||
| 75aa01791a | |||
| 97a6152ea9 | |||
| 03f091a77f | |||
| 3f5c5cbe82 | |||
| 8696a423b0 | |||
| 107f8db9bc | |||
| b11c900a4c | |||
| ac4aa97103 | |||
| 0bc93c6a1e | |||
| 53ccd196d7 | |||
| 0d049a0be7 | |||
| 01c24ab4cd | |||
| e8d9701a26 | |||
| 5567a1e9ac | |||
| fa5016713f | |||
| f28a82de71 | |||
| 7c2fae7b9d | |||
| 70934e54cf | |||
| f6ad275030 | |||
| 6666a78936 | |||
| bbb2cdcceb | |||
| 6b6e18695f | |||
| b63962e90b | |||
| 4434de6241 | |||
| 6d572424ac | |||
| d371d14c1f | |||
| 72eda1e909 | |||
| 7dbf8a8a8e | |||
| 37ebf1827f | |||
| e65252725a | |||
| 6f53f2ac64 | |||
| deaba46e1c | |||
| 99d7155729 | |||
| f30439a544 | |||
| 997eddfed1 | |||
| 52340aca78 | |||
| e1fb446888 | |||
| 83443ad2b5 | |||
| 3fcc067481 | |||
| 3e564eaf19 | |||
| 0a90df2b14 | |||
| 4ab75c1c03 | |||
| 65e21faa3e | |||
| bf10fd0cf0 | |||
| 83ce04dc8d | |||
| f7bbec6be4 | |||
| 721902c2d4 | |||
| e6b366020a | |||
| cec84b857b | |||
| 1d4a7a7b02 | |||
| 701411c1b9 | |||
| 013463aafc | |||
| 39c15b2868 | |||
| 60ca634eff | |||
| be282dd038 | |||
| b368acf941 | |||
| 530291f81c | |||
| 393dc51167 | |||
| 8cc1397ace | |||
| 984cc7a4f2 | |||
| e7b9903341 | |||
| e3e01e07b1 | |||
| d18aa1db98 | |||
| c155e4a7c9 | |||
| fdf0be09db | |||
| e1addc5aef | |||
| b4b4927370 | |||
| 0ffceb9691 | |||
| 1e810d2426 | |||
| c0110e7f29 | |||
| 86ab880c90 | |||
| f6ab0f8f46 | |||
| f01b205486 | |||
| 8962ced038 | |||
| 04d7884af8 | |||
| 6732b6601e | |||
| eb8f1dd553 | |||
| c8341d9dc4 | |||
| b239b3a4db | |||
| 5b9120ba6c | |||
| eac01868ca | |||
| 8ace30ee23 | |||
| 5ffade663a | |||
| c025e25839 | |||
| 8f2843bfcf | |||
| 9397372f87 | |||
| 8bbf6da052 | |||
| f7d0cecdac | |||
| 8a2f3405d5 | |||
| 25db35e41e | |||
| 99000fada1 | |||
| 58b2f8ca17 | |||
| 8be3c1aaf2 | |||
| 2ee8639eaf | |||
| 32605578dd | |||
| fe0bba6df6 | |||
| 5fdcd6298f | |||
| 55943dbff6 | |||
| d12e571b20 | |||
| 0c15f05316 | |||
| 25c9f8e038 | |||
| a3811371cc | |||
| f734e196e5 | |||
| 6129f4722f | |||
| 585d7d0b87 | |||
| cdfc198f28 | |||
| 6fcb3d3d5e | |||
| 358d9ec06d | |||
| 322c8c1cf3 | |||
| 47eb0c34a2 | |||
| 4a290a85e6 | |||
| 5489c50cc0 | |||
| 066e40dada | |||
| 123d04ff7b | |||
| d5881736cf | |||
| 5e539da3da | |||
| ba58ca9d5c | |||
| 117007dfa1 | |||
| d29b3633d1 | |||
| 7cf4baa92a | |||
| 6c3dfdfe6d | |||
| 149d159c05 | |||
| c0ad16f497 | |||
| 9edb631d52 | |||
| 58d2f0a41e | |||
| 255d9427b6 | |||
| d29f4489de | |||
| 4367fc54bf | |||
| b89116eb55 | |||
| 9430e9c8e2 | |||
| b01d53a247 | |||
| 65cbba3c2e | |||
| f93e7b91ff | |||
| 04069bab82 | |||
| 3106035ef9 | |||
| 18720b3302 | |||
| 12e546e63a | |||
| c28936fefb | |||
| 080d196138 | |||
| d3967b37cd | |||
| 0089ea2321 | |||
| 3f35124838 | |||
| 6ca5fb6b20 | |||
| a3b0273445 | |||
| 2a54797dce | |||
| 9770016eec | |||
| 6210716199 | |||
| e41a16dbf3 | |||
| 01f4aa018f | |||
| f9baeefbaf | |||
| af3417d6cc | |||
| 17bf8d0124 | |||
| c3e02286d3 | |||
| a9d82bf157 | |||
| e097df912e | |||
| 477bb6165f | |||
| 19850e8c5a | |||
| 12dcf76da9 | |||
| 36aac328e4 | |||
| 9cf81c7ad4 | |||
| 6c6417e595 | |||
| efa8ba5965 | |||
| fd02385c22 | |||
| 713b21de14 | |||
| af144a5184 | |||
| 9b31ae3146 | |||
| 4cb0012872 | |||
| eaa68327f7 | |||
| 68ef618028 | |||
| 3ecdafa685 | |||
| 20ae9dea19 | |||
| 34cd106357 | |||
| 714fce7e59 | |||
| 08e4ea384e | |||
| fe0f9743d3 | |||
| 57019e170f | |||
| 9f303cc116 | |||
| e504b20235 | |||
| f64b0d3818 | |||
| 1a26ea0911 | |||
| 7098ab6509 | |||
| 0d3589ca24 | |||
| f02ff62a08 | |||
| fbfc817c5f | |||
| 13601031cb | |||
| 442cad69a7 | |||
| be6545a366 | |||
| 32fdd36802 | |||
| fbc54526ed | |||
| a3306e4a81 | |||
| 3d858b21fa | |||
| 62b557f82c | |||
| 158c82ff5f | |||
| fd410c0281 | |||
| 65e3696029 | |||
| 690a5119f4 | |||
| cc0653c68a | |||
| 042a15d294 | |||
| 8e4c0f60a1 | |||
| 5615fc09e6 | |||
| d68f1e4cfa | |||
| 0c4901487d | |||
| 7f4b2d6e42 | |||
| 715a49d9fe | |||
| b98c1a0627 | |||
| da30292d84 | |||
| 7bda5c06de | |||
| 3d5847f4b3 | |||
| db400dffb5 | |||
| 199cdf6899 | |||
| 752171d5b8 | |||
| 7a5714cc85 | |||
| c77f5eee8c | |||
| aacfed40f8 | |||
| ec1059e74c | |||
| 3500217f94 | |||
| 427f8b1522 | |||
| 8b52bad16f | |||
| daed0b60bc | |||
| 4654f7aa37 | |||
| 70e87dad1c | |||
| ba8d8a6f05 | |||
| 605d267fe8 | |||
| 8f2a17585e | |||
| 51424d01a9 | |||
| f5ff9b2208 | |||
| 457f4c410a | |||
| bb013d5c3c | |||
| a9c7dbd17a | |||
| 09fdc946a0 | |||
| 31f1bce16b | |||
| 2f3ddaec20 | |||
| 7cd37e6e95 | |||
| a938009074 | |||
| 21d08ff742 | |||
| da8b41b12a | |||
| 6e031727fa | |||
| 381890b578 | |||
| 71fa6d765f | |||
| 9793130f6c | |||
| aadfa9aa9c | |||
| 645bba96cd |
@@ -3108,6 +3108,115 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bryanlopezinc",
|
||||
"name": "BRYAN ",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/23613427?v=4",
|
||||
"profile": "https://github.com/bryanlopezinc",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "U-H-T",
|
||||
"name": "U-H-T",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/64061710?v=4",
|
||||
"profile": "https://github.com/U-H-T",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tyree",
|
||||
"name": "Matt Tyree",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5395363?v=4",
|
||||
"profile": "https://github.com/Tyree",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "FlorentDotMe",
|
||||
"name": "Florent Bervas",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/292081?v=4",
|
||||
"profile": "http://spoontux.net",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dbakan",
|
||||
"name": "Daniel Albertsen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4498077?v=4",
|
||||
"profile": "https://ditscheri.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "r-xyz",
|
||||
"name": "r-xyz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/100710244?v=4",
|
||||
"profile": "https://github.com/r-xyz",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DrekiDegga",
|
||||
"name": "Steven Mainor",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/47491036?v=4",
|
||||
"profile": "https://github.com/DrekiDegga",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "arne-kroeger",
|
||||
"name": "arne-kroeger",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/65785975?v=4",
|
||||
"profile": "https://github.com/arne-kroeger",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Glukose1",
|
||||
"name": "Glukose1",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/167117705?v=4",
|
||||
"profile": "https://github.com/Glukose1",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Scarzy",
|
||||
"name": "Scarzy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1197791?v=4",
|
||||
"profile": "https://github.com/Scarzy",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "setpill",
|
||||
"name": "setpill",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/37372069?v=4",
|
||||
"profile": "https://github.com/setpill",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "swift2512",
|
||||
"name": "swift2512",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3755203?v=4",
|
||||
"profile": "https://github.com/swift2512",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DB SETUP
|
||||
# --------------------------------------------
|
||||
# https://mariadb.com/kb/en/mariadb-server-docker-official-image-environment-variables/
|
||||
|
||||
MYSQL_DATABASE=snipeit
|
||||
MYSQL_USER=snipeit
|
||||
MYSQL_PASSWORD=changeme1234
|
||||
MYSQL_ROOT_PASSWORD=changeme1234
|
||||
# --------------------------------------------
|
||||
# REQUIRED: BASIC APP SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_ENV=develop
|
||||
APP_DEBUG=false
|
||||
# please regenerate the APP_KEY value by calling `docker-compose run --rm snipeit bash` and then `php artisan key:generate --show` and then copy paste the value here
|
||||
APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=
|
||||
APP_URL=http://localhost:8000
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
MAX_RESULTS=500
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: UPLOADED FILE STORAGE SETTINGS
|
||||
# --------------------------------------------
|
||||
PRIVATE_FILESYSTEM_DISK=local
|
||||
PUBLIC_FILESYSTEM_DISK=local_public
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mariadb
|
||||
DB_DATABASE=snipeit
|
||||
DB_USERNAME=snipeit
|
||||
DB_PASSWORD=changeme1234
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SSL DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_SSL=false
|
||||
DB_SSL_IS_PAAS=false
|
||||
DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
DB_SSL_CA_PATH=null
|
||||
DB_SSL_CIPHER=null
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME='Snipe-IT'
|
||||
MAIL_REPLYTO_ADDR=you@example.com
|
||||
MAIL_REPLYTO_NAME='Snipe-IT'
|
||||
MAIL_AUTO_EMBED_METHOD='attachment'
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: IMAGE LIBRARY
|
||||
# This should be gd or imagick
|
||||
# --------------------------------------------
|
||||
IMAGE_LIB=gd
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: BACKUP SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_BACKUP_NOTIFICATION_DRIVER=null
|
||||
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
|
||||
BACKUP_ENV=true
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SESSION SETTINGS
|
||||
# --------------------------------------------
|
||||
SESSION_LIFETIME=12000
|
||||
EXPIRE_ON_CLOSE=false
|
||||
ENCRYPT=false
|
||||
COOKIE_NAME=snipeit_session
|
||||
COOKIE_DOMAIN=null
|
||||
SECURE_COOKIES=false
|
||||
API_TOKEN_EXPIRATION_YEARS=40
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SECURITY HEADER SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
|
||||
ALLOW_IFRAMING=false
|
||||
REFERRER_POLICY=same-origin
|
||||
ENABLE_CSP=false
|
||||
CORS_ALLOWED_ORIGINS=null
|
||||
ENABLE_HSTS=false
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: CACHE SETTINGS
|
||||
# --------------------------------------------
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
CACHE_PREFIX=snipeit
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: REDIS SETTINGS
|
||||
# --------------------------------------------
|
||||
REDIS_HOST=redis
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MEMCACHED SETTINGS
|
||||
# --------------------------------------------
|
||||
MEMCACHED_HOST=null
|
||||
MEMCACHED_PORT=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: PUBLIC S3 Settings
|
||||
# --------------------------------------------
|
||||
PUBLIC_AWS_SECRET_ACCESS_KEY=null
|
||||
PUBLIC_AWS_ACCESS_KEY_ID=null
|
||||
PUBLIC_AWS_DEFAULT_REGION=null
|
||||
PUBLIC_AWS_BUCKET=null
|
||||
PUBLIC_AWS_URL=null
|
||||
PUBLIC_AWS_BUCKET_ROOT=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: PRIVATE S3 Settings
|
||||
# --------------------------------------------
|
||||
PRIVATE_AWS_ACCESS_KEY_ID=null
|
||||
PRIVATE_AWS_SECRET_ACCESS_KEY=null
|
||||
PRIVATE_AWS_DEFAULT_REGION=null
|
||||
PRIVATE_AWS_BUCKET=null
|
||||
PRIVATE_AWS_URL=null
|
||||
PRIVATE_AWS_BUCKET_ROOT=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: AWS Settings
|
||||
# --------------------------------------------
|
||||
AWS_ACCESS_KEY_ID=null
|
||||
AWS_SECRET_ACCESS_KEY=null
|
||||
AWS_DEFAULT_REGION=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: LOGIN THROTTLING
|
||||
# --------------------------------------------
|
||||
LOGIN_MAX_ATTEMPTS=5
|
||||
LOGIN_LOCKOUT_DURATION=60
|
||||
RESET_PASSWORD_LINK_EXPIRES=900
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MISC
|
||||
# --------------------------------------------
|
||||
LOG_CHANNEL=stderr
|
||||
LOG_MAX_DAYS=10
|
||||
APP_LOCKED=false
|
||||
APP_CIPHER=AES-256-CBC
|
||||
APP_FORCE_TLS=false
|
||||
GOOGLE_MAPS_API=
|
||||
LDAP_MEM_LIM=500M
|
||||
LDAP_TIME_LIM=600
|
||||
+21
-15
@@ -1,20 +1,20 @@
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DB SETUP
|
||||
# REQUIRED: DOCKER SPECIFIC SETTINGS
|
||||
# --------------------------------------------
|
||||
MYSQL_DATABASE=snipeit
|
||||
MYSQL_USER=snipeit
|
||||
MYSQL_PASSWORD=changeme1234
|
||||
MYSQL_ROOT_PASSWORD=changeme1234
|
||||
APP_VERSION=v6.4.1
|
||||
APP_PORT=8000
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: BASIC APP SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_ENV=develop
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
# please regenerate the APP_KEY value by calling `docker-compose run --rm snipeit bash` and then `php artisan key:generate --show` and then copy paste the value here
|
||||
# Please regenerate the APP_KEY value by calling `docker compose run --rm snipeit php artisan key:generate --show`. Copy paste the value here
|
||||
APP_KEY=base64:3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=
|
||||
APP_URL=http://localhost:8000
|
||||
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ identifier
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
APP_LOCALE=en-US
|
||||
MAX_RESULTS=500
|
||||
|
||||
# --------------------------------------------
|
||||
@@ -27,10 +27,12 @@ PUBLIC_FILESYSTEM_DISK=local_public
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mariadb
|
||||
DB_HOST=db
|
||||
DB_PORT='3306'
|
||||
DB_DATABASE=snipeit
|
||||
DB_USERNAME=snipeit
|
||||
DB_PASSWORD=changeme1234
|
||||
MYSQL_ROOT_PASSWORD=changeme1234
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_CHARSET=utf8mb4
|
||||
@@ -50,25 +52,30 @@ DB_SSL_VERIFY_SERVER=null
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_TLS_VERIFY_PEER=true
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME='Snipe-IT'
|
||||
MAIL_REPLYTO_ADDR=you@example.com
|
||||
MAIL_REPLYTO_NAME='Snipe-IT'
|
||||
MAIL_AUTO_EMBED_METHOD='attachment'
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATA PROTECTION
|
||||
# --------------------------------------------
|
||||
ALLOW_BACKUP_DELETE=false
|
||||
ALLOW_DATA_PURGE=false
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: IMAGE LIBRARY
|
||||
# This should be gd or imagick
|
||||
# --------------------------------------------
|
||||
IMAGE_LIB=gd
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: BACKUP SETTINGS
|
||||
# --------------------------------------------
|
||||
@@ -76,7 +83,6 @@ MAIL_BACKUP_NOTIFICATION_DRIVER=null
|
||||
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
|
||||
BACKUP_ENV=true
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SESSION SETTINGS
|
||||
# --------------------------------------------
|
||||
@@ -91,7 +97,7 @@ API_TOKEN_EXPIRATION_YEARS=40
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SECURITY HEADER SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
|
||||
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1,172.0.0.0/8
|
||||
ALLOW_IFRAMING=false
|
||||
REFERRER_POLICY=same-origin
|
||||
ENABLE_CSP=false
|
||||
@@ -109,7 +115,7 @@ CACHE_PREFIX=snipeit
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: REDIS SETTINGS
|
||||
# --------------------------------------------
|
||||
REDIS_HOST=redis
|
||||
REDIS_HOST=null
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ APP_DEBUG=false
|
||||
APP_KEY=base64:hTUIUh9CP6dQx+6EjSlfWTgbaMaaRvlpEwk45vp+xmk=
|
||||
APP_URL=http://127.0.0.1:8000
|
||||
APP_TIMEZONE='US/Eastern'
|
||||
APP_LOCALE=en
|
||||
APP_LOCALE=en-US
|
||||
APP_LOCKED=false
|
||||
MAX_RESULTS=200
|
||||
|
||||
@@ -41,7 +41,7 @@ DB_SSL_VERIFY_SERVER=null
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER="log"
|
||||
MAIL_MAILER="log"
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
+11
-3
@@ -32,6 +32,8 @@ DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
DB_SANITIZE_BY_DEFAULT=false
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SSL DATABASE SETTINGS
|
||||
@@ -47,17 +49,21 @@ DB_SSL_VERIFY_SERVER=null
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=email-smtp.us-west-2.amazonaws.com
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=YOURUSERNAME
|
||||
MAIL_PASSWORD=YOURPASSWORD
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME='Snipe-IT'
|
||||
MAIL_REPLYTO_ADDR=you@example.com
|
||||
MAIL_REPLYTO_NAME='Snipe-IT'
|
||||
MAIL_AUTO_EMBED_METHOD='attachment'
|
||||
MAIL_TLS_VERIFY_PEER=true
|
||||
|
||||
# MAIL_ENCRYPTION is no longer supported. SymfonyMailer will use tls if it's
|
||||
# advertised, and won't if it's not. If you want to use your mail server's IP but it's failing
|
||||
# because of certificate errors, set MAIL_TLS_VERIFY_PEER-true
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: IMAGE LIBRARY
|
||||
@@ -83,6 +89,7 @@ SESSION_LIFETIME=12000
|
||||
EXPIRE_ON_CLOSE=false
|
||||
ENCRYPT=false
|
||||
COOKIE_NAME=snipeit_session
|
||||
PASSPORT_COOKIE_NAME='snipeit_passport_token'
|
||||
COOKIE_DOMAIN=null
|
||||
SECURE_COOKIES=false
|
||||
API_TOKEN_EXPIRATION_YEARS=15
|
||||
@@ -179,6 +186,7 @@ REPORT_TIME_LIMIT=12000
|
||||
REQUIRE_SAML=false
|
||||
API_THROTTLE_PER_MINUTE=120
|
||||
CSV_ESCAPE_FORMULAS=true
|
||||
LIVEWIRE_URL_PREFIX=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: HASHING
|
||||
@@ -193,4 +201,4 @@ ARGON_TIME=2
|
||||
# OPTIONAL: SCIM
|
||||
# --------------------------------------------
|
||||
SCIM_TRACE=false
|
||||
SCIM_STANDARDS_COMPLIANCE=false
|
||||
SCIM_STANDARDS_COMPLIANCE=false
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ DB_PASSWORD=null
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER=log
|
||||
MAIL_MAILER=log
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
+1
-1
@@ -18,6 +18,6 @@ APP_KEY=base64:tu9NRh/a6+dCXBDGvg0Gv/0TcABnFsbT4AKxrr8mwQo=
|
||||
LOGIN_MAX_ATTEMPTS=1000000
|
||||
LOGIN_LOCKOUT_DURATION=100000000
|
||||
|
||||
MAIL_DRIVER=log
|
||||
MAIL_MAILER=log
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME=Snipe-IT
|
||||
|
||||
+1
-1
@@ -15,6 +15,6 @@ APP_KEY=base64:tu9NRh/a6+dCXBDGvg0Gv/0TcABnFsbT4AKxrr8mwQo=
|
||||
LOGIN_MAX_ATTEMPTS=1000000
|
||||
LOGIN_LOCKOUT_DURATION=100000000
|
||||
|
||||
MAIL_DRIVER=log
|
||||
MAIL_MAILER=log
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME=Snipe-IT
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
- :woman_technologist: ready for dev
|
||||
- :moneybag: bounty
|
||||
- :hand: bug
|
||||
- "🔐 security"
|
||||
- "👩💻 ready for dev"
|
||||
- "💰 bounty"
|
||||
- "✋ bug"
|
||||
|
||||
exemptMilestones: true
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
only: issues
|
||||
|
||||
# Comment to post when removing the stale label.
|
||||
unmarkComment: >
|
||||
Okay, it looks like this issue or feature request might still be important. We'll re-open
|
||||
it for now. Thank you for letting us know!
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Is this still relevant? We haven't heard from anyone in a bit. If so,
|
||||
please comment with any updates or additional detail.
|
||||
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Don't
|
||||
take it personally, we just need to keep a handle on things. Thank you
|
||||
for your contributions!
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because it has not had
|
||||
recent activity. If you believe this is still an issue, please confirm that
|
||||
this issue is still happening in the most recent version of Snipe-IT and reply
|
||||
to this thread to re-open it.
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.1
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.5
|
||||
with:
|
||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||
# You can also omit the token and run the tools that support default configurations
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Crowdin push
|
||||
uses: crowdin/github-action@v1
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine
|
||||
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
name: 'Close stale issues'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# contents: write # only for delete-branch option
|
||||
issues: write
|
||||
# pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
debug-only: true
|
||||
operations-per-run: 100 # just while we're debugging
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 60
|
||||
days-before-close: 7
|
||||
exempt-all-milestones: true
|
||||
stale-issue-message: >
|
||||
Is this still relevant? We haven't heard from anyone in a bit. If so,
|
||||
please comment with any updates or additional detail.
|
||||
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Don't
|
||||
take it personally, we just need to keep a handle on things. Thank you
|
||||
for your contributions!
|
||||
close-issue-message: >
|
||||
This issue has been automatically closed because it has not had
|
||||
recent activity. If you believe this is still an issue, please confirm that
|
||||
this issue is still happening in the most recent version of Snipe-IT and reply
|
||||
to this thread to re-open it.
|
||||
# There doesn't seem to be a 'reopen issue message'?
|
||||
# Since there is no 'stale-pr-message' - PR's should not be stale'd
|
||||
stale-issue-label: stale
|
||||
exempt-issue-labels: >
|
||||
pinned,security,:woman_technologist: ready for dev,:moneybag: bounty,:hand: bug,🔐 security,👩💻 ready for dev,💰 bounty,✋ bug
|
||||
@@ -25,9 +25,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
- "8.0"
|
||||
- "8.1.1"
|
||||
- "8.1"
|
||||
- "8.2"
|
||||
- "8.3"
|
||||
|
||||
name: PHP ${{ matrix.php-version }}
|
||||
|
||||
@@ -58,11 +58,17 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- name: Generate key
|
||||
run: php artisan key:generate
|
||||
|
||||
- name: Directory Permissions
|
||||
run: chmod -R 777 storage bootstrap/cache
|
||||
- name: Setup Laravel
|
||||
env:
|
||||
DB_CONNECTION: mysql
|
||||
DB_DATABASE: snipeit
|
||||
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
||||
DB_USERNAME: root
|
||||
run: |
|
||||
php artisan key:generate
|
||||
php artisan migrate --force
|
||||
php artisan passport:install
|
||||
chmod -R 777 storage bootstrap/cache
|
||||
|
||||
- name: Execute tests (Unit and Feature tests) via PHPUnit
|
||||
env:
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
name: Tests in Postgres
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgresql:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_DB: snipeit
|
||||
POSTGRES_USER: snipeit
|
||||
POSTGRES_PASSWORD: password
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-version:
|
||||
- "8.1"
|
||||
- "8.2"
|
||||
- "8.3"
|
||||
|
||||
name: PHP ${{ matrix.php-version }}
|
||||
|
||||
steps:
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
coverage: none
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get Composer Cache Directory
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-composer-
|
||||
|
||||
- name: Copy .env
|
||||
run: |
|
||||
cp -v .env.testing.example .env
|
||||
cp -v .env.testing.example .env.testing
|
||||
|
||||
- name: Install Dependencies
|
||||
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- name: Setup Laravel
|
||||
env:
|
||||
DB_CONNECTION: pgsql
|
||||
DB_DATABASE: snipeit
|
||||
DB_PORT: ${{ job.services.postgresql.ports[5432] }}
|
||||
DB_USERNAME: snipeit
|
||||
DB_PASSWORD: password
|
||||
run: |
|
||||
php artisan key:generate
|
||||
php artisan migrate --force
|
||||
php artisan passport:install
|
||||
chmod -R 777 storage bootstrap/cache
|
||||
|
||||
- name: Execute tests (Unit and Feature tests) via PHPUnit
|
||||
env:
|
||||
DB_CONNECTION: pgsql
|
||||
DB_DATABASE: snipeit
|
||||
DB_PORT: ${{ job.services.postgresql.ports[5432] }}
|
||||
DB_USERNAME: snipeit
|
||||
DB_PASSWORD: password
|
||||
run: php artisan test --parallel
|
||||
@@ -49,6 +49,9 @@ jobs:
|
||||
- name: Generate key
|
||||
run: php artisan key:generate
|
||||
|
||||
- name: Setup Passport
|
||||
run: php artisan passport:keys
|
||||
|
||||
- name: Directory Permissions
|
||||
run: chmod -R 777 storage bootstrap/cache
|
||||
|
||||
|
||||
@@ -67,3 +67,6 @@ _ide_helper_models.php
|
||||
/.phplint-cache
|
||||
storage/ldap_client_tls.cert
|
||||
storage/ldap_client_tls.key
|
||||
/storage/framework/testing
|
||||
|
||||
/.phpunit.cache
|
||||
@@ -3,8 +3,8 @@
|
||||
"DOC2": "In other words, what you see locally are the requirements for your _current_ install",
|
||||
"DOC3": "Please don't rely on these versions for planning upgrades unless you've fetched the most recent version",
|
||||
"DOC4": "You should really just ignore it and run upgrade.php. Really",
|
||||
"php_min_version": "7.4.0",
|
||||
"php_max_major_minor": "8.1",
|
||||
"php_max_wontwork": "8.2.0",
|
||||
"current_snipeit_version": "6.3"
|
||||
"php_min_version": "8.1.0",
|
||||
"php_max_major_minor": "8.3",
|
||||
"php_max_wontwork": "8.4.0",
|
||||
"current_snipeit_version": "7.0"
|
||||
}
|
||||
|
||||
+3
-1
@@ -50,7 +50,9 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> | [<img src="https://avatars.githubusercontent.com/u/5731963?v=4" width="110px;"/><br /><sub>dboth</sub>](http://dboth.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [<img src="https://avatars.githubusercontent.com/u/87536651?v=4" width="110px;"/><br /><sub>Zachary Fleck</sub>](https://github.com/zacharyfleck)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [<img src="https://avatars.githubusercontent.com/u/74609912?v=4" width="110px;"/><br /><sub>VIKAAS-A</sub>](https://github.com/vikaas-cyper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") | [<img src="https://avatars.githubusercontent.com/u/88882041?v=4" width="110px;"/><br /><sub>Abdul Kareem</sub>](https://github.com/ak-piracha)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ak-piracha "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/111287779?v=4" width="110px;"/><br /><sub>NojoudAlshehri</sub>](https://github.com/NojoudAlshehri)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [<img src="https://avatars.githubusercontent.com/u/54367449?v=4" width="110px;"/><br /><sub>Stefan Stidl</sub>](https://github.com/stefanstidlffg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [<img src="https://avatars.githubusercontent.com/u/87803479?v=4" width="110px;"/><br /><sub>Quentin Aymard</sub>](https://github.com/qay21)<br />[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | [<img src="https://avatars.githubusercontent.com/u/5396871?v=4" width="110px;"/><br /><sub>Grant Le Roux</sub>](https://github.com/cram42)<br />[💻](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") | [<img src="https://avatars.githubusercontent.com/u/58479551?v=4" width="110px;"/><br /><sub>Bogdan</sub>](http://@singrity)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Singrity "Code") | [<img src="https://avatars.githubusercontent.com/u/3483684?v=4" width="110px;"/><br /><sub>mmanjos</sub>](https://github.com/mmanjos)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mmanjos "Code") | [<img src="https://avatars.githubusercontent.com/u/7429229?v=4" width="110px;"/><br /><sub>Abdelaziz Faki</sub>](https://azooz2014.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azooz2014 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/47315739?v=4" width="110px;"/><br /><sub>bilias</sub>](https://github.com/bilias)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bilias "Code") | [<img src="https://avatars.githubusercontent.com/u/2565989?v=4" width="110px;"/><br /><sub>coach1988</sub>](https://github.com/coach1988)<br />[💻](https://github.com/snipe/snipe-it/commits?author=coach1988 "Code") | [<img src="https://avatars.githubusercontent.com/u/11910225?v=4" width="110px;"/><br /><sub>MrM</sub>](https://github.com/mauro-miatello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mauro-miatello "Code") | [<img src="https://avatars.githubusercontent.com/u/60405354?v=4" width="110px;"/><br /><sub>koiakoia</sub>](https://github.com/koiakoia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koiakoia "Code") | [<img src="https://avatars.githubusercontent.com/u/5323832?v=4" width="110px;"/><br /><sub>Mustafa Online</sub>](https://github.com/mustafa-online)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mustafa-online "Code") | [<img src="https://avatars.githubusercontent.com/u/104601439?v=4" width="110px;"/><br /><sub>franceslui</sub>](https://github.com/franceslui)<br />[💻](https://github.com/snipe/snipe-it/commits?author=franceslui "Code") | [<img src="https://avatars.githubusercontent.com/u/125313163?v=4" width="110px;"/><br /><sub>Q4kK</sub>](https://github.com/Q4kK)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Q4kK "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [<img src="https://avatars.githubusercontent.com/u/23613427?v=4" width="110px;"/><br /><sub>BRYAN </sub>](https://github.com/bryanlopezinc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/167117705?v=4" width="110px;"/><br /><sub>Glukose1</sub>](https://github.com/Glukose1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Glukose1 "Code") | [<img src="https://avatars.githubusercontent.com/u/1197791?v=4" width="110px;"/><br /><sub>Scarzy</sub>](https://github.com/Scarzy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Scarzy "Code") | [<img src="https://avatars.githubusercontent.com/u/37372069?v=4" width="110px;"/><br /><sub>setpill</sub>](https://github.com/setpill)<br />[💻](https://github.com/snipe/snipe-it/commits?author=setpill "Code") | [<img src="https://avatars.githubusercontent.com/u/3755203?v=4" width="110px;"/><br /><sub>swift2512</sub>](https://github.com/swift2512)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aswift2512 "Bug reports") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
+34
-34
@@ -1,35 +1,35 @@
|
||||
FROM alpine:3.18.6
|
||||
FROM alpine:3.19
|
||||
# Apache + PHP
|
||||
RUN apk add --no-cache \
|
||||
apache2 \
|
||||
php81 \
|
||||
php81-common \
|
||||
php81-apache2 \
|
||||
php81-curl \
|
||||
php81-ldap \
|
||||
php81-mysqli \
|
||||
php81-gd \
|
||||
php81-xml \
|
||||
php81-mbstring \
|
||||
php81-zip \
|
||||
php81-ctype \
|
||||
php81-tokenizer \
|
||||
php81-pdo_mysql \
|
||||
php81-openssl \
|
||||
php81-bcmath \
|
||||
php81-phar \
|
||||
php81-json \
|
||||
php81-iconv \
|
||||
php81-fileinfo \
|
||||
php81-simplexml \
|
||||
php81-session \
|
||||
php81-dom \
|
||||
php81-xmlwriter \
|
||||
php81-xmlreader \
|
||||
php81-sodium \
|
||||
php81-redis \
|
||||
php81-pecl-memcached \
|
||||
php81-exif \
|
||||
php82 \
|
||||
php82-common \
|
||||
php82-apache2 \
|
||||
php82-curl \
|
||||
php82-ldap \
|
||||
php82-mysqli \
|
||||
php82-gd \
|
||||
php82-xml \
|
||||
php82-mbstring \
|
||||
php82-zip \
|
||||
php82-ctype \
|
||||
php82-tokenizer \
|
||||
php82-pdo_mysql \
|
||||
php82-openssl \
|
||||
php82-bcmath \
|
||||
php82-phar \
|
||||
php82-json \
|
||||
php82-iconv \
|
||||
php82-fileinfo \
|
||||
php82-simplexml \
|
||||
php82-session \
|
||||
php82-dom \
|
||||
php82-xmlwriter \
|
||||
php82-xmlreader \
|
||||
php82-sodium \
|
||||
php82-redis \
|
||||
php82-pecl-memcached \
|
||||
php82-exif \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
@@ -42,7 +42,7 @@ COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
# Where apache's PID lives
|
||||
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php81/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php82/php.ini
|
||||
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
|
||||
|
||||
# Enable mod_rewrite
|
||||
@@ -79,12 +79,12 @@ USER root
|
||||
|
||||
VOLUME ["/var/lib/snipeit"]
|
||||
|
||||
# Entrypoints
|
||||
COPY docker/entrypoint_alpine.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
# Startup script
|
||||
COPY docker/startup_alpine.sh /startup.sh
|
||||
RUN chmod +x /startup.sh
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
||||
CMD ["/startup.sh"]
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
@@ -97,7 +97,7 @@ RUN set -eux; \
|
||||
VOLUME [ "/var/lib/snipeit" ]
|
||||
|
||||
COPY --chown=www-data:www-data docker/docker-secrets.env /var/www/html/.env
|
||||
COPY --chmod=655 docker/docker-entrypoint.sh /usr/local/bin/docker-snipeit-entrypoint
|
||||
COPY --chmod=655 docker/startup_alpine_fpm.sh /startup.sh
|
||||
COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
ENTRYPOINT [ "/usr/local/bin/docker-snipeit-entrypoint" ]
|
||||
CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ]
|
||||
ENTRYPOINT [ "/startup.sh" ]
|
||||
CMD [ "/startup.sh", "php-fpm" ]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
This is a FOSS project for asset management in IT Operations. Knowing who has which laptop, when it was purchased in order to depreciate it correctly, handling software licenses, etc.
|
||||
|
||||
It is built on [Laravel 8](http://laravel.com).
|
||||
It is built on [Laravel 10](http://laravel.com).
|
||||
|
||||
Snipe-IT is actively developed and we [release quite frequently](https://github.com/snipe/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
|
||||
|
||||
@@ -72,12 +72,13 @@ Since the release of the JSON REST API, several third-party developers have been
|
||||
- [Snipe-IT plugin for Jira Service Desk](https://marketplace.atlassian.com/apps/1220964/snipe-it-for-jira)
|
||||
- [Python 3 CSV importer](https://github.com/gastamper/snipeit-csvimporter) - allows importing assets into Snipe-IT based on Item Name rather than Asset Tag.
|
||||
- [Snipe-IT Kubernetes Helm Chart](https://github.com/t3n/helm-charts/tree/master/snipeit) - For more information, [click here](https://hub.helm.sh/charts/t3n/snipeit).
|
||||
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-it.
|
||||
- [MosyleSnipeSync](https://github.com/RodneyLeeBrands/MosyleSnipeSync) by [@Karpadiem](https://github.com/Karpadiem) - Python script to synchronize information between Mosyle and Snipe-IT
|
||||
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-IT.
|
||||
- [MosyleSnipeSync](https://github.com/RodneyLeeBrands/MosyleSnipeSync) by [@Karpadiem](https://github.com/Karpadiem) - Python script to synchronize information between Mosyle and Snipe-IT.
|
||||
- [WWW::SnipeIT](https://github.com/SEDC/perl-www-snipeit) by [@SEDC](https://github.com/SEDC) - perl module for accessing the API
|
||||
- [UniFi to Snipe-IT](https://github.com/RodneyLeeBrands/UnifiSnipeSync) by [@karpadiem](https://github.com/karpadiem) - Python script that synchronizes UniFi devices with Snipe-IT.
|
||||
- [Kandji2Snipe](https://github.com/grokability/kandji2snipe) by [@briangoldstein](https://github.com/briangoldstein) - Python script that synchronizes Kandji with Snipe-IT.
|
||||
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by @ReticentRobot - Windows agent for Snipe-IT
|
||||
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by [@ReticentRobot](https://github.com/ReticentRobot) - Windows agent for Snipe-IT.
|
||||
- [Gate Pass Generator](https://github.com/cha7uraAE/snipe-it-gate-pass-system) by [@cha7uraAE](https://github.com/cha7uraAE) - A Streamlit application for generating gate passes based on hardware data from a Snipe-IT API.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ APP_DEBUG=true
|
||||
APP_KEY=base64:glJpcM7BYwWiBggp3SQ/+NlRkqsBQMaGEOjemXqJzOU=
|
||||
APP_URL=http://localhost:8000
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
APP_LOCALE=en-US
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"description": "The maximum number of search results that can be returned at one time.",
|
||||
"value": "500"
|
||||
},
|
||||
"MAIL_DRIVER": {
|
||||
"MAIL_MAILER": {
|
||||
"description": "Mail driver - Generally SMTP on Heroku - https://snipe-it.readme.io/docs/configuration#required-outgoing-mail-settings",
|
||||
"value": "smtp"
|
||||
},
|
||||
@@ -58,9 +58,9 @@
|
||||
"description": "SMTP Server Password",
|
||||
"value": "YOURPASSWORD"
|
||||
},
|
||||
"MAIL_ENCRYPTION": {
|
||||
"description": "Encryption protocol for email sending.",
|
||||
"value": "null"
|
||||
"MAIL_TLS_VERIFY_PEER": {
|
||||
"description": "Ensure validity of TLS certificate on remote mail server",
|
||||
"value": true
|
||||
},
|
||||
"MAIL_FROM_ADDR": {
|
||||
"description": "Email from address",
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class FixupAssignedToWithoutAssignedType extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:assigned-to-fixup
|
||||
{--debug : Display debugging output}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Fixes up assets that have an assigned_to but no assigned_type';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$assets = Asset::whereNull("assigned_type")->whereNotNull("assigned_to")->withTrashed();
|
||||
$this->withProgressBar($assets->get(), function (Asset $asset) {
|
||||
//now check each action log, from the most recent backwards, to find the last checkin or checkout
|
||||
foreach($asset->log()->orderBy("id","desc")->get() as $action_log) {
|
||||
if($this->option("debug")) {
|
||||
$this->info("Asset id: " . $asset->id . " action log, action type is: " . $action_log->action_type);
|
||||
}
|
||||
switch($action_log->action_type) {
|
||||
case 'checkin from':
|
||||
if($this->option("debug")) {
|
||||
$this->info("Doing a checkin for ".$asset->id);
|
||||
}
|
||||
$asset->assigned_to = null;
|
||||
// if you have a required custom field, we still want to save, and we *don't* want an action_log
|
||||
$asset->saveQuietly();
|
||||
return;
|
||||
|
||||
case 'checkout':
|
||||
if($this->option("debug")) {
|
||||
$this->info("Doing a checkout for " . $asset->id . " picking target type: " . $action_log->target_type);
|
||||
}
|
||||
if($asset->assigned_to != $action_log->target_id) {
|
||||
$this->error("Asset's assigned_to does *NOT* match Action Log's target_id. \$asset->assigned_to=".$asset->assigned_to." vs. \$action_log->target_id=".$action_log->target_id);
|
||||
//FIXME - do we abort here? Do we try to keep looking? I don't know, this means your data is *really* messed up...
|
||||
}
|
||||
$asset->assigned_type = $action_log->target_type;
|
||||
$asset->saveQuietly(); // see above
|
||||
return;
|
||||
}
|
||||
}
|
||||
$asset->assigned_to = null; //asset was never checked in or out in its lifetime - it stays 'checked in'
|
||||
$asset->saveQuietly(); //see above
|
||||
});
|
||||
$this->newLine();
|
||||
$this->info("Assets assigned_type are fixed");
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ use Illuminate\Console\Command;
|
||||
use App\Models\User;
|
||||
use Laravel\Passport\TokenRepository;
|
||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GeneratePersonalAccessToken extends Command
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Models\Setting;
|
||||
use App\Models\Ldap;
|
||||
use App\Models\User;
|
||||
use App\Models\Location;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class LdapSync extends Command
|
||||
{
|
||||
@@ -251,6 +251,7 @@ class LdapSync extends Command
|
||||
// Creating a new user.
|
||||
$user = new User;
|
||||
$user->password = $user->noPassword();
|
||||
$user->locale = app()->getLocale();
|
||||
$user->activated = 1; // newly created users can log in by default, unless AD's UAC is in use, or an active flag is set (below)
|
||||
$item['createorupdate'] = 'created';
|
||||
}
|
||||
@@ -298,7 +299,7 @@ class LdapSync extends Command
|
||||
try {
|
||||
$ldap_manager = Ldap::findLdapUsers($item['manager'], -1, $this->option('filter'));
|
||||
} catch (\Exception $e) {
|
||||
\Log::warning("Manager lookup caused an exception: " . $e->getMessage() . ". Falling back to direct username lookup");
|
||||
Log::warning("Manager lookup caused an exception: " . $e->getMessage() . ". Falling back to direct username lookup");
|
||||
// Hail-mary for Okta manager 'shortnames' - will only work if
|
||||
// Okta configuration is using full email-address-style usernames
|
||||
$ldap_manager = [
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Console\Commands;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Setting;
|
||||
use Exception;
|
||||
use Crypt;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
|
||||
/**
|
||||
* Check if a given ip is in a network
|
||||
@@ -160,7 +160,7 @@ class LdapTroubleshooter extends Command
|
||||
$output[] = "-x";
|
||||
$output[] = "-b ".escapeshellarg($settings->ldap_basedn);
|
||||
$output[] = "-D ".escapeshellarg($settings->ldap_uname);
|
||||
$output[] = "-w ".escapeshellarg(\Crypt::Decrypt($settings->ldap_pword));
|
||||
$output[] = "-w ".escapeshellarg(Crypt::Decrypt($settings->ldap_pword));
|
||||
$output[] = escapeshellarg(parenthesized_filter($settings->ldap_filter));
|
||||
if($settings->ldap_tls) {
|
||||
$this->line("# adding STARTTLS option");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Events\UserMerged;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -51,7 +52,7 @@ class MergeUsersByUsername extends Command
|
||||
|
||||
$bad_users = User::where('username', '=', trim($parts[0]))
|
||||
->whereNull('deleted_at')
|
||||
->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations')
|
||||
->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations','uploads', 'acceptances')
|
||||
->get();
|
||||
|
||||
|
||||
@@ -105,10 +106,26 @@ class MergeUsersByUsername extends Command
|
||||
$managedLocation->save();
|
||||
}
|
||||
|
||||
foreach ($bad_user->uploads as $upload) {
|
||||
$this->info('Updating upload log record '.$upload->id.' to user '.$user->id);
|
||||
$upload->item_id = $user->id;
|
||||
$upload->save();
|
||||
}
|
||||
|
||||
foreach ($bad_user->acceptances as $acceptance) {
|
||||
$this->info('Updating acceptance log record '.$acceptance->id.' to user '.$user->id);
|
||||
$acceptance->item_id = $user->id;
|
||||
$acceptance->save();
|
||||
}
|
||||
|
||||
// Mark the user as deleted
|
||||
$this->info('Marking the user as deleted');
|
||||
$bad_user->deleted_at = Carbon::now()->timestamp;
|
||||
$bad_user->save();
|
||||
|
||||
event(new UserMerged($bad_user, $user, null));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class MoveUploadsToNewDisk extends Command
|
||||
{
|
||||
@@ -74,7 +75,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$new_url = Storage::disk('public')->url('uploads/'.$public_type.'/'.$filename, $filename);
|
||||
$this->info($type_count.'. PUBLIC: '.$filename.' was copied to '.$new_url);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
}
|
||||
@@ -116,7 +117,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$new_url = Storage::url($private_type . '/' . $filename, $filename);
|
||||
$this->info($type_count . '. PRIVATE: ' . $filename . ' was copied to ' . $new_url);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
}
|
||||
@@ -140,7 +141,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
unlink($filename);
|
||||
$public_delete_count++;
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
}
|
||||
@@ -153,7 +154,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
unlink($filename);
|
||||
$private_delete_count++;
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
$this->error($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Console\Commands;
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
|
||||
@@ -59,7 +60,7 @@ class ObjectImportCommand extends Command
|
||||
|
||||
// This $logFile/useFiles() bit is currently broken, so commenting it out for now
|
||||
// $logFile = $this->option('logfile');
|
||||
// \Log::useFiles($logFile);
|
||||
// Log::useFiles($logFile);
|
||||
$this->comment('======= Importing Items from '.$filename.' =========');
|
||||
$importer->import();
|
||||
|
||||
@@ -112,10 +113,10 @@ class ObjectImportCommand extends Command
|
||||
public function log($string, $level = 'info')
|
||||
{
|
||||
if ($level === 'warning') {
|
||||
\Log::warning($string);
|
||||
Log::warning($string);
|
||||
$this->comment($string);
|
||||
} else {
|
||||
\Log::Info($string);
|
||||
Log::Info($string);
|
||||
if ($this->option('verbose')) {
|
||||
$this->comment($string);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Console\Commands;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CustomField;
|
||||
use Schema;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class PaveIt extends Command
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
@@ -15,6 +16,8 @@ use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class Purge extends Command
|
||||
{
|
||||
@@ -141,6 +144,20 @@ class Purge extends Command
|
||||
$this->info($users->count().' users purged.');
|
||||
$user_assoc = 0;
|
||||
foreach ($users as $user) {
|
||||
|
||||
$rel_path = 'private_uploads/users';
|
||||
$filenames = Actionlog::where('action_type', 'uploaded')
|
||||
->where('item_id', $user->id)
|
||||
->pluck('filename');
|
||||
foreach($filenames as $filename) {
|
||||
try {
|
||||
if (Storage::exists($rel_path . '/' . $filename)) {
|
||||
Storage::delete($rel_path . '/' . $filename);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::info('An error occurred while deleting files: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
$this->info('- User "'.$user->username.'" deleted.');
|
||||
$user_assoc += $user->userlog()->count();
|
||||
$user->userlog()->forceDelete();
|
||||
|
||||
@@ -103,7 +103,7 @@ class RecryptFromMcrypt extends Command
|
||||
$this->comment('INFO: No LDAP password found. Skipping... ');
|
||||
} else {
|
||||
$decrypted_ldap_pword = $mcrypter->decrypt($settings->ldap_pword);
|
||||
$settings->ldap_pword = \Crypt::encrypt($decrypted_ldap_pword);
|
||||
$settings->ldap_pword = Crypt::encrypt($decrypted_ldap_pword);
|
||||
$settings->save();
|
||||
}
|
||||
/** @var CustomField[] $custom_fields */
|
||||
@@ -132,7 +132,7 @@ class RecryptFromMcrypt extends Command
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($asset->{$columnName});
|
||||
$asset->{$columnName} = \Crypt::encrypt($decrypted_field);
|
||||
$asset->{$columnName} = Crypt::encrypt($decrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use Artisan;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RegenerateAssetTags extends Command
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RemoveExplicitEols extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:remove-explicit-eols {--model_name= : The name of the asset model to update (use "all" to update all models)}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Removes explicit EOLs on assets with selected model so they may inherit the asset model EOL';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
|
||||
if ($this->option('model_name') == 'all') {
|
||||
$assets = Asset::all();
|
||||
$this->updateAssets($assets);
|
||||
} else {
|
||||
$assetModel = AssetModel::where('name', '=', $this->option('model_name'))->first();
|
||||
|
||||
if ($assetModel) {
|
||||
$assets = Asset::where('model_id', '=', $assetModel->id)->get();
|
||||
$this->updateAssets($assets);
|
||||
} else {
|
||||
$this->error('Asset model not found');
|
||||
}
|
||||
}
|
||||
$endTime = microtime(true);
|
||||
$executionTime = ($endTime - $startTime);
|
||||
$this->info('Command executed in ' . round($executionTime, 2) . ' seconds.');
|
||||
}
|
||||
|
||||
private function updateAssets($assets)
|
||||
{
|
||||
foreach ($assets as $asset) {
|
||||
$asset->eol_explicit = 0;
|
||||
$asset->asset_eol_date = null;
|
||||
$asset->save();
|
||||
}
|
||||
|
||||
$this->info($assets->count() . ' Assets updated successfully');
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,7 @@ class ResetDemoSettings extends Command
|
||||
$settings->saml_forcelogin = '0';
|
||||
$settings->saml_slo = null;
|
||||
$settings->saml_custom_settings = null;
|
||||
$settings->default_avatar = 'default.png';
|
||||
|
||||
|
||||
$settings->save();
|
||||
|
||||
@@ -6,8 +6,8 @@ use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\User;
|
||||
use Artisan;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RestoreDeletedUsers extends Command
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use ZipArchive;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class SQLStreamer {
|
||||
private $input;
|
||||
@@ -29,8 +30,11 @@ class SQLStreamer {
|
||||
public function parse_sql(string $line): string {
|
||||
// take into account the 'start of line or not' setting as an instance variable?
|
||||
// 'continuation' lines for a permitted statement are PERMITTED.
|
||||
// remove *only* line-feeds & carriage-returns; helpful for regexes against lines from
|
||||
// Windows dumps
|
||||
$line = trim($line, "\r\n");
|
||||
if($this->statement_is_permitted && $line[0] === ' ') {
|
||||
return $line;
|
||||
return $line . "\n"; //re-add the newline
|
||||
}
|
||||
|
||||
$table_regex = '`?([a-zA-Z0-9_]+)`?';
|
||||
@@ -41,8 +45,12 @@ class SQLStreamer {
|
||||
"/^(INSERT INTO )$table_regex(.*)$/" => false,
|
||||
"/^UNLOCK TABLES/" => false,
|
||||
// "/^\\) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;/" => false, // FIXME not sure what to do here?
|
||||
"/^\\)[a-zA-Z0-9_= ]*;$/" => false
|
||||
// ^^^^^^ that bit should *exit* the 'perimitted' black
|
||||
"/^\\)[a-zA-Z0-9_= ]*;$/" => false,
|
||||
// ^^^^^^ that bit should *exit* the 'permitted' block
|
||||
"/^\\(.*\\)[,;]$/" => false, //older MySQL dump style with one set of values per line
|
||||
/* we *could* have made the ^INSERT INTO blah VALUES$ turn on the capturing state, and closed it with
|
||||
a ^(blahblah);$ but it's cleaner to not have to manage the state machine. We're just going to
|
||||
assume that (blahblah), or (blahblah); are values for INSERT and are always acceptable. */
|
||||
];
|
||||
|
||||
foreach($allowed_statements as $statement => $statechange) {
|
||||
@@ -66,7 +74,7 @@ class SQLStreamer {
|
||||
}
|
||||
//how do we *replace* the tablename?
|
||||
// print "RETURNING LINE: $line";
|
||||
return $line;
|
||||
return $line . "\n"; //re-add newline
|
||||
}
|
||||
}
|
||||
// all that is not allowed is denied.
|
||||
@@ -84,7 +92,7 @@ class SQLStreamer {
|
||||
$parser->line_aware_piping(); // <----- THIS is doing the heavy lifting!
|
||||
|
||||
$check_tables = ['settings' => null, 'migrations' => null /* 'assets' => null */]; //TODO - move to statics?
|
||||
//can't use 'users' because the 'accessories_users' table?
|
||||
//can't use 'users' because the 'accessories_checkout' table?
|
||||
// can't use 'assets' because 'ver1_components_assets'
|
||||
foreach($check_tables as $check_table => $_ignore) {
|
||||
foreach ($parser->tablenames as $tablename => $_count) {
|
||||
@@ -125,7 +133,7 @@ class SQLStreamer {
|
||||
while (($buffer = fgets($this->input, SQLStreamer::$buffer_size)) !== false) {
|
||||
$bytes_read += strlen($buffer);
|
||||
if ($this->reading_beginning_of_line) {
|
||||
// \Log::debug("Buffer is: '$buffer'");
|
||||
// Log::debug("Buffer is: '$buffer'");
|
||||
$cleaned_buffer = $this->parse_sql($buffer);
|
||||
if ($this->output) {
|
||||
$bytes_written = fwrite($this->output, $cleaned_buffer);
|
||||
@@ -163,7 +171,8 @@ class RestoreFromBackup extends Command
|
||||
{filename : The zip file to be migrated}
|
||||
{--no-progress : Don\'t show a progress bar}
|
||||
{--sanitize-guess-prefix : Guess and output the table-prefix needed to "sanitize" the SQL}
|
||||
{--sanitize-with-prefix= : "Sanitize" the SQL, using the passed-in table prefix (can be learned from --sanitize-guess-prefix). Pass as just \'--sanitize-with-prefix=\' to use no prefix}';
|
||||
{--sanitize-with-prefix= : "Sanitize" the SQL, using the passed-in table prefix (can be learned from --sanitize-guess-prefix). Pass as just \'--sanitize-with-prefix=\' to use no prefix}
|
||||
{--sql-stdout-only : ONLY "Sanitize" the SQL and print it to stdout - useful for debugging - probably requires --sanitize-with-prefix= }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@@ -191,7 +200,7 @@ class RestoreFromBackup extends Command
|
||||
{
|
||||
$dir = getcwd();
|
||||
if( $dir != base_path() ) { // usually only the case when running via webserver, not via command-line
|
||||
\Log::debug("Current working directory is: $dir, changing directory to: ".base_path());
|
||||
Log::debug("Current working directory is: $dir, changing directory to: ".base_path());
|
||||
chdir(base_path()); // TODO - is this *safe* to change on a running script?!
|
||||
}
|
||||
//
|
||||
@@ -297,7 +306,7 @@ class RestoreFromBackup extends Command
|
||||
continue;
|
||||
}
|
||||
if (@pathinfo($raw_path, PATHINFO_EXTENSION) == 'sql') {
|
||||
\Log::debug("Found a sql file!");
|
||||
Log::debug("Found a sql file!");
|
||||
$sqlfiles[] = $raw_path;
|
||||
$sqlfile_indices[] = $i;
|
||||
continue;
|
||||
@@ -364,6 +373,15 @@ class RestoreFromBackup extends Command
|
||||
return $this->info("Re-run this command with '--sanitize-with-prefix=".$prefix."' to see an attempt to sanitze your SQL.");
|
||||
}
|
||||
|
||||
// If we're doing --sql-stdout-only, handle that now so we don't have to open pipes to mysql and all of that silliness
|
||||
if ($this->option('sql-stdout-only')) {
|
||||
$sql_importer = new SQLStreamer($sql_contents, STDOUT, $this->option('sanitize-with-prefix'));
|
||||
$bytes_read = $sql_importer->line_aware_piping();
|
||||
return $this->warn("$bytes_read total bytes read");
|
||||
//TODO - it'd be nice to dump this message to STDERR so that STDOUT is just pure SQL,
|
||||
// which would be good for redirecting to a file, and not having to trim the last line off of it
|
||||
}
|
||||
|
||||
//how to invoke the restore?
|
||||
$pipes = [];
|
||||
|
||||
@@ -413,7 +431,7 @@ class RestoreFromBackup extends Command
|
||||
$bytes_read = 0;
|
||||
while (($buffer = fgets($sql_contents, SQLStreamer::$buffer_size)) !== false) {
|
||||
$bytes_read += strlen($buffer);
|
||||
// \Log::debug("Buffer is: '$buffer'");
|
||||
// Log::debug("Buffer is: '$buffer'");
|
||||
$bytes_written = fwrite($pipes[0], $buffer);
|
||||
|
||||
if ($bytes_written === false) {
|
||||
@@ -425,13 +443,13 @@ class RestoreFromBackup extends Command
|
||||
$bytes_read = $sql_importer->line_aware_piping();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("Error during restore!!!! ".$e->getMessage());
|
||||
Log::error("Error during restore!!!! ".$e->getMessage());
|
||||
// FIXME - put these back and/or put them in the right places?!
|
||||
$err_out = fgets($pipes[1]);
|
||||
$err_err = fgets($pipes[2]);
|
||||
\Log::error("Error OUTPUT: ".$err_out);
|
||||
Log::error("Error OUTPUT: ".$err_out);
|
||||
$this->info($err_out);
|
||||
\Log::error("Error ERROR : ".$err_err);
|
||||
Log::error("Error ERROR : ".$err_err);
|
||||
$this->error($err_err);
|
||||
throw $e;
|
||||
}
|
||||
@@ -465,6 +483,9 @@ class RestoreFromBackup extends Command
|
||||
$ugly_file_name = $za->statIndex($file_details['index'])['name'];
|
||||
$fp = $za->getStream($ugly_file_name);
|
||||
//$this->info("Weird problem, here are file details? ".print_r($file_details,true));
|
||||
if (!is_dir($file_details['dest'])) {
|
||||
mkdir($file_details['dest'], 0755, true); //0755 is what Laravel uses, so we do that
|
||||
}
|
||||
$migrated_file = fopen($file_details['dest'].'/'.basename($pretty_file_name), 'w');
|
||||
while (($buffer = fgets($fp, SQLStreamer::$buffer_size)) !== false) {
|
||||
fwrite($migrated_file, $buffer);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Console\Commands;
|
||||
use App\Models\Asset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Setting;
|
||||
use Artisan;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Encryption\Encrypter;
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CheckoutAssetNotification;
|
||||
use App\Notifications\CurrentInventory;
|
||||
use App\Notifications\UnacceptedAssetReminderNotification;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class SendAcceptanceReminder extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:acceptance-reminder';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will resend users with unaccepted assets a reminder to accept or decline them.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$pending = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')
|
||||
->whereHas('checkoutable', function($query) {
|
||||
$query->where('accepted_at', null)
|
||||
->where('declined_at', null);
|
||||
})
|
||||
->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model', 'checkoutable.admin'])
|
||||
->get();
|
||||
|
||||
$count = 0;
|
||||
$unacceptedAssetGroups = $pending
|
||||
->filter(function($acceptance) {
|
||||
return $acceptance->checkoutable_type == 'App\Models\Asset';
|
||||
})
|
||||
->map(function($acceptance) {
|
||||
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
|
||||
})
|
||||
->groupBy(function($item) {
|
||||
return $item['acceptance']->assignedTo ? $item['acceptance']->assignedTo->id : '';
|
||||
});
|
||||
|
||||
$no_mail_address = [];
|
||||
|
||||
foreach($unacceptedAssetGroups as $unacceptedAssetGroup) {
|
||||
$item_count = $unacceptedAssetGroup->count();
|
||||
foreach ($unacceptedAssetGroup as $unacceptedAsset) {
|
||||
// if ($unacceptedAsset['acceptance']->assignedTo->email == ''){
|
||||
// $no_mail_address[] = $unacceptedAsset['checkoutable']->assignedTo->present()->fullName;
|
||||
// }
|
||||
if ($unacceptedAsset['acceptance']->assignedTo) {
|
||||
|
||||
if (!$unacceptedAsset['acceptance']->assignedTo->locale) {
|
||||
Notification::locale(Setting::getSettings()->locale)->send(
|
||||
$unacceptedAsset['acceptance']->assignedTo,
|
||||
new UnacceptedAssetReminderNotification($unacceptedAsset['assetItem'], $count)
|
||||
);
|
||||
} else {
|
||||
Notification::send(
|
||||
$unacceptedAsset['acceptance']->assignedTo,
|
||||
new UnacceptedAssetReminderNotification($unacceptedAsset, $item_count)
|
||||
);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($no_mail_address)) {
|
||||
foreach($no_mail_address as $user) {
|
||||
return $user.' has no email.';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->info($count.' users notified.');
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ class SendCurrentInventoryToUsers extends Command
|
||||
|
||||
$count = 0;
|
||||
foreach ($users as $user) {
|
||||
if (($user->assets->count() > 0) || ($user->accessories->count() > 0) || ($user->licenses->count() > 0)) {
|
||||
if (($user->assets->count() > 0) || ($user->accessories->count() > 0) || ($user->licenses->count() > 0) || ($user->consumables->count() > 0)) {
|
||||
$count++;
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Models\Recipients\AlertRecipient;
|
||||
use App\Models\Setting;
|
||||
use App\Notifications\SendUpcomingAuditNotification;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendUpcomingAuditReport extends Command
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class SyncAssetCounters extends Command
|
||||
{
|
||||
@@ -58,7 +59,7 @@ class SyncAssetCounters extends Command
|
||||
$asset->save();
|
||||
$bar->advance();
|
||||
|
||||
\Log::debug('Asset: '.$asset->id.' has '.$asset->checkin_counter.' checkins, '.$asset->checkout_counter.' checkouts, and '.$asset->requests_counter.' requests');
|
||||
Log::debug('Asset: '.$asset->id.' has '.$asset->checkin_counter.' checkins, '.$asset->checkout_counter.' checkouts, and '.$asset->requests_counter.' requests');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class UserMerged
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $from_user, User $to_user, User $admin)
|
||||
public function __construct(User $from_user, User $to_user, ?User $admin)
|
||||
{
|
||||
$this->merged_from = $from_user;
|
||||
$this->merged_to = $to_user;
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Helpers\Helper;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use ArieTimmerman\Laravel\SCIMServer\Exceptions\SCIMException;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Throwable;
|
||||
use JsonException;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
@@ -44,8 +44,8 @@ class Handler extends ExceptionHandler
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
if ($this->shouldReport($exception)) {
|
||||
if (class_exists(\Log::class)) {
|
||||
\Log::error($exception);
|
||||
if (class_exists(Log::class)) {
|
||||
Log::error($exception);
|
||||
}
|
||||
return parent::report($exception);
|
||||
}
|
||||
|
||||
+96
-16
@@ -12,10 +12,12 @@ use App\Models\Depreciation;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\License;
|
||||
use Crypt;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Image;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Helper
|
||||
{
|
||||
@@ -60,8 +62,9 @@ class Helper
|
||||
'mn' => 'mn-MN', // Mongolian
|
||||
'ms' => 'ms-MY', // Malay
|
||||
'nl' => 'nl-NL', // Dutch
|
||||
'no' => 'no-NO', // Norwegian
|
||||
'no' => 'nb-NO', // Norwegian Bokmål
|
||||
'pl' => 'pl-PL', // Polish
|
||||
'pt' => 'pt-PT', // Portuguese
|
||||
'ro' => 'ro-RO', // Romanian
|
||||
'ru' => 'ru-RU', // Russian
|
||||
'sk' => 'sk-SK', // Slovak
|
||||
@@ -412,7 +415,7 @@ class Helper
|
||||
|
||||
if ($index >= $total_colors) {
|
||||
|
||||
\Log::info('Status label count is '.$index.' and exceeds the allowed count of 266.');
|
||||
Log::info('Status label count is '.$index.' and exceeds the allowed count of 266.');
|
||||
//patch fix for array key overflow (color count starts at 1, array starts at 0)
|
||||
$index = $index - $total_colors - 1;
|
||||
|
||||
@@ -718,7 +721,7 @@ class Helper
|
||||
{
|
||||
$alert_threshold = \App\Models\Setting::getSettings()->alert_threshold;
|
||||
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('users as users_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('checkouts as checkouts_count')->whereNotNull('min_amt')->get();
|
||||
$components = Component::whereNotNull('min_amt')->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->get();
|
||||
$licenses = License::where('min_amt', '>', 0)->get();
|
||||
@@ -746,7 +749,7 @@ class Helper
|
||||
}
|
||||
|
||||
foreach ($accessories as $accessory) {
|
||||
$avail = $accessory->qty - $accessory->users_count;
|
||||
$avail = $accessory->qty - $accessory->checkouts_count;
|
||||
if ($avail < ($accessory->min_amt) + $alert_threshold) {
|
||||
if ($accessory->qty > 0) {
|
||||
$percent = number_format((($avail / $accessory->qty) * 100), 0);
|
||||
@@ -875,12 +878,15 @@ class Helper
|
||||
$permission_name = $permission[$x]['permission'];
|
||||
|
||||
if ($permission[$x]['display'] === true) {
|
||||
if ($selected_arr) {
|
||||
|
||||
if (is_array($selected_arr)) {
|
||||
|
||||
if (array_key_exists($permission_name, $selected_arr)) {
|
||||
$permissions_arr[$permission_name] = $selected_arr[$permission_name];
|
||||
} else {
|
||||
$permissions_arr[$permission_name] = '0';
|
||||
}
|
||||
|
||||
} else {
|
||||
$permissions_arr[$permission_name] = '0';
|
||||
}
|
||||
@@ -908,13 +914,22 @@ class Helper
|
||||
$rules = $class::rules();
|
||||
foreach ($rules as $rule_name => $rule) {
|
||||
if ($rule_name == $field) {
|
||||
if (strpos($rule, 'required') === false) {
|
||||
return false;
|
||||
if (is_array($rule)) {
|
||||
if (in_array('required', $rule)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
if (strpos($rule, 'required') === false) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1012,7 +1027,7 @@ class Helper
|
||||
|
||||
|
||||
try {
|
||||
$tmp_date = new \Carbon($date);
|
||||
$tmp_date = new Carbon($date);
|
||||
|
||||
if ($type == 'datetime') {
|
||||
$dt['datetime'] = $tmp_date->format('Y-m-d H:i:s');
|
||||
@@ -1029,7 +1044,7 @@ class Helper
|
||||
return $dt['formatted'];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::warning($e);
|
||||
Log::warning($e);
|
||||
return $date.' (Invalid '.$type.' value.)';
|
||||
}
|
||||
|
||||
@@ -1342,7 +1357,7 @@ class Helper
|
||||
public static function isDemoMode() {
|
||||
if (config('app.lock_passwords') === true) {
|
||||
return true;
|
||||
\Log::debug('app locked!');
|
||||
Log::debug('app locked!');
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1435,7 +1450,6 @@ class Helper
|
||||
|
||||
foreach (self::$language_map as $legacy => $new) {
|
||||
if ($language_code == $legacy) {
|
||||
\Log::debug('Current language is '.$legacy.', using '.$new.' instead');
|
||||
return $new;
|
||||
}
|
||||
}
|
||||
@@ -1446,6 +1460,7 @@ class Helper
|
||||
|
||||
public static function mapBackToLegacyLocale($new_locale = null)
|
||||
{
|
||||
|
||||
if (strlen($new_locale) <= 4) {
|
||||
return $new_locale; //"new locale" apparently wasn't quite so new
|
||||
}
|
||||
@@ -1453,10 +1468,75 @@ class Helper
|
||||
// This does a *reverse* search against our new language map array - given the value, find the *key* for it
|
||||
$legacy_locale = array_search($new_locale, self::$language_map);
|
||||
|
||||
if($legacy_locale !== false) {
|
||||
if ($legacy_locale !== false) {
|
||||
return $legacy_locale;
|
||||
}
|
||||
return $new_locale; // better that you have some weird locale that doesn't fit into our mappings anywhere than 'void'
|
||||
}
|
||||
|
||||
public static function determineLanguageDirection() {
|
||||
return in_array(app()->getLocale(),
|
||||
[
|
||||
'ar-SA',
|
||||
'fa-IR',
|
||||
'he-IL'
|
||||
]) ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
|
||||
static public function getRedirectOption($request, $id, $table, $item_id = null)
|
||||
{
|
||||
|
||||
$redirect_option = Session::get('redirect_option');
|
||||
$checkout_to_type = Session::get('checkout_to_type');
|
||||
|
||||
// return to index
|
||||
if ($redirect_option == 'index') {
|
||||
switch ($table) {
|
||||
case "Assets":
|
||||
return route('hardware.index');
|
||||
case "Users":
|
||||
return route('users.index');
|
||||
case "Licenses":
|
||||
return route('licenses.index');
|
||||
case "Accessories":
|
||||
return route('accessories.index');
|
||||
case "Components":
|
||||
return route('components.index');
|
||||
case "Consumables":
|
||||
return route('consumables.index');
|
||||
}
|
||||
}
|
||||
|
||||
// return to thing being assigned
|
||||
if ($redirect_option == 'item') {
|
||||
switch ($table) {
|
||||
case "Assets":
|
||||
return route('hardware.show', $id ?? $item_id);
|
||||
case "Users":
|
||||
return route('users.show', $id ?? $item_id);
|
||||
case "Licenses":
|
||||
return route('licenses.show', $id ?? $item_id);
|
||||
case "Accessories":
|
||||
return route('accessories.show', $id ?? $item_id);
|
||||
case "Components":
|
||||
return route('components.show', $id ?? $item_id);
|
||||
case "Consumables":
|
||||
return route('consumables.show', $id ?? $item_id);
|
||||
}
|
||||
}
|
||||
|
||||
// return to assignment target
|
||||
if ($redirect_option == 'target') {
|
||||
switch ($checkout_to_type) {
|
||||
case 'user':
|
||||
return route('users.show', ['user' => $request->assigned_user]);
|
||||
case 'location':
|
||||
return route('locations.show', ['location' => $request->assigned_location]);
|
||||
case 'asset':
|
||||
return route('hardware.show', ['hardware' => $request->assigned_asset]);
|
||||
}
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
class IconHelper
|
||||
{
|
||||
|
||||
public static function icon($type) {
|
||||
switch ($type) {
|
||||
case 'checkout':
|
||||
return 'fa-solid fa-rotate-left';
|
||||
case 'checkin':
|
||||
return 'fa-solid fa-rotate-right';
|
||||
case 'edit':
|
||||
return 'fas fa-pencil-alt';
|
||||
case 'clone':
|
||||
return 'far fa-clone';
|
||||
case 'delete':
|
||||
return 'fas fa-trash';
|
||||
case 'create':
|
||||
return 'fa-solid fa-plus';
|
||||
case 'audit':
|
||||
return 'fa-solid fa-clipboard-check';
|
||||
case '2fa reset':
|
||||
return 'fa-solid fa-mobile-screen';
|
||||
case 'new-user':
|
||||
return 'fa-solid fa-user-plus';
|
||||
case 'merged-user':
|
||||
return 'fa-solid fa-people-arrows';
|
||||
case 'delete-user':
|
||||
return 'fa-solid fa-user-minus';
|
||||
case 'update-user':
|
||||
return 'fa-solid fa-user-pen';
|
||||
case 'user':
|
||||
return 'fa-solid fa-user';
|
||||
case 'users':
|
||||
return 'fas fa-users';
|
||||
case 'restore':
|
||||
return 'fa-solid fa-trash-arrow-up';
|
||||
case 'external-link':
|
||||
return 'fa fa-external-link';
|
||||
case 'email':
|
||||
return 'fa-regular fa-envelope';
|
||||
case 'phone':
|
||||
return 'fa-solid fa-phone';
|
||||
case 'long-arrow-right':
|
||||
return 'fas fa-long-arrow-alt-right';
|
||||
case 'download':
|
||||
return 'fas fa-download';
|
||||
case 'checkmark':
|
||||
return 'fas fa-check icon-white';
|
||||
case 'x':
|
||||
return 'fas fa-times';
|
||||
case 'logout':
|
||||
return 'fa fa-sign-out';
|
||||
case 'admin-settings':
|
||||
return 'fas fa-cogs';
|
||||
case 'settings':
|
||||
return 'fas fa-cog';
|
||||
case 'angle-left':
|
||||
return 'fas fa-angle-left';
|
||||
case 'warning':
|
||||
return 'fas fa-exclamation-triangle';
|
||||
case 'kits':
|
||||
return 'fas fa-object-group';
|
||||
case 'assets':
|
||||
return 'fas fa-barcode';
|
||||
case 'accessories':
|
||||
return 'far fa-keyboard';
|
||||
case 'components':
|
||||
return 'far fa-hdd';
|
||||
case 'consumables':
|
||||
return 'fas fa-tint';
|
||||
case 'licenses':
|
||||
return 'far fa-save';
|
||||
case 'requestable':
|
||||
return 'fas fa-laptop';
|
||||
case 'reports':
|
||||
return 'fas fa-chart-bar';
|
||||
case 'heart':
|
||||
return 'fas fa-heart';
|
||||
case 'circle':
|
||||
return 'fa-regular fa-circle';
|
||||
case 'circle-solid':
|
||||
return 'fa-solid fa-circle';
|
||||
case 'due':
|
||||
return 'fas fa-history';
|
||||
case 'import':
|
||||
return 'fas fa-cloud-upload-alt';
|
||||
case 'search':
|
||||
return 'fas fa-search';
|
||||
case 'alerts':
|
||||
return 'far fa-flag';
|
||||
case 'password':
|
||||
return 'fa-solid fa-key';
|
||||
case 'api-key':
|
||||
return 'fa-solid fa-user-secret';
|
||||
case 'nav-toggle':
|
||||
return 'fas fa-bars';
|
||||
case 'dashboard':
|
||||
return 'fas fa-tachometer-alt';
|
||||
case 'info-circle':
|
||||
return 'fas fa-info-circle';
|
||||
case 'caret-right':
|
||||
return 'fa fa-caret-right';
|
||||
case 'caret-up':
|
||||
return 'fa fa-caret-up';
|
||||
case 'caret-down':
|
||||
return 'fa fa-caret-down';
|
||||
case 'arrow-circle-right':
|
||||
return 'fa fa-arrow-circle-right';
|
||||
case 'minus':
|
||||
return 'fas fa-minus';
|
||||
case 'spinner':
|
||||
return 'fas fa-spinner fa-spin';
|
||||
case 'copy-clipboard':
|
||||
return 'fa-regular fa-clipboard';
|
||||
case 'paperclip':
|
||||
return 'fas fa-paperclip';
|
||||
case 'files':
|
||||
return 'fa-regular fa-file';
|
||||
case 'more-info':
|
||||
return 'far fa-life-ring';
|
||||
case 'calendar':
|
||||
return 'fas fa-calendar';
|
||||
case 'plus':
|
||||
return 'fas fa-plus';
|
||||
case 'history':
|
||||
return 'fas fa-history';
|
||||
case 'more-files':
|
||||
return 'fa-solid fa-laptop-file';
|
||||
case 'maintenances':
|
||||
return 'fas fa-wrench';
|
||||
case 'seats':
|
||||
return 'far fa-list-alt';
|
||||
case 'globe-us':
|
||||
return 'fas fa-globe-americas';
|
||||
case 'locked':
|
||||
return 'fas fa-lock';
|
||||
case 'unlocked':
|
||||
return 'fas fa-lock';
|
||||
case 'locations':
|
||||
return 'fas fa-map-marker-alt';
|
||||
case 'superadmin':
|
||||
return 'fas fa-crown';
|
||||
case 'print':
|
||||
return 'fa-solid fa-print';
|
||||
case 'checkin-and-delete':
|
||||
return 'fa-solid fa-user-xmark';
|
||||
case 'branding':
|
||||
return 'fas fa-copyright';
|
||||
case 'general-settings':
|
||||
return 'fa-solid fa-list-check';
|
||||
case 'groups':
|
||||
return 'fa-solid fa-user-group';
|
||||
case 'bell':
|
||||
return 'fa-solid fa-bell';
|
||||
case 'hashtag':
|
||||
return 'fa-solid fa-hashtag';
|
||||
case 'asset-tags':
|
||||
return 'fas fa-list-ol';
|
||||
case 'labels':
|
||||
return 'fas fa-tags';
|
||||
case 'ldap':
|
||||
return 'fas fa-sitemap';
|
||||
case 'google':
|
||||
return 'fa-brands fa-google';
|
||||
case 'saml':
|
||||
return 'fas fa-sign-in-alt';
|
||||
case 'backups':
|
||||
return 'fas fa-file-archive';
|
||||
case 'logins':
|
||||
return 'fas fa-crosshairs';
|
||||
case 'oauth':
|
||||
return 'fas fa-user-secret';
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,13 @@
|
||||
namespace App\Helpers;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
class StorageHelper
|
||||
{
|
||||
public static function downloader($filename, $disk = 'default')
|
||||
public static function downloader($filename, $disk = 'default') : BinaryFileResponse | RedirectResponse | StreamedResponse
|
||||
{
|
||||
if ($disk == 'default') {
|
||||
$disk = config('filesystems.default');
|
||||
|
||||
@@ -7,10 +7,11 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Redirect;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/** This controller handles all actions related to Accessories for
|
||||
* the Snipe-IT Asset Management application.
|
||||
@@ -26,13 +27,10 @@ class AccessoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AccessoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
public function index() : View
|
||||
{
|
||||
$this->authorize('index', Accessory::class);
|
||||
|
||||
return view('accessories/index');
|
||||
}
|
||||
|
||||
@@ -40,10 +38,8 @@ class AccessoriesController extends Controller
|
||||
* Returns a view with a form to create a new Accessory.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
public function create() : View
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
$category_type = 'accessory';
|
||||
@@ -57,10 +53,8 @@ class AccessoriesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize(Accessory::class);
|
||||
|
||||
@@ -79,16 +73,17 @@ class AccessoriesController extends Controller
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = request('purchase_cost');
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->user_id = auth()->id();
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
$accessory->notes = request('notes');
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
@@ -99,15 +94,12 @@ class AccessoriesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($accessoryId = null)
|
||||
public function edit($accessoryId = null) : View | RedirectResponse
|
||||
{
|
||||
|
||||
if ($item = Accessory::find($accessoryId)) {
|
||||
$this->authorize($item);
|
||||
|
||||
return view('accessories/edit', compact('item'))->with('category_type', 'accessory');
|
||||
}
|
||||
|
||||
@@ -121,9 +113,8 @@ class AccessoriesController extends Controller
|
||||
* @author [J. Vinsmoke]
|
||||
* @param int $accessoryId
|
||||
* @since [v6.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getClone($accessoryId = null)
|
||||
public function getClone($accessoryId = null) : View | RedirectResponse
|
||||
{
|
||||
|
||||
$this->authorize('create', Accessory::class);
|
||||
@@ -150,17 +141,15 @@ class AccessoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null)
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null) : RedirectResponse
|
||||
{
|
||||
if ($accessory = Accessory::withCount('users as users_count')->find($accessoryId)) {
|
||||
if ($accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessoryId)) {
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
"qty" => "required|numeric|min:$accessory->users_count"
|
||||
"qty" => "required|numeric|min:$accessory->checkouts_count"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
@@ -188,9 +177,10 @@ class AccessoriesController extends Controller
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
// Was the accessory updated?
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($accessory->save()) {
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
} else {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
@@ -204,10 +194,8 @@ class AccessoriesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($accessoryId)
|
||||
public function destroy($accessoryId) : RedirectResponse
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
@@ -224,7 +212,7 @@ class AccessoriesController extends Controller
|
||||
try {
|
||||
Storage::disk('public')->delete('accessories'.'/'.$accessory->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,12 +230,10 @@ class AccessoriesController extends Controller
|
||||
* @param int $accessoryID
|
||||
* @see AccessoriesController::getDataView() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($accessoryID = null)
|
||||
public function show($accessoryID = null) : View | RedirectResponse
|
||||
{
|
||||
$accessory = Accessory::withCount('users as users_count')->find($accessoryID);
|
||||
$accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessoryID);
|
||||
$this->authorize('view', $accessory);
|
||||
if (isset($accessory->id)) {
|
||||
return view('accessories/view', compact('accessory'));
|
||||
|
||||
@@ -7,9 +7,13 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Accessory;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Accessory\HttpFoundation\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class AccessoriesFilesController extends Controller
|
||||
{
|
||||
@@ -18,20 +22,17 @@ class AccessoriesFilesController extends Controller
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $accessoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @todo Switch to using the AssetFileRequest form request validator.
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $accessoryId = null)
|
||||
public function store(UploadFileRequest $request, $accessoryId = null) : RedirectResponse
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('accessories.show', ['accessory'=>$accessoryId])->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
|
||||
$accessory = Accessory::find($accessoryId);
|
||||
|
||||
if (isset($accessory->id)) {
|
||||
@@ -68,10 +69,8 @@ class AccessoriesFilesController extends Controller
|
||||
* @since [v1.0]
|
||||
* @param int $accessoryId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($accessoryId = null, $fileId = null)
|
||||
public function destroy($accessoryId = null, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$accessory = Accessory::find($accessoryId);
|
||||
|
||||
@@ -85,7 +84,7 @@ class AccessoriesFilesController extends Controller
|
||||
try {
|
||||
Storage::delete('accessories/'.$log->filename);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +105,11 @@ class AccessoriesFilesController extends Controller
|
||||
* @since [v1.4]
|
||||
* @param int $accessoryId
|
||||
* @param int $fileId
|
||||
* @return \Symfony\Accessory\HttpFoundation\Response
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($accessoryId = null, $fileId = null, $download = true)
|
||||
public function show($accessoryId = null, $fileId = null, $download = true) : View | RedirectResponse | Response | BinaryFileResponse | StreamedResponse
|
||||
{
|
||||
|
||||
\Log::debug('Private filesystem is: '.config('filesystems.default'));
|
||||
Log::debug('Private filesystem is: '.config('filesystems.default'));
|
||||
$accessory = Accessory::find($accessoryId);
|
||||
|
||||
|
||||
@@ -129,8 +126,8 @@ class AccessoriesFilesController extends Controller
|
||||
$file = 'private_uploads/accessories/'.$log->filename;
|
||||
|
||||
if (Storage::missing($file)) {
|
||||
\Log::debug('FILE DOES NOT EXISTS for '.$file);
|
||||
\Log::debug('URL should be '.Storage::url($file));
|
||||
Log::debug('FILE DOES NOT EXISTS for '.$file);
|
||||
Log::debug('URL should be '.Storage::url($file));
|
||||
|
||||
return response('File '.$file.' ('.Storage::url($file).') not found on server', 404)
|
||||
->header('Content-Type', 'text/plain');
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
class AccessoryCheckinController extends Controller
|
||||
{
|
||||
@@ -19,15 +22,10 @@ class AccessoryCheckinController extends Controller
|
||||
* @param Request $request
|
||||
* @param int $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return View
|
||||
* @internal param int $accessoryId
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($accessoryUserId = null, $backto = null)
|
||||
public function create($accessoryUserId = null, $backto = null) : View | RedirectResponse
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
if (is_null($accessory_user = DB::table('accessories_checkout')->find($accessoryUserId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
@@ -42,21 +40,16 @@ class AccessoryCheckinController extends Controller
|
||||
*
|
||||
* @uses Accessory::checkin_email() to determine if an email can and should be sent
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param null $accessoryUserId
|
||||
* @param null $accessoryCheckoutId
|
||||
* @param string $backto
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function store(Request $request, $accessoryUserId = null, $backto = null)
|
||||
public function store(Request $request, $accessoryCheckoutId = null, $backto = null) : RedirectResponse
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryCheckoutId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$accessory = Accessory::find($accessory_checkout->accessory_id);
|
||||
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
@@ -67,12 +60,12 @@ class AccessoryCheckinController extends Controller
|
||||
}
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
$return_to = e($accessory_user->assigned_to);
|
||||
if ($accessory_checkout->delete()) {
|
||||
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at));
|
||||
|
||||
event(new CheckoutableCheckedIn($accessory, User::find($return_to), Auth::user(), $request->input('note'), $checkin_at));
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
return redirect()->route('accessories.show', $accessory->id)->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
|
||||
|
||||
@@ -3,29 +3,34 @@
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AccessoryCheckoutRequest;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
class AccessoryCheckoutController extends Controller
|
||||
{
|
||||
|
||||
use CheckInOutRequest;
|
||||
|
||||
/**
|
||||
* Return the form to checkout an Accessory to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create($id)
|
||||
public function create($id) : View | RedirectResponse
|
||||
{
|
||||
|
||||
if ($accessory = Accessory::withCount('users as users_count')->find($id)) {
|
||||
if ($accessory = Accessory::withCount('checkouts as checkouts_count')->find($id)) {
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
@@ -58,46 +63,38 @@ class AccessoryCheckoutController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @param Accessory $accessory
|
||||
*/
|
||||
public function store(Request $request, $accessoryId)
|
||||
public function store(AccessoryCheckoutRequest $request, Accessory $accessory) : RedirectResponse
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::withCount('users as users_count')->find($accessoryId))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.user_not_found'));
|
||||
}
|
||||
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
if (!$user = User::find($request->input('assigned_to'))) {
|
||||
return redirect()->route('accessories.checkout.show', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
|
||||
$target = $this->determineCheckoutTarget();
|
||||
|
||||
$accessory->checkout_qty = $request->input('checkout_qty', 1);
|
||||
|
||||
for ($i = 0; $i < $accessory->checkout_qty; $i++) {
|
||||
AccessoryCheckout::create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => $target::class,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
}
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
|
||||
// Make sure there is at least one available to checkout
|
||||
if ($accessory->numRemaining() <= 0){
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkout.unavailable'));
|
||||
}
|
||||
// Set this as user since we only allow checkout to user for this item type
|
||||
$request->request->add(['checkout_to_type' => request('checkout_to_type')]);
|
||||
$request->request->add(['assigned_user' => $target->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->assigned_to = e($request->input('assigned_to'));
|
||||
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->get('assigned_to'),
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
|
||||
|
||||
event(new CheckoutableCheckedOut($accessory, $user, Auth::user(), $request->input('note')));
|
||||
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.checkout.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))
|
||||
->with('success', trans('admin/accessories/message.checkout.success'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,25 +23,23 @@ use App\Notifications\AcceptanceAssetAcceptedNotification;
|
||||
use App\Notifications\AcceptanceAssetDeclinedNotification;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Http\Controllers\SettingsController;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Carbon\Carbon;
|
||||
use phpDocumentor\Reflection\Types\Compound;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AcceptanceController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show a listing of pending checkout acceptances for the current user
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
public function index() : View
|
||||
{
|
||||
$acceptances = CheckoutAcceptance::forUser(Auth::user())->pending()->get();
|
||||
|
||||
$acceptances = CheckoutAcceptance::forUser(auth()->user())->pending()->get();
|
||||
return view('account/accept.index', compact('acceptances'));
|
||||
}
|
||||
|
||||
@@ -49,9 +47,8 @@ class AcceptanceController extends Controller
|
||||
* Shows a form to either accept or decline the checkout acceptance
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function create($id)
|
||||
public function create($id) : View | RedirectResponse
|
||||
{
|
||||
$acceptance = CheckoutAcceptance::find($id);
|
||||
|
||||
@@ -64,7 +61,7 @@ class AcceptanceController extends Controller
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.asset_already_accepted'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isCheckedOutTo(Auth::user())) {
|
||||
if (! $acceptance->isCheckedOutTo(auth()->user())) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
|
||||
}
|
||||
|
||||
@@ -80,9 +77,8 @@ class AcceptanceController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request, $id)
|
||||
public function store(Request $request, $id) : RedirectResponse
|
||||
{
|
||||
$acceptance = CheckoutAcceptance::find($id);
|
||||
|
||||
@@ -94,7 +90,7 @@ class AcceptanceController extends Controller
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.asset_already_accepted'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isCheckedOutTo(Auth::user())) {
|
||||
if (! $acceptance->isCheckedOutTo(auth()->user())) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
|
||||
}
|
||||
|
||||
@@ -222,6 +218,7 @@ class AcceptanceController extends Controller
|
||||
'item_tag' => $item->asset_tag,
|
||||
'item_model' => $display_model,
|
||||
'item_serial' => $item->serial,
|
||||
'item_status' => $item->assetstatus?->name,
|
||||
'eula' => $item->getEula(),
|
||||
'note' => $request->input('note'),
|
||||
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d'),
|
||||
@@ -234,7 +231,7 @@ class AcceptanceController extends Controller
|
||||
];
|
||||
|
||||
if ($pdf_view_route!='') {
|
||||
\Log::debug($pdf_filename.' is the filename, and the route was specified.');
|
||||
Log::debug($pdf_filename.' is the filename, and the route was specified.');
|
||||
$pdf = Pdf::loadView($pdf_view_route, $data);
|
||||
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
|
||||
}
|
||||
@@ -312,6 +309,7 @@ class AcceptanceController extends Controller
|
||||
'item_tag' => $item->asset_tag,
|
||||
'item_model' => $display_model,
|
||||
'item_serial' => $item->serial,
|
||||
'item_status' => $item->assetstatus?->name,
|
||||
'note' => $request->input('note'),
|
||||
'declined_date' => Carbon::parse($acceptance->declined_at)->format('Y-m-d'),
|
||||
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
|
||||
@@ -321,7 +319,7 @@ class AcceptanceController extends Controller
|
||||
];
|
||||
|
||||
if ($pdf_view_route!='') {
|
||||
\Log::debug($pdf_filename.' is the filename, and the route was specified.');
|
||||
Log::debug($pdf_filename.' is the filename, and the route was specified.');
|
||||
$pdf = Pdf::loadView($pdf_view_route, $data);
|
||||
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
|
||||
}
|
||||
|
||||
@@ -3,34 +3,44 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Actionlog;
|
||||
use Response;
|
||||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Illuminate\Http\Response;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
class ActionlogController extends Controller
|
||||
{
|
||||
public function displaySig($filename)
|
||||
public function displaySig($filename) : RedirectResponse | Response | bool
|
||||
{
|
||||
// PHP doesn't let you handle file not found errors well with
|
||||
// file_get_contents, so we set the error reporting for just this class
|
||||
error_reporting(0);
|
||||
|
||||
$this->authorize('view', \App\Models\Asset::class);
|
||||
$file = config('app.private_uploads').'/signatures/'.$filename;
|
||||
$filetype = Helper::checkUploadIsImage($file);
|
||||
$disk = config('filesystems.default');
|
||||
switch (config("filesystems.disks.$disk.driver")) {
|
||||
|
||||
$contents = file_get_contents($file, false, stream_context_create(['http' => ['ignore_errors' => true]]));
|
||||
if ($contents === false) {
|
||||
\Log::warn('File '.$file.' not found');
|
||||
return false;
|
||||
} else {
|
||||
return Response::make($contents)->header('Content-Type', $filetype);
|
||||
case 's3':
|
||||
$file = 'private_uploads/signatures/'.$filename;
|
||||
return redirect()->away(Storage::disk($disk)->temporaryUrl($file, now()->addMinutes(5)));
|
||||
default:
|
||||
$this->authorize('view', \App\Models\Asset::class);
|
||||
$file = config('app.private_uploads').'/signatures/'.$filename;
|
||||
$filetype = Helper::checkUploadIsImage($file);
|
||||
|
||||
$contents = file_get_contents($file, false, stream_context_create(['http' => ['ignore_errors' => true]]));
|
||||
if ($contents === false) {
|
||||
Log::warning('File '.$file.' not found');
|
||||
return false;
|
||||
} else {
|
||||
return response()->make($contents)->header('Content-Type', $filetype);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public function getStoredEula($filename){
|
||||
|
||||
public function getStoredEula($filename) : Response | BinaryFileResponse
|
||||
{
|
||||
$this->authorize('view', \App\Models\Asset::class);
|
||||
$file = config('app.private_uploads').'/eula-pdfs/'.$filename;
|
||||
|
||||
return Response::download($file);
|
||||
return response()->download($file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,26 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AccessoryCheckoutRequest;
|
||||
use App\Http\Requests\StoreAccessoryRequest;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\AccessoryCheckout;
|
||||
|
||||
class AccessoriesController extends Controller
|
||||
{
|
||||
use CheckInOutRequest;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@@ -45,13 +51,13 @@ class AccessoriesController extends Controller
|
||||
'min_amt',
|
||||
'company_id',
|
||||
'notes',
|
||||
'users_count',
|
||||
'checkouts_count',
|
||||
'qty',
|
||||
];
|
||||
|
||||
|
||||
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'users', 'location', 'supplier')
|
||||
->withCount('users as users_count');
|
||||
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'checkouts', 'location', 'supplier')
|
||||
->withCount('checkouts as checkouts_count');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessories = $accessories->TextSearch($request->input('search'));
|
||||
@@ -120,12 +126,12 @@ class AccessoriesController extends Controller
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(StoreAccessoryRequest $request)
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
$accessory = new Accessory;
|
||||
@@ -143,15 +149,15 @@ class AccessoriesController extends Controller
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
$accessory = Accessory::withCount('users as users_count')->findOrFail($id);
|
||||
$accessory = Accessory::withCount('checkouts as checkouts_count')->findOrFail($id);
|
||||
|
||||
return (new AccessoriesTransformer)->transformAccessory($accessory);
|
||||
}
|
||||
@@ -160,10 +166,10 @@ class AccessoriesController extends Controller
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return array
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function accessory_detail($id)
|
||||
{
|
||||
@@ -194,28 +200,23 @@ class AccessoriesController extends Controller
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$accessory_users = $accessory->users;
|
||||
$total = $accessory_users->count();
|
||||
$accessory_checkouts = $accessory->checkouts;
|
||||
$total = $accessory_checkouts->count();
|
||||
|
||||
if ($total < $offset) {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$accessory_users = $accessory->users()->skip($offset)->take($limit)->get();
|
||||
$accessory_checkouts = $accessory->checkouts()->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessory_users = $accessory->users()
|
||||
->where(function ($query) use ($request) {
|
||||
$search_str = '%' . $request->input('search') . '%';
|
||||
$query->where('first_name', 'like', $search_str)
|
||||
->orWhere('last_name', 'like', $search_str)
|
||||
->orWhere('note', 'like', $search_str);
|
||||
})
|
||||
|
||||
$accessory_checkouts = $accessory->checkouts()->TextSearch($request->input('search'))
|
||||
->get();
|
||||
$total = $accessory_users->count();
|
||||
$total = $accessory_checkouts->count();
|
||||
}
|
||||
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_users, $total);
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_checkouts, $total);
|
||||
}
|
||||
|
||||
|
||||
@@ -272,43 +273,31 @@ class AccessoriesController extends Controller
|
||||
* If Slack is enabled and/or asset acceptance is enabled, it will also
|
||||
* trigger a Slack message and send an email.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function checkout(Request $request, $accessoryId)
|
||||
public function checkout(AccessoryCheckoutRequest $request, Accessory $accessory)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::withCount('users as users_count')->find($accessoryId))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.does_not_exist')));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
$target = $this->determineCheckoutTarget();
|
||||
$accessory->checkout_qty = $request->input('checkout_qty', 1);
|
||||
|
||||
|
||||
if ($accessory->numRemaining() > 0) {
|
||||
|
||||
if (! $user = User::find($request->input('assigned_to'))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.checkout.user_does_not_exist')));
|
||||
}
|
||||
|
||||
// Update the accessory data
|
||||
$accessory->assigned_to = $request->input('assigned_to');
|
||||
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
for ($i = 0; $i < $accessory->checkout_qty; $i++) {
|
||||
AccessoryCheckout::create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note'),
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => $target::class,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($accessory, $user, Auth::user(), $request->input('note')));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.checkout.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No accessories remaining'));
|
||||
// Set this value to be able to pass the qty through to the event
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.checkout.success')));
|
||||
|
||||
}
|
||||
|
||||
@@ -320,24 +309,24 @@ class AccessoriesController extends Controller
|
||||
* @param Request $request
|
||||
* @param int $accessoryUserId
|
||||
* @param string $backto
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function checkin(Request $request, $accessoryUserId = null)
|
||||
{
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryUserId))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.does_not_exist')));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$accessory = Accessory::find($accessory_checkout->accessory_id);
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
$logaction = $accessory->logCheckin(User::find($accessory_user->assigned_to), $request->input('note'));
|
||||
$logaction = $accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note'));
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
if (! is_null($accessory_user->assigned_to)) {
|
||||
$user = User::find($accessory_user->assigned_to);
|
||||
if ($accessory_checkout->delete()) {
|
||||
if (! is_null($accessory_checkout->assigned_to)) {
|
||||
$user = User::find($accessory_checkout->assigned_to);
|
||||
}
|
||||
|
||||
$data['log_id'] = $logaction->id;
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Actionlog;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls file related actions related
|
||||
* to assets for the Snipe-IT Asset Management application.
|
||||
*
|
||||
* Based on the Assets/AssetFilesController by A. Gianotto <snipe@snipe.net>
|
||||
*
|
||||
* @version v1.0
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
class AssetFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Accepts a POST to upload a file to the server.
|
||||
*
|
||||
* @param \App\Http\Requests\UploadFileRequest $request
|
||||
* @param int $assetId
|
||||
* @since [v6.0]
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $assetId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// Make sure we are allowed to update this asset
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
// If the file storage directory doesn't exist; create it
|
||||
if (! Storage::exists('private_uploads/assets')) {
|
||||
Storage::makeDirectory('private_uploads/assets', 775);
|
||||
}
|
||||
|
||||
// Loop over the attached files and add them to the asset
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file);
|
||||
|
||||
$asset->logUpload($file_name, e($request->get('notes')));
|
||||
}
|
||||
|
||||
// All done - report success
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.upload.success')));
|
||||
}
|
||||
|
||||
// We only reach here if no files were included in the POST, so tell the user this
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.upload.nofiles')), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the files for an asset.
|
||||
*
|
||||
* @param int $assetId
|
||||
* @since [v6.0]
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
public function list($assetId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
// Check that there are some uploads on this asset that can be listed
|
||||
if ($asset->uploads->count() > 0) {
|
||||
$files = array();
|
||||
foreach ($asset->uploads as $upload) {
|
||||
array_push($files, $upload);
|
||||
}
|
||||
// Give the list of files back to the user
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $files, trans('admin/hardware/message.upload.success')));
|
||||
}
|
||||
|
||||
// There are no files.
|
||||
return response()->json(Helper::formatStandardApiResponse('success', array(), trans('admin/hardware/message.upload.success')));
|
||||
}
|
||||
|
||||
// Send back an error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.error')), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v6.0]
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
public function show($assetId = null, $fileId = null) : JsonResponse | StreamedResponse | Storage | StorageHelper | BinaryFileResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
// Check that the file being requested exists for the asset
|
||||
if (! $log = Actionlog::whereNotNull('filename')->where('item_id', $asset->id)->find($fileId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.no_match', ['id' => $fileId])), 404);
|
||||
}
|
||||
|
||||
// Form the full filename with path
|
||||
$file = 'private_uploads/assets/'.$log->filename;
|
||||
Log::debug('Checking for '.$file);
|
||||
|
||||
if ($log->action_type == 'audit') {
|
||||
$file = 'private_uploads/audits/'.$log->filename;
|
||||
}
|
||||
|
||||
// Check the file actually exists on the filesystem
|
||||
if (! Storage::exists($file)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.does_not_exist', ['id' => $fileId])), 404);
|
||||
}
|
||||
|
||||
if (request('inline') == 'true') {
|
||||
|
||||
$headers = [
|
||||
'Content-Disposition' => 'inline',
|
||||
];
|
||||
|
||||
return Storage::download($file, $log->filename, $headers);
|
||||
}
|
||||
|
||||
return StorageHelper::downloader($file);
|
||||
}
|
||||
|
||||
// Send back an error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.error', ['id' => $fileId])), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v6.0]
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
public function destroy($assetId = null, $fileId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
$rel_path = 'private_uploads/assets';
|
||||
|
||||
// the asset is valid
|
||||
if (isset($asset->id)) {
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
// Check for the file
|
||||
$log = Actionlog::find($fileId);
|
||||
if ($log) {
|
||||
// Check the file actually exists, and delete it
|
||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
||||
Storage::delete($rel_path.'/'.$log->filename);
|
||||
}
|
||||
// Delete the record of the file
|
||||
$log->delete();
|
||||
|
||||
// All deleting done - notify the user of success
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.deletefile.success')), 200);
|
||||
}
|
||||
|
||||
// The file doesn't seem to really exist, so report an error
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.deletefile.error')), 500);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.deletefile.error')), 500);
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,9 @@ use App\Http\Transformers\AssetMaintenancesTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Company;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Asset Maintenance for
|
||||
@@ -22,7 +21,6 @@ use Illuminate\Support\Facades\Input;
|
||||
class AssetMaintenancesController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Generates the JSON response for asset maintenances listing view.
|
||||
*
|
||||
@@ -30,9 +28,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
@@ -120,9 +117,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
@@ -148,9 +144,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $request
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
@@ -186,9 +181,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
public function destroy($assetMaintenanceId) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
@@ -212,9 +206,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
public function show($assetMaintenanceId) : JsonResponse
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Actionlog;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls file related actions related
|
||||
* to assets for the Snipe-IT Asset Management application.
|
||||
*
|
||||
* Based on the Assets/AssetFilesController by A. Gianotto <snipe@snipe.net>
|
||||
*
|
||||
* @version v1.0
|
||||
* @author [T. Scarsbrook] [<snipe@scarzybrook.co.uk>]
|
||||
*/
|
||||
class AssetModelFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Accepts a POST to upload a file to the server.
|
||||
*
|
||||
* @param \App\Http\Requests\UploadFileRequest $request
|
||||
* @param int $assetModelId
|
||||
* @since [v7.0.12]
|
||||
* @author [r-xyz]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $assetModelId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $assetModel = AssetModel::find($assetModelId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// Make sure we are allowed to update this asset
|
||||
$this->authorize('update', $assetModel);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
// If the file storage directory doesn't exist; create it
|
||||
if (! Storage::exists('private_uploads/assetmodels')) {
|
||||
Storage::makeDirectory('private_uploads/assetmodels', 775);
|
||||
}
|
||||
|
||||
// Loop over the attached files and add them to the asset
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/assetmodels/','model-'.$assetModel->id, $file);
|
||||
|
||||
$assetModel->logUpload($file_name, e($request->get('notes')));
|
||||
}
|
||||
|
||||
// All done - report success
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetModel, trans('admin/models/message.upload.success')));
|
||||
}
|
||||
|
||||
// We only reach here if no files were included in the POST, so tell the user this
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.upload.nofiles')), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the files for an asset.
|
||||
*
|
||||
* @param int $assetModelId
|
||||
* @since [v7.0.12]
|
||||
* @author [r-xyz]
|
||||
*/
|
||||
public function list($assetModelId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $assetModel = AssetModel::find($assetModelId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// the asset is valid
|
||||
if (isset($assetModel->id)) {
|
||||
$this->authorize('view', $assetModel);
|
||||
|
||||
// Check that there are some uploads on this asset that can be listed
|
||||
if ($assetModel->uploads->count() > 0) {
|
||||
$files = array();
|
||||
foreach ($assetModel->uploads as $upload) {
|
||||
array_push($files, $upload);
|
||||
}
|
||||
// Give the list of files back to the user
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $files, trans('admin/models/message.upload.success')));
|
||||
}
|
||||
|
||||
// There are no files.
|
||||
return response()->json(Helper::formatStandardApiResponse('success', array(), trans('admin/models/message.upload.success')));
|
||||
}
|
||||
|
||||
// Send back an error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.download.error')), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @param int $assetModelId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v7.0.12]
|
||||
* @author [r-xyz]
|
||||
*/
|
||||
public function show($assetModelId = null, $fileId = null) : JsonResponse | StreamedResponse | Storage | StorageHelper | BinaryFileResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $assetModel = AssetModel::find($assetModelId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
// the asset is valid
|
||||
if (isset($assetModel->id)) {
|
||||
$this->authorize('view', $assetModel);
|
||||
|
||||
// Check that the file being requested exists for the asset
|
||||
if (! $log = Actionlog::whereNotNull('filename')->where('item_id', $assetModel->id)->find($fileId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.download.no_match', ['id' => $fileId])), 404);
|
||||
}
|
||||
|
||||
// Form the full filename with path
|
||||
$file = 'private_uploads/assetmodels/'.$log->filename;
|
||||
Log::debug('Checking for '.$file);
|
||||
|
||||
if ($log->action_type == 'audit') {
|
||||
$file = 'private_uploads/audits/'.$log->filename;
|
||||
}
|
||||
|
||||
// Check the file actually exists on the filesystem
|
||||
if (! Storage::exists($file)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.download.does_not_exist', ['id' => $fileId])), 404);
|
||||
}
|
||||
|
||||
if (request('inline') == 'true') {
|
||||
|
||||
$headers = [
|
||||
'Content-Disposition' => 'inline',
|
||||
];
|
||||
|
||||
return Storage::download($file, $log->filename, $headers);
|
||||
}
|
||||
|
||||
return StorageHelper::downloader($file);
|
||||
}
|
||||
|
||||
// Send back an error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.download.error', ['id' => $fileId])), 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @param int $assetModelId
|
||||
* @param int $fileId
|
||||
* @since [v7.0.12]
|
||||
* @author [r-xyz]
|
||||
*/
|
||||
public function destroy($assetModelId = null, $fileId = null) : JsonResponse
|
||||
{
|
||||
// Start by checking if the asset being acted upon exists
|
||||
if (! $assetModel = AssetModel::find($assetModelId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.does_not_exist')), 404);
|
||||
}
|
||||
|
||||
$rel_path = 'private_uploads/assetmodels';
|
||||
|
||||
// the asset is valid
|
||||
if (isset($assetModel->id)) {
|
||||
$this->authorize('update', $assetModel);
|
||||
|
||||
// Check for the file
|
||||
$log = Actionlog::find($fileId);
|
||||
if ($log) {
|
||||
// Check the file actually exists, and delete it
|
||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
||||
Storage::delete($rel_path.'/'.$log->filename);
|
||||
}
|
||||
// Delete the record of the file
|
||||
$log->delete();
|
||||
|
||||
// All deleting done - notify the user of success
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/models/message.deletefile.success')), 200);
|
||||
}
|
||||
|
||||
// The file doesn't seem to really exist, so report an error
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.deletefile.error')), 500);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.deletefile.error')), 500);
|
||||
}
|
||||
}
|
||||
@@ -4,14 +4,16 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreAssetModelRequest;
|
||||
use App\Http\Transformers\AssetModelsTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to asset models for
|
||||
@@ -27,9 +29,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
$allowed_columns =
|
||||
@@ -77,6 +78,10 @@ class AssetModelsController extends Controller
|
||||
$assetmodels = $assetmodels->where('models.category_id', '=', $request->input('category_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('depreciation_id')) {
|
||||
$assetmodels = $assetmodels->where('models.depreciation_id', '=', $request->input('depreciation_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$assetmodels->TextSearch($request->input('search'));
|
||||
}
|
||||
@@ -115,10 +120,9 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\StoreAssetModelRequest $request
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(StoreAssetModelRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
$assetmodel = new AssetModel;
|
||||
@@ -139,9 +143,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
$assetmodel = AssetModel::withCount('assets as assets_count')->findOrFail($id);
|
||||
@@ -155,9 +158,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function assets($id)
|
||||
public function assets($id) : array
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
$assets = Asset::where('model_id', '=', $id)->get();
|
||||
@@ -175,7 +177,7 @@ class AssetModelsController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(StoreAssetModelRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
$assetmodel = AssetModel::findOrFail($id);
|
||||
@@ -208,9 +210,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
$assetmodel = AssetModel::findOrFail($id);
|
||||
@@ -224,7 +225,7 @@ class AssetModelsController extends Controller
|
||||
try {
|
||||
Storage::disk('public')->delete('assetmodels/'.$assetmodel->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
Log::info($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +241,7 @@ class AssetModelsController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Http\Requests\StoreAssetRequest;
|
||||
use App\Http\Requests\UpdateAssetRequest;
|
||||
use App\Http\Traits\MigratesLegacyAssetLocations;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\LicenseSeat;
|
||||
@@ -25,19 +26,13 @@ use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use \Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Input;
|
||||
use Paginator;
|
||||
use Slack;
|
||||
use Str;
|
||||
use TCPDF;
|
||||
use Validator;
|
||||
use Route;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
||||
/**
|
||||
@@ -57,9 +52,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function index(Request $request, $action = null, $upcoming_status = null)
|
||||
public function index(Request $request, $action = null, $upcoming_status = null) : JsonResponse | array
|
||||
{
|
||||
|
||||
$filter_non_deprecable_assets = false;
|
||||
@@ -416,9 +410,8 @@ class AssetsController extends Controller
|
||||
* @param string $tag
|
||||
* @since [v4.2.1]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function showByTag(Request $request, $tag)
|
||||
public function showByTag(Request $request, $tag) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('index', Asset::class);
|
||||
$assets = Asset::where('asset_tag', $tag)->with('assetstatus')->with('assignedTo');
|
||||
@@ -456,7 +449,7 @@ class AssetsController extends Controller
|
||||
* @since [v4.2.1]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function showBySerial(Request $request, $serial)
|
||||
public function showBySerial(Request $request, $serial) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('index', Asset::class);
|
||||
$assets = Asset::where('serial', $serial)->with('assetstatus')->with('assignedTo');
|
||||
@@ -483,19 +476,20 @@ class AssetsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function show(Request $request, $id)
|
||||
public function show(Request $request, $id) : JsonResponse | array
|
||||
{
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->withTrashed()
|
||||
->withCount('checkins as checkins_count', 'checkouts as checkouts_count', 'userRequests as user_requests_count')->findOrFail($id)) {
|
||||
if ($asset = Asset::with('assetstatus')
|
||||
->with('assignedTo')->withTrashed()
|
||||
->withCount('checkins as checkins_count', 'checkouts as checkouts_count', 'userRequests as user_requests_count')->find($id)) {
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
return (new AssetsTransformer)->transformAsset($asset, $request->input('components') );
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
|
||||
|
||||
}
|
||||
|
||||
public function licenses(Request $request, $id)
|
||||
public function licenses(Request $request, $id) : array
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$this->authorize('view', License::class);
|
||||
@@ -512,9 +506,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$assets = Asset::select([
|
||||
@@ -609,7 +602,7 @@ class AssetsController extends Controller
|
||||
if ($field->field_encrypted == '1') {
|
||||
Log::debug('This model field is encrypted in this fieldset.');
|
||||
|
||||
if (Gate::allows('admin')) {
|
||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||
|
||||
// If input value is null, use custom field's default value
|
||||
if (($field_val == null) && ($request->has('model_id') != '')) {
|
||||
@@ -639,7 +632,7 @@ class AssetsController extends Controller
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
@@ -659,37 +652,35 @@ class AssetsController extends Controller
|
||||
* Accepts a POST request to update an asset
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(UpdateAssetRequest $request, Asset $asset): JsonResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$asset->fill($request->validated());
|
||||
|
||||
if ($asset = Asset::find($id)) {
|
||||
$asset->fill($request->all());
|
||||
if ($request->has('model_id')) {
|
||||
$asset->model()->associate(AssetModel::find($request->validated()['model_id']));
|
||||
}
|
||||
if ($request->has('company_id')) {
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->validated()['company_id']);
|
||||
}
|
||||
if ($request->has('rtd_location_id') && !$request->has('location_id')) {
|
||||
$asset->location_id = $request->validated()['rtd_location_id'];
|
||||
}
|
||||
if ($request->input('last_audit_date')) {
|
||||
$asset->last_audit_date = Carbon::parse($request->input('last_audit_date'))->startOfDay()->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
($request->filled('model_id')) ?
|
||||
$asset->model()->associate(AssetModel::find($request->get('model_id'))) : null;
|
||||
($request->filled('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : '';
|
||||
($request->filled('company_id')) ?
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : '';
|
||||
/**
|
||||
* this is here just legacy reasons. Api\AssetController
|
||||
* used image_source once to allow encoded image uploads.
|
||||
*/
|
||||
if ($request->has('image_source')) {
|
||||
$request->offsetSet('image', $request->offsetGet('image_source'));
|
||||
}
|
||||
|
||||
($request->filled('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : null;
|
||||
|
||||
/**
|
||||
* this is here just legacy reasons. Api\AssetController
|
||||
* used image_source once to allow encoded image uploads.
|
||||
*/
|
||||
if ($request->has('image_source')) {
|
||||
$request->offsetSet('image', $request->offsetGet('image_source'));
|
||||
}
|
||||
|
||||
$asset = $request->handleImages($asset);
|
||||
$model = AssetModel::find($asset->model_id);
|
||||
$asset = $request->handleImages($asset);
|
||||
$model = $asset->model;
|
||||
|
||||
// Update custom fields
|
||||
$problems_updating_encrypted_custom_fields = false;
|
||||
@@ -704,7 +695,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||
$field_val = Crypt::encrypt($field_val);
|
||||
} else {
|
||||
$problems_updating_encrypted_custom_fields = true;
|
||||
@@ -715,39 +706,33 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($asset->save()) {
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
|
||||
$location = $target->location_id;
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) {
|
||||
$location = $target->location_id;
|
||||
|
||||
Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $id)
|
||||
Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $asset->id)
|
||||
->update(['location_id' => $target->location_id]);
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) {
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
$asset->image = $asset->getImageUrl();
|
||||
}
|
||||
|
||||
if ($problems_updating_encrypted_custom_fields) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
|
||||
} else {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
}
|
||||
if ($problems_updating_encrypted_custom_fields) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.encrypted_warning')));
|
||||
} else {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
}
|
||||
|
||||
|
||||
@@ -757,9 +742,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Asset::class);
|
||||
|
||||
@@ -786,9 +770,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v5.1.18]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function restore(Request $request, $assetId = null)
|
||||
public function restore(Request $request, $assetId = null) : JsonResponse
|
||||
{
|
||||
|
||||
if ($asset = Asset::withTrashed()->find($assetId)) {
|
||||
@@ -816,9 +799,8 @@ class AssetsController extends Controller
|
||||
* @author [N. Butler]
|
||||
* @param string $tag
|
||||
* @since [v6.0.5]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function checkoutByTag(AssetCheckoutRequest $request, $tag)
|
||||
public function checkoutByTag(AssetCheckoutRequest $request, $tag) : JsonResponse
|
||||
{
|
||||
if ($asset = Asset::where('asset_tag', $tag)->first()) {
|
||||
return $this->checkout($request, $asset->id);
|
||||
@@ -832,9 +814,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function checkout(AssetCheckoutRequest $request, $asset_id)
|
||||
public function checkout(AssetCheckoutRequest $request, $asset_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
@@ -851,7 +832,6 @@ class AssetsController extends Controller
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
];
|
||||
|
||||
|
||||
// This item is checked out to a location
|
||||
if (request('checkout_to_type') == 'location') {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
@@ -878,13 +858,10 @@ class AssetsController extends Controller
|
||||
$asset->status_id = $request->get('status_id');
|
||||
}
|
||||
|
||||
|
||||
if (! isset($target)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'Checkout target for asset '.e($asset->asset_tag).' is invalid - '.$error_payload['target_type'].' does not exist.'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
$checkout_at = request('checkout_at', date('Y-m-d H:i:s'));
|
||||
$expected_checkin = request('expected_checkin', null);
|
||||
$note = request('note', null);
|
||||
@@ -900,9 +877,7 @@ class AssetsController extends Controller
|
||||
// $asset->location_id = $target->rtd_location_id;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id)) {
|
||||
if ($asset->checkOut($target, auth()->user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success')));
|
||||
}
|
||||
|
||||
@@ -916,9 +891,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function checkin(Request $request, $asset_id)
|
||||
public function checkin(Request $request, $asset_id) : JsonResponse
|
||||
{
|
||||
$asset = Asset::with('model')->findOrFail($asset_id);
|
||||
$this->authorize('checkin', $asset);
|
||||
@@ -954,7 +928,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->has('status_id')) {
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
@@ -983,7 +957,7 @@ class AssetsController extends Controller
|
||||
});
|
||||
|
||||
if ($asset->save()) {
|
||||
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at, $originalValues));
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', [
|
||||
'asset_tag'=> e($asset->asset_tag),
|
||||
@@ -1000,12 +974,11 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Janes] [<ajanes@adagiohealth.org>]
|
||||
* @since [v6.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function checkinByTag(Request $request, $tag = null)
|
||||
public function checkinByTag(Request $request, $tag = null) : JsonResponse
|
||||
{
|
||||
$this->authorize('checkin', Asset::class);
|
||||
if(null == $tag && null !== ($request->input('asset_tag'))) {
|
||||
if (null == $tag && null !== ($request->input('asset_tag'))) {
|
||||
$tag = $request->input('asset_tag');
|
||||
}
|
||||
$asset = Asset::where('asset_tag', $tag)->first();
|
||||
@@ -1026,9 +999,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function audit(Request $request)
|
||||
public function audit(Request $request) : JsonResponse
|
||||
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
@@ -1119,9 +1091,8 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function requestable(Request $request)
|
||||
public function requestable(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('viewRequestable', Asset::class);
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ use App\Http\Transformers\CategoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class CategoriesController extends Controller
|
||||
{
|
||||
@@ -21,7 +21,7 @@ class CategoriesController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : array
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$allowed_columns = [
|
||||
@@ -115,7 +115,7 @@ class CategoriesController extends Controller
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Category::class);
|
||||
$category = new Category;
|
||||
@@ -136,9 +136,8 @@ class CategoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$category = Category::withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
@@ -156,7 +155,7 @@ class CategoriesController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Category::class);
|
||||
$category = Category::findOrFail($id);
|
||||
@@ -164,7 +163,7 @@ class CategoriesController extends Controller
|
||||
// Don't allow the user to change the category_type once it's been created
|
||||
if (($request->filled('category_type')) && ($category->category_type != $request->input('category_type'))) {
|
||||
return response()->json(
|
||||
Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.update.cannot_change_category_type'))
|
||||
Helper::formatStandardApiResponse('error', null, ['category_type' => trans('admin/categories/message.update.cannot_change_category_type')], 422)
|
||||
);
|
||||
}
|
||||
$category->fill($request->all());
|
||||
@@ -185,7 +184,7 @@ class CategoriesController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Category::class);
|
||||
$category = Category::withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
@@ -208,7 +207,7 @@ class CategoriesController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request, $category_type = 'asset')
|
||||
public function selectlist(Request $request, $category_type = 'asset') : array
|
||||
{
|
||||
$this->authorize('view.selectlists');
|
||||
$categories = Category::select([
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Models\Company;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class CompaniesController extends Controller
|
||||
{
|
||||
@@ -18,9 +19,8 @@ class CompaniesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Company::class);
|
||||
|
||||
@@ -79,9 +79,8 @@ class CompaniesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Company::class);
|
||||
$company = new Company;
|
||||
@@ -102,9 +101,8 @@ class CompaniesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Company::class);
|
||||
$company = Company::findOrFail($id);
|
||||
@@ -120,9 +118,8 @@ class CompaniesController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Company::class);
|
||||
$company = Company::findOrFail($id);
|
||||
@@ -144,9 +141,8 @@ class CompaniesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Company::class);
|
||||
$company = Company::findOrFail($id);
|
||||
@@ -169,7 +165,7 @@ class CompaniesController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$this->authorize('view.selectlists');
|
||||
$companies = Company::select([
|
||||
|
||||
@@ -5,15 +5,17 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ComponentsTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Events\ComponentCheckedIn;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ComponentsController extends Controller
|
||||
{
|
||||
@@ -23,9 +25,8 @@ class ComponentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Component::class);
|
||||
|
||||
@@ -115,9 +116,8 @@ class ComponentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
$component = new Component;
|
||||
@@ -136,9 +136,8 @@ class ComponentsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Component::class);
|
||||
$component = Component::findOrFail($id);
|
||||
@@ -155,9 +154,8 @@ class ComponentsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Component::class);
|
||||
$component = Component::findOrFail($id);
|
||||
@@ -178,9 +176,8 @@ class ComponentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Component::class);
|
||||
$component = Component::findOrFail($id);
|
||||
@@ -197,9 +194,8 @@ class ComponentsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getAssets(Request $request, $id)
|
||||
public function getAssets(Request $request, $id) : array
|
||||
{
|
||||
$this->authorize('view', \App\Models\Asset::class);
|
||||
|
||||
@@ -240,10 +236,8 @@ class ComponentsController extends Controller
|
||||
* @since [v5.1.8]
|
||||
* @param Request $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function checkout(Request $request, $componentId)
|
||||
public function checkout(Request $request, $componentId) : JsonResponse
|
||||
{
|
||||
// Check if the component exists
|
||||
if (!$component = Component::find($componentId)) {
|
||||
@@ -274,9 +268,9 @@ class ComponentsController extends Controller
|
||||
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'created_at' => \Carbon::now(),
|
||||
'created_at' => Carbon::now(),
|
||||
'assigned_qty' => $request->get('assigned_qty', 1),
|
||||
'user_id' => \Auth::id(),
|
||||
'user_id' => auth()->id(),
|
||||
'asset_id' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note'),
|
||||
]);
|
||||
@@ -296,12 +290,10 @@ class ComponentsController extends Controller
|
||||
* @since [v5.1.8]
|
||||
* @param Request $request
|
||||
* @param $component_asset_id
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function checkin(Request $request, $component_asset_id)
|
||||
public function checkin(Request $request, $component_asset_id) : JsonResponse
|
||||
{
|
||||
if ($component_assets = \DB::table('components_assets')->find($component_asset_id)) {
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
|
||||
@@ -314,7 +306,7 @@ class ComponentsController extends Controller
|
||||
|
||||
if ($max_to_checkin > 1) {
|
||||
|
||||
$validator = \Validator::make($request->all(), [
|
||||
$validator = Validator::make($request->all(), [
|
||||
"checkin_qty" => "required|numeric|between:1,$max_to_checkin"
|
||||
]);
|
||||
|
||||
@@ -331,21 +323,21 @@ class ComponentsController extends Controller
|
||||
// actually checked out.
|
||||
$component_assets->assigned_qty = $qty_remaining_in_checkout;
|
||||
|
||||
\Log::debug($component_asset_id.' - '.$qty_remaining_in_checkout.' remaining in record '.$component_assets->id);
|
||||
Log::debug($component_asset_id.' - '.$qty_remaining_in_checkout.' remaining in record '.$component_assets->id);
|
||||
|
||||
\DB::table('components_assets')->where('id',
|
||||
DB::table('components_assets')->where('id',
|
||||
$component_asset_id)->update(['assigned_qty' => $qty_remaining_in_checkout]);
|
||||
|
||||
// If the checked-in qty is exactly the same as the assigned_qty,
|
||||
// we can simply delete the associated components_assets record
|
||||
if ($qty_remaining_in_checkout == 0) {
|
||||
\DB::table('components_assets')->where('id', '=', $component_asset_id)->delete();
|
||||
DB::table('components_assets')->where('id', '=', $component_asset_id)->delete();
|
||||
}
|
||||
|
||||
|
||||
$asset = Asset::find($component_assets->asset_id);
|
||||
|
||||
event(new CheckoutableCheckedIn($component, $asset, \Auth::user(), $request->input('note'), \Carbon::now()));
|
||||
event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now()));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.checkin.success')));
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreConsumableRequest;
|
||||
use App\Http\Transformers\ConsumablesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
@@ -12,7 +13,8 @@ use App\Models\Consumable;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ConsumablesController extends Controller
|
||||
{
|
||||
@@ -21,34 +23,13 @@ class ConsumablesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : array
|
||||
{
|
||||
$this->authorize('index', Consumable::class);
|
||||
|
||||
// This array is what determines which fields should be allowed to be sorted on ON the table itself, no relations
|
||||
// Relations will be handled in query scopes a little further down.
|
||||
$allowed_columns =
|
||||
[
|
||||
'id',
|
||||
'name',
|
||||
'order_number',
|
||||
'min_amt',
|
||||
'purchase_date',
|
||||
'purchase_cost',
|
||||
'company',
|
||||
'category',
|
||||
'model_number',
|
||||
'item_no',
|
||||
'qty',
|
||||
'image',
|
||||
'notes',
|
||||
];
|
||||
|
||||
$consumables = Consumable::select('consumables.*')
|
||||
->with('company', 'location', 'category', 'users', 'manufacturer');
|
||||
$consumables = Consumable::with('company', 'location', 'category', 'supplier', 'manufacturer')
|
||||
->withCount('users as consumables_users_count');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$consumables = $consumables->TextSearch(e($request->input('search')));
|
||||
@@ -90,15 +71,9 @@ class ConsumablesController extends Controller
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $consumables->count()) ? $consumables->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$allowed_columns = ['id', 'name', 'order_number', 'min_amt', 'purchase_date', 'purchase_cost', 'company', 'category', 'model_number', 'item_no', 'manufacturer', 'location', 'qty', 'image'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
$sort_override = $request->input('sort');
|
||||
$column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'created_at';
|
||||
|
||||
|
||||
switch ($sort_override) {
|
||||
switch ($request->input('sort')) {
|
||||
case 'category':
|
||||
$consumables = $consumables->OrderCategory($order);
|
||||
break;
|
||||
@@ -112,10 +87,30 @@ class ConsumablesController extends Controller
|
||||
$consumables = $consumables->OrderCompany($order);
|
||||
break;
|
||||
case 'supplier':
|
||||
$components = $consumables->OrderSupplier($order);
|
||||
$consumables = $consumables->OrderSupplier($order);
|
||||
break;
|
||||
default:
|
||||
$consumables = $consumables->orderBy($column_sort, $order);
|
||||
// This array is what determines which fields should be allowed to be sorted on ON the table itself.
|
||||
// These must match a column on the consumables table directly.
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'name',
|
||||
'order_number',
|
||||
'min_amt',
|
||||
'purchase_date',
|
||||
'purchase_cost',
|
||||
'company',
|
||||
'category',
|
||||
'model_number',
|
||||
'item_no',
|
||||
'manufacturer',
|
||||
'location',
|
||||
'qty',
|
||||
'image'
|
||||
];
|
||||
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
$consumables = $consumables->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -131,9 +126,8 @@ class ConsumablesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(StoreConsumableRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
$consumable = new Consumable;
|
||||
@@ -152,9 +146,8 @@ class ConsumablesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Consumable::class);
|
||||
$consumable = Consumable::with('users')->findOrFail($id);
|
||||
@@ -169,9 +162,8 @@ class ConsumablesController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(StoreConsumableRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Consumable::class);
|
||||
$consumable = Consumable::findOrFail($id);
|
||||
@@ -191,9 +183,8 @@ class ConsumablesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Consumable::class);
|
||||
$consumable = Consumable::findOrFail($id);
|
||||
@@ -210,9 +201,8 @@ class ConsumablesController extends Controller
|
||||
* @see \App\Http\Controllers\Consumables\ConsumablesController::getView() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return array
|
||||
*/
|
||||
public function getDataView($consumableId)
|
||||
public function getDataView($consumableId) : array
|
||||
{
|
||||
$consumable = Consumable::with(['consumableAssignments'=> function ($query) {
|
||||
$query->orderBy($query->getModel()->getTable().'.created_at', 'DESC');
|
||||
@@ -251,9 +241,8 @@ class ConsumablesController extends Controller
|
||||
* @author [A. Gutierrez] [<andres@baller.tv>]
|
||||
* @param int $id
|
||||
* @since [v4.9.5]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkout(Request $request, $id)
|
||||
public function checkout(Request $request, $id) : JsonResponse
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (!$consumable = Consumable::with('users')->find($id)) {
|
||||
@@ -277,7 +266,6 @@ class ConsumablesController extends Controller
|
||||
if (!$user = User::find($request->input('assigned_to'))) {
|
||||
// Return error message
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'No user found'));
|
||||
\Log::debug('No valid user');
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
@@ -292,7 +280,7 @@ class ConsumablesController extends Controller
|
||||
]
|
||||
);
|
||||
|
||||
event(new CheckoutableCheckedOut($consumable, $user, Auth::user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.checkout.success')));
|
||||
|
||||
@@ -303,7 +291,7 @@ class ConsumablesController extends Controller
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$consumables = Consumable::select([
|
||||
'consumables.id',
|
||||
|
||||
@@ -8,7 +8,8 @@ use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Http\Request;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class CustomFieldsController extends Controller
|
||||
{
|
||||
@@ -20,7 +21,7 @@ class CustomFieldsController extends Controller
|
||||
* @since [v3.0]
|
||||
* @return array
|
||||
*/
|
||||
public function index()
|
||||
public function index() : array
|
||||
{
|
||||
$this->authorize('index', CustomField::class);
|
||||
$fields = CustomField::get();
|
||||
@@ -33,9 +34,8 @@ class CustomFieldsController extends Controller
|
||||
* @author [V. Cordes] [<volker@fdatek.de>]
|
||||
* @param int $id
|
||||
* @since [v4.1.10]
|
||||
* @return View
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', CustomField::class);
|
||||
if ($field = CustomField::find($id)) {
|
||||
@@ -52,9 +52,8 @@ class CustomFieldsController extends Controller
|
||||
* @since [v4.1.10]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$field = CustomField::findOrFail($id);
|
||||
@@ -86,9 +85,8 @@ class CustomFieldsController extends Controller
|
||||
* @author [V. Cordes] [<volker@fdatek.de>]
|
||||
* @since [v4.1.10]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
$field = new CustomField;
|
||||
@@ -136,7 +134,7 @@ class CustomFieldsController extends Controller
|
||||
return $fieldset->fields()->sync($fields);
|
||||
}
|
||||
|
||||
public function associate(Request $request, $field_id)
|
||||
public function associate(Request $request, $field_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', CustomFieldset::class);
|
||||
|
||||
@@ -155,10 +153,9 @@ class CustomFieldsController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.update.success')));
|
||||
}
|
||||
|
||||
public function disassociate(Request $request, $field_id)
|
||||
public function disassociate(Request $request, $field_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', CustomFieldset::class);
|
||||
|
||||
$field = CustomField::findOrFail($field_id);
|
||||
|
||||
$fieldset_id = $request->input('fieldset_id');
|
||||
@@ -179,9 +176,8 @@ class CustomFieldsController extends Controller
|
||||
*
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy($field_id)
|
||||
public function destroy($field_id) : JsonResponse
|
||||
{
|
||||
$field = CustomField::findOrFail($field_id);
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@ use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Http\Request;
|
||||
use Redirect;
|
||||
use View;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Custom Asset Fieldsets for
|
||||
@@ -30,9 +29,8 @@ class CustomFieldsetsController extends Controller
|
||||
* @author [Josh Gibson]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
public function index() : array
|
||||
{
|
||||
$this->authorize('index', CustomField::class);
|
||||
$fieldsets = CustomFieldset::withCount('fields as fields_count', 'models as models_count')->get();
|
||||
@@ -46,9 +44,8 @@ class CustomFieldsetsController extends Controller
|
||||
* @author [Josh Gibson]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', CustomField::class);
|
||||
if ($fieldset = CustomFieldset::find($id)) {
|
||||
@@ -65,9 +62,8 @@ class CustomFieldsetsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$fieldset = CustomFieldset::findOrFail($id);
|
||||
@@ -86,9 +82,8 @@ class CustomFieldsetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
$fieldset = new CustomFieldset;
|
||||
@@ -118,9 +113,8 @@ class CustomFieldsetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', CustomField::class);
|
||||
$fieldset = CustomFieldset::findOrFail($id);
|
||||
@@ -147,7 +141,7 @@ class CustomFieldsetsController extends Controller
|
||||
* @param $fieldsetId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function fields($id)
|
||||
public function fields($id) : array
|
||||
{
|
||||
$this->authorize('view', CustomField::class);
|
||||
$set = CustomFieldset::findOrFail($id);
|
||||
@@ -164,14 +158,11 @@ class CustomFieldsetsController extends Controller
|
||||
* @param $fieldsetId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function fieldsWithDefaultValues($fieldsetId, $modelId)
|
||||
public function fieldsWithDefaultValues($fieldsetId, $modelId) : array
|
||||
{
|
||||
$this->authorize('view', CustomField::class);
|
||||
|
||||
$set = CustomFieldset::findOrFail($fieldsetId);
|
||||
|
||||
$fields = $set->fields;
|
||||
|
||||
return (new CustomFieldsTransformer)->transformCustomFieldsWithDefaultValues($fields, $modelId, $fields->count());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,11 @@ use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\DepartmentsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\Department;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
@@ -20,9 +19,8 @@ class DepartmentsController extends Controller
|
||||
*
|
||||
* @author [Godfrey Martinez] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
$allowed_columns = ['id', 'name', 'image', 'users_count'];
|
||||
@@ -91,16 +89,15 @@ class DepartmentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Department::class);
|
||||
$department = new Department;
|
||||
$department->fill($request->all());
|
||||
$department = $request->handleImages($department);
|
||||
|
||||
$department->user_id = Auth::user()->id;
|
||||
$department->user_id = auth()->id();
|
||||
$department->manager_id = ($request->filled('manager_id') ? $request->input('manager_id') : null);
|
||||
|
||||
if ($department->save()) {
|
||||
@@ -116,13 +113,11 @@ class DepartmentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
$department = Department::findOrFail($id);
|
||||
|
||||
return (new DepartmentsTransformer)->transformDepartment($department);
|
||||
}
|
||||
|
||||
@@ -133,9 +128,8 @@ class DepartmentsController extends Controller
|
||||
* @since [v5.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Department::class);
|
||||
$department = Department::findOrFail($id);
|
||||
@@ -156,9 +150,8 @@ class DepartmentsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$department = Department::findOrFail($id);
|
||||
|
||||
@@ -180,7 +173,7 @@ class DepartmentsController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\DepreciationsTransformer;
|
||||
use App\Models\Depreciation;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class DepreciationsController extends Controller
|
||||
{
|
||||
@@ -15,14 +16,26 @@ class DepreciationsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Depreciation::class);
|
||||
$allowed_columns = ['id','name','months','depreciation_min','created_at'];
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'name',
|
||||
'months',
|
||||
'depreciation_min',
|
||||
'depreciation_type',
|
||||
'created_at',
|
||||
'assets_count',
|
||||
'models_count',
|
||||
'licenses_count',
|
||||
];
|
||||
|
||||
$depreciations = Depreciation::select('id','name','months','depreciation_min','user_id','created_at','updated_at');
|
||||
$depreciations = Depreciation::select('id','name','months','depreciation_min','depreciation_type','user_id','created_at','updated_at')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('models as models_count')
|
||||
->withCount('licenses as licenses_count');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$depreciations = $depreciations->TextSearch($request->input('search'));
|
||||
@@ -48,9 +61,8 @@ class DepreciationsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Depreciation::class);
|
||||
$depreciation = new Depreciation;
|
||||
@@ -69,9 +81,8 @@ class DepreciationsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Depreciation::class);
|
||||
$depreciation = Depreciation::findOrFail($id);
|
||||
@@ -86,9 +97,8 @@ class DepreciationsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Depreciation::class);
|
||||
$depreciation = Depreciation::findOrFail($id);
|
||||
@@ -107,9 +117,8 @@ class DepreciationsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Depreciation::class);
|
||||
$depreciation = Depreciation::withCount('models as models_count')->findOrFail($id);
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\GroupsTransformer;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Http\Request;
|
||||
use Auth;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
|
||||
class GroupsController extends Controller
|
||||
@@ -17,9 +17,8 @@ class GroupsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('superadmin');
|
||||
|
||||
@@ -56,19 +55,21 @@ class GroupsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('superadmin');
|
||||
$group = new Group;
|
||||
// Get all the available permissions
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = Helper::selectedPermissionsArray($permissions, $permissions);
|
||||
|
||||
$group->name = $request->input('name');
|
||||
$group->created_by = Auth::user()->id;
|
||||
$group->permissions = json_encode($request->input('permissions')); // Todo - some JSON validation stuff here
|
||||
$group->created_by = auth()->id();
|
||||
$group->permissions = json_encode($request->input('permissions', $groupPermissions));
|
||||
|
||||
if ($group->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new GroupsTransformer)->transformGroup($group), trans('admin/groups/message.success.create')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $group->getErrors()));
|
||||
@@ -80,13 +81,11 @@ class GroupsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('superadmin');
|
||||
$group = Group::findOrFail($id);
|
||||
|
||||
return (new GroupsTransformer)->transformGroup($group);
|
||||
}
|
||||
|
||||
@@ -97,9 +96,8 @@ class GroupsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('superadmin');
|
||||
$group = Group::findOrFail($id);
|
||||
@@ -108,7 +106,7 @@ class GroupsController extends Controller
|
||||
$group->permissions = $request->input('permissions'); // Todo - some JSON validation stuff here
|
||||
|
||||
if ($group->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.update.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new GroupsTransformer)->transformGroup($group), trans('admin/groups/message.success.update')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $group->getErrors()));
|
||||
@@ -120,9 +118,8 @@ class GroupsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('superadmin');
|
||||
$group = Group::findOrFail($id);
|
||||
|
||||
@@ -9,22 +9,23 @@ use App\Http\Transformers\ImportsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Import;
|
||||
use Artisan;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Database\Eloquent\JsonEncodingException;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ImportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
public function index() : JsonResponse | array
|
||||
{
|
||||
$this->authorize('import');
|
||||
$imports = Import::latest()->get();
|
||||
@@ -36,9 +37,8 @@ class ImportController extends Controller
|
||||
* Process and store a CSV upload file.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function store()
|
||||
public function store() : JsonResponse
|
||||
{
|
||||
$this->authorize('import');
|
||||
if (! config('app.lock_passwords')) {
|
||||
@@ -151,18 +151,17 @@ class ImportController extends Controller
|
||||
* Processes the specified Import.
|
||||
*
|
||||
* @param int $import_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function process(ItemImportRequest $request, $import_id)
|
||||
public function process(ItemImportRequest $request, $import_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('import');
|
||||
|
||||
// Run a backup immediately before processing
|
||||
if ($request->get('run-backup')) {
|
||||
\Log::debug('Backup manually requested via importer');
|
||||
Log::debug('Backup manually requested via importer');
|
||||
Artisan::call('snipeit:backup', ['--filename' => 'pre-import-backup-'.date('Y-m-d-H:i:s')]);
|
||||
} else {
|
||||
\Log::debug('NO BACKUP requested via importer');
|
||||
Log::debug('NO BACKUP requested via importer');
|
||||
}
|
||||
|
||||
$import = Import::find($import_id);
|
||||
@@ -211,9 +210,8 @@ class ImportController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $import_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($import_id)
|
||||
public function destroy($import_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
|
||||
@@ -230,6 +228,8 @@ class ImportController extends Controller
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('warning', null, trans('admin/hardware/message.import.file_not_deleted_warning')));
|
||||
}
|
||||
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('warning', null, trans('admin/hardware/message.import.file_not_deleted_warning')));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use App\Http\Transformers\LabelsTransformer;
|
||||
use App\Models\Labels\Label;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\ItemNotFoundException;
|
||||
use Auth;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class LabelsController extends Controller
|
||||
{
|
||||
@@ -16,9 +16,8 @@ class LabelsController extends Controller
|
||||
* Returns JSON listing of all labels.
|
||||
*
|
||||
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Label::class);
|
||||
|
||||
@@ -50,9 +49,8 @@ class LabelsController extends Controller
|
||||
*
|
||||
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
|
||||
* @param string $labelName
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(string $labelName)
|
||||
public function show(string $labelName) : JsonResponse | array
|
||||
{
|
||||
$labelName = str_replace('/', '\\', $labelName);
|
||||
try {
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LicenseSeatsController extends Controller
|
||||
@@ -19,11 +19,10 @@ class LicenseSeatsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $licenseId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request, $licenseId)
|
||||
public function index(Request $request, $licenseId) : JsonResponse | array
|
||||
{
|
||||
//
|
||||
|
||||
if ($license = License::find($licenseId)) {
|
||||
$this->authorize('view', $license);
|
||||
|
||||
@@ -64,11 +63,10 @@ class LicenseSeatsController extends Controller
|
||||
*
|
||||
* @param int $licenseId
|
||||
* @param int $seatId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($licenseId, $seatId)
|
||||
public function show($licenseId, $seatId) : JsonResponse | array
|
||||
{
|
||||
//
|
||||
|
||||
$this->authorize('view', License::class);
|
||||
// sanity checks:
|
||||
// 1. does the license seat exist?
|
||||
@@ -89,19 +87,18 @@ class LicenseSeatsController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $licenseId
|
||||
* @param int $seatId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $licenseId, $seatId)
|
||||
public function update(Request $request, $licenseId, $seatId) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('checkout', License::class);
|
||||
|
||||
// sanity checks:
|
||||
// 1. does the license seat exist?
|
||||
|
||||
if (! $licenseSeat = LicenseSeat::find($seatId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||
}
|
||||
// 2. does the seat belong to the specified license?
|
||||
if (! $license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
|
||||
|
||||
$license = $licenseSeat->license()->first();
|
||||
if (!$license || $license->id != intval($licenseId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||
}
|
||||
|
||||
@@ -110,7 +107,7 @@ class LicenseSeatsController extends Controller
|
||||
|
||||
// attempt to update the license seat
|
||||
$licenseSeat->fill($request->all());
|
||||
$licenseSeat->user_id = Auth::user()->id;
|
||||
$licenseSeat->user_id = auth()->id();
|
||||
|
||||
// check if this update is a checkin operation
|
||||
// 1. are relevant fields touched at all?
|
||||
|
||||
@@ -4,14 +4,12 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class LicensesController extends Controller
|
||||
{
|
||||
@@ -21,16 +19,15 @@ class LicensesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
|
||||
$licenses = License::with('company', 'manufacturer', 'supplier','category')->withCount('freeSeats as free_seats_count');
|
||||
$licenses = License::with('company', 'manufacturer', 'supplier','category', 'adminuser')->withCount('freeSeats as free_seats_count');
|
||||
|
||||
if ($request->filled('company_id')) {
|
||||
$licenses->where('company_id', '=', $request->input('company_id'));
|
||||
$licenses->where('licenses.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('name')) {
|
||||
@@ -73,6 +70,9 @@ class LicensesController extends Controller
|
||||
$licenses->where('depreciation_id', '=', $request->input('depreciation_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('user_id')) {
|
||||
$licenses->where('user_id', '=', $request->input('user_id'));
|
||||
}
|
||||
|
||||
if (($request->filled('maintained')) && ($request->input('maintained')=='true')) {
|
||||
$licenses->where('maintained','=',1);
|
||||
@@ -116,6 +116,9 @@ class LicensesController extends Controller
|
||||
case 'company':
|
||||
$licenses = $licenses->leftJoin('companies', 'licenses.company_id', '=', 'companies.id')->orderBy('companies.name', $order);
|
||||
break;
|
||||
case 'created_by':
|
||||
$licenses = $licenses->OrderCreatedBy($order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns =
|
||||
[
|
||||
@@ -156,11 +159,9 @@ class LicensesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
//
|
||||
$this->authorize('create', License::class);
|
||||
$license = new License;
|
||||
$license->fill($request->all());
|
||||
@@ -177,9 +178,8 @@ class LicensesController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$license = License::withCount('freeSeats')->findOrFail($id);
|
||||
@@ -195,9 +195,8 @@ class LicensesController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse | array
|
||||
{
|
||||
//
|
||||
$this->authorize('update', License::class);
|
||||
@@ -218,9 +217,8 @@ class LicensesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
//
|
||||
$license = License::findOrFail($id);
|
||||
@@ -248,7 +246,7 @@ class LicensesController extends Controller
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$licenses = License::select([
|
||||
'licenses.id',
|
||||
|
||||
@@ -5,12 +5,15 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\LocationsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class LocationsController extends Controller
|
||||
{
|
||||
@@ -21,7 +24,7 @@ class LocationsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
$allowed_columns = [
|
||||
@@ -138,9 +141,8 @@ class LocationsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Location::class);
|
||||
$location = new Location;
|
||||
@@ -160,9 +162,8 @@ class LocationsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
$location = Location::with('parent', 'manager', 'children')
|
||||
@@ -199,9 +200,8 @@ class LocationsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Location::class);
|
||||
$location = Location::findOrFail($id);
|
||||
@@ -224,15 +224,23 @@ class LocationsController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
|
||||
}
|
||||
|
||||
public function assets(Request $request, Location $location) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$this->authorize('view', $location);
|
||||
$assets = Asset::where('assigned_to', '=', $location->id)->where('assigned_type', '=', Location::class)->with('model', 'model.category', 'assetstatus', 'location', 'company', 'defaultLoc');
|
||||
$assets = $assets->get();
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Location::class);
|
||||
$location = Location::withCount('assignedAssets as assigned_assets_count')
|
||||
@@ -240,11 +248,12 @@ class LocationsController extends Controller
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->findOrFail($id);
|
||||
|
||||
if (! $location->isDeletable()) {
|
||||
return response()
|
||||
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
|
||||
->json(Helper::formatStandardApiResponse('error', null, trans('admin/locations/message.assoc_users')));
|
||||
}
|
||||
$this->authorize('delete', $location);
|
||||
$location->delete();
|
||||
@@ -280,7 +289,7 @@ class LocationsController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
// If a user is in the process of editing their profile, as determined by the referrer,
|
||||
// then we check that they have permission to edit their own location.
|
||||
@@ -325,7 +334,6 @@ class LocationsController extends Controller
|
||||
|
||||
$paginated_results = new LengthAwarePaginator($locations_formatted->forPage($page, 500), $locations_formatted->count(), 500, $page, []);
|
||||
|
||||
//return [];
|
||||
return (new SelectlistTransformer)->transformSelectlist($paginated_results);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ use App\Models\Actionlog;
|
||||
use App\Models\Manufacturer;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ManufacturersController extends Controller
|
||||
{
|
||||
@@ -22,7 +22,7 @@ class ManufacturersController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Manufacturer::class);
|
||||
$allowed_columns = ['id', 'name', 'url', 'support_url', 'support_email', 'warranty_lookup_url', 'support_phone', 'created_at', 'updated_at', 'image', 'assets_count', 'consumables_count', 'components_count', 'licenses_count'];
|
||||
@@ -83,9 +83,8 @@ class ManufacturersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Manufacturer::class);
|
||||
$manufacturer = new Manufacturer;
|
||||
@@ -105,9 +104,8 @@ class ManufacturersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Manufacturer::class);
|
||||
$manufacturer = Manufacturer::withCount('assets as assets_count')->withCount('licenses as licenses_count')->withCount('consumables as consumables_count')->withCount('accessories as accessories_count')->findOrFail($id);
|
||||
@@ -122,9 +120,8 @@ class ManufacturersController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Manufacturer::class);
|
||||
$manufacturer = Manufacturer::findOrFail($id);
|
||||
@@ -144,9 +141,8 @@ class ManufacturersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Manufacturer::class);
|
||||
$manufacturer = Manufacturer::findOrFail($id);
|
||||
@@ -167,10 +163,9 @@ class ManufacturersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.3.4]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function restore($id)
|
||||
public function restore($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Manufacturer::class);
|
||||
|
||||
@@ -186,7 +181,7 @@ class ManufacturersController extends Controller
|
||||
$logaction->item_type = Manufacturer::class;
|
||||
$logaction->item_id = $manufacturer->id;
|
||||
$logaction->created_at = date('Y-m-d H:i:s');
|
||||
$logaction->user_id = Auth::user()->id;
|
||||
$logaction->user_id = auth()->id();
|
||||
$logaction->logaction('restore');
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', trans('admin/manufacturers/message.restore.success')), 200);
|
||||
@@ -206,7 +201,7 @@ class ManufacturersController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
@@ -7,6 +7,8 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\PredefinedKitsTransformer;
|
||||
use App\Models\PredefinedKit;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
/**
|
||||
* @author [D. Minaev.] [<dmitriy.minaev.v@gmail.com>]
|
||||
@@ -18,7 +20,7 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$allowed_columns = ['id', 'name'];
|
||||
@@ -47,9 +49,8 @@ class PredefinedKitsController extends Controller
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', PredefinedKit::class);
|
||||
$kit = new PredefinedKit;
|
||||
@@ -66,9 +67,8 @@ class PredefinedKitsController extends Controller
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
@@ -81,9 +81,8 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id kit id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
@@ -100,9 +99,8 @@ class PredefinedKitsController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($id);
|
||||
@@ -123,7 +121,7 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$kits = PredefinedKit::select([
|
||||
'id',
|
||||
@@ -145,7 +143,7 @@ class PredefinedKitsController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexLicenses($kit_id)
|
||||
public function indexLicenses($kit_id) : array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -160,7 +158,7 @@ class PredefinedKitsController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeLicense(Request $request, $kit_id)
|
||||
public function storeLicense(Request $request, $kit_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
@@ -186,9 +184,8 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateLicense(Request $request, $kit_id, $license_id)
|
||||
public function updateLicense(Request $request, $kit_id, $license_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -205,9 +202,8 @@ class PredefinedKitsController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachLicense($kit_id, $license_id)
|
||||
public function detachLicense($kit_id, $license_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -221,9 +217,8 @@ class PredefinedKitsController extends Controller
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexModels($kit_id)
|
||||
public function indexModels($kit_id) : array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -236,9 +231,8 @@ class PredefinedKitsController extends Controller
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeModel(Request $request, $kit_id)
|
||||
public function storeModel(Request $request, $kit_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
@@ -252,7 +246,7 @@ class PredefinedKitsController extends Controller
|
||||
|
||||
$relation = $kit->models();
|
||||
if ($relation->find($model_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => 'Model already attached to kit']));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => trans('admin/kits/general.model_already_attached')]));
|
||||
}
|
||||
$relation->attach($model_id, ['quantity' => $quantity]);
|
||||
|
||||
@@ -264,9 +258,8 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateModel(Request $request, $kit_id, $model_id)
|
||||
public function updateModel(Request $request, $kit_id, $model_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -283,9 +276,8 @@ class PredefinedKitsController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachModel($kit_id, $model_id)
|
||||
public function detachModel($kit_id, $model_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -299,9 +291,8 @@ class PredefinedKitsController extends Controller
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexConsumables($kit_id)
|
||||
public function indexConsumables($kit_id) : array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -314,9 +305,8 @@ class PredefinedKitsController extends Controller
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeConsumable(Request $request, $kit_id)
|
||||
public function storeConsumable(Request $request, $kit_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
@@ -342,9 +332,8 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateConsumable(Request $request, $kit_id, $consumable_id)
|
||||
public function updateConsumable(Request $request, $kit_id, $consumable_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -361,9 +350,8 @@ class PredefinedKitsController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachConsumable($kit_id, $consumable_id)
|
||||
public function detachConsumable($kit_id, $consumable_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -377,9 +365,8 @@ class PredefinedKitsController extends Controller
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexAccessories($kit_id)
|
||||
public function indexAccessories($kit_id) : array
|
||||
{
|
||||
$this->authorize('view', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -392,9 +379,8 @@ class PredefinedKitsController extends Controller
|
||||
* Store the specified resource.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function storeAccessory(Request $request, $kit_id)
|
||||
public function storeAccessory(Request $request, $kit_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
|
||||
@@ -420,9 +406,8 @@ class PredefinedKitsController extends Controller
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateAccessory(Request $request, $kit_id, $accessory_id)
|
||||
public function updateAccessory(Request $request, $kit_id, $accessory_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
@@ -439,9 +424,8 @@ class PredefinedKitsController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $kit_id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function detachAccessory($kit_id, $accessory_id)
|
||||
public function detachAccessory($kit_id, $accessory_id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', PredefinedKit::class);
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
@@ -6,13 +6,13 @@ use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CheckoutRequest;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Passport\TokenRepository;
|
||||
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use App\Models\CustomField;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
@@ -42,12 +42,10 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.3.0]
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function requestedAssets()
|
||||
public function requestedAssets() : array
|
||||
{
|
||||
$checkoutRequests = CheckoutRequest::where('user_id', '=', Auth::user()->id)->get();
|
||||
$checkoutRequests = CheckoutRequest::where('user_id', '=', auth()->id())->get();
|
||||
|
||||
$results = array();
|
||||
$show_field = array();
|
||||
@@ -95,10 +93,9 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.0.5]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function createApiToken(Request $request) {
|
||||
public function createApiToken(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
if (!Gate::allows('self.api')) {
|
||||
abort(403);
|
||||
@@ -106,14 +103,14 @@ class ProfileController extends Controller
|
||||
|
||||
$accessTokenName = $request->input('name', 'Auth Token');
|
||||
|
||||
if ($accessToken = Auth::user()->createToken($accessTokenName)->accessToken) {
|
||||
if ($accessToken = auth()->user()->createToken($accessTokenName)->accessToken) {
|
||||
|
||||
// Get the ID so we can return that with the payload
|
||||
$token = DB::table('oauth_access_tokens')->where('user_id', '=', Auth::user()->id)->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first();
|
||||
$token = DB::table('oauth_access_tokens')->where('user_id', '=', auth()->id())->where('name','=',$accessTokenName)->orderBy('created_at', 'desc')->first();
|
||||
$accessTokenData['id'] = $token->id;
|
||||
$accessTokenData['token'] = $accessToken;
|
||||
$accessTokenData['name'] = $accessTokenName;
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $accessTokenData, 'Personal access token '.$accessTokenName.' created successfully'));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $accessTokenData, trans('account/general.personal_api_keys_success', ['key' => $accessTokenName])));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Token could not be created.'));
|
||||
|
||||
@@ -125,17 +122,16 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.0.5]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function deleteApiToken($tokenId) {
|
||||
public function deleteApiToken($tokenId) : Response
|
||||
{
|
||||
|
||||
if (!Gate::allows('self.api')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$token = $this->tokenRepository->findForUser(
|
||||
$tokenId, Auth::user()->getAuthIdentifier()
|
||||
$tokenId, auth()->user()->getAuthIdentifier()
|
||||
);
|
||||
|
||||
if (is_null($token)) {
|
||||
@@ -154,16 +150,15 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.0.5]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showApiTokens(Request $request) {
|
||||
public function showApiTokens() : JsonResponse
|
||||
{
|
||||
|
||||
if (!Gate::allows('self.api')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tokens = $this->tokenRepository->forUser(Auth::user()->getAuthIdentifier());
|
||||
$tokens = $this->tokenRepository->forUser(auth()->user()->getAuthIdentifier());
|
||||
$token_values = $tokens->load('client')->filter(function ($token) {
|
||||
return $token->client->personal_access_client && ! $token->revoked;
|
||||
})->values();
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ActionlogsTransformer;
|
||||
use App\Models\Actionlog;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class ReportsController extends Controller
|
||||
{
|
||||
@@ -14,9 +15,8 @@ class ReportsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
|
||||
@@ -78,15 +78,24 @@ class ReportsController extends Controller
|
||||
];
|
||||
|
||||
|
||||
$total = $actionlogs->count();
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $actionlogs->count()) ? $actionlogs->count() : app('api_offset_value');
|
||||
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$order = ($request->input('order') == 'asc') ? 'asc' : 'desc';
|
||||
$total = $actionlogs->count();
|
||||
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order)->skip($offset)->take($limit)->get();
|
||||
switch ($request->input('sort')) {
|
||||
case 'admin':
|
||||
$actionlogs->OrderAdmin($order);
|
||||
break;
|
||||
default:
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
$actionlogs = $actionlogs->skip($offset)->take($limit)->get();
|
||||
|
||||
return response()->json((new ActionlogsTransformer)->transformActionlogs($actionlogs, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
@@ -9,42 +9,38 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Ldap;
|
||||
use App\Models\Setting;
|
||||
use Mail;
|
||||
use App\Notifications\SlackTest;
|
||||
use App\Notifications\MailTest;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Http\Requests\SlackSettingsRequest;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Http\Transformers\LoginAttemptsTransformer;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function ldaptest()
|
||||
public function ldaptest() : JsonResponse
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if ($settings->ldap_enabled!='1') {
|
||||
\Log::debug('LDAP is not enabled cannot test.');
|
||||
Log::debug('LDAP is not enabled cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
\Log::debug('Preparing to test LDAP connection');
|
||||
Log::debug('Preparing to test LDAP connection');
|
||||
|
||||
$message = []; //where we collect together test messages
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
$message['bind'] = ['message' => 'Successfully bound to LDAP server.'];
|
||||
\Log::debug('attempting to bind to LDAP for LDAP test');
|
||||
Log::debug('attempting to bind to LDAP for LDAP test');
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
$message['login'] = [
|
||||
'message' => 'Successfully connected to LDAP server.',
|
||||
@@ -75,24 +71,24 @@ class SettingsController extends Controller
|
||||
|
||||
return response()->json($message, 200);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Bind failed');
|
||||
\Log::debug("Exception was: ".$e->getMessage());
|
||||
Log::debug('Bind failed');
|
||||
Log::debug("Exception was: ".$e->getMessage());
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
//return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Connection failed but we cannot debug it any further on our end.');
|
||||
Log::debug('Connection failed but we cannot debug it any further on our end.');
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ldaptestlogin(Request $request)
|
||||
public function ldaptestlogin(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
if (Setting::getSettings()->ldap_enabled != '1') {
|
||||
\Log::debug('LDAP is not enabled. Cannot test.');
|
||||
Log::debug('LDAP is not enabled. Cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
@@ -104,39 +100,39 @@ class SettingsController extends Controller
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
\Log::debug('LDAP Validation test failed.');
|
||||
Log::debug('LDAP Validation test failed.');
|
||||
$validation_errors = implode(' ',$validator->errors()->all());
|
||||
return response()->json(['message' => $validator->errors()->all()], 400);
|
||||
}
|
||||
|
||||
|
||||
|
||||
\Log::debug('Preparing to test LDAP login');
|
||||
Log::debug('Preparing to test LDAP login');
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
\Log::debug('Attempting to bind to LDAP for LDAP test');
|
||||
Log::debug('Attempting to bind to LDAP for LDAP test');
|
||||
try {
|
||||
$ldap_user = Ldap::findAndBindUserLdap($request->input('ldaptest_user'), $request->input('ldaptest_password'));
|
||||
if ($ldap_user) {
|
||||
\Log::debug('It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.');
|
||||
Log::debug('It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.');
|
||||
return response()->json(['message' => 'It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.'], 200);
|
||||
}
|
||||
return response()->json(['message' => 'Login Failed. '. $request->input('ldaptest_user').' did not successfully bind to LDAP.'], 400);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('LDAP login failed');
|
||||
Log::debug('LDAP login failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Bind failed');
|
||||
Log::debug('Bind failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
//return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Connection failed');
|
||||
Log::debug('Connection failed');
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
@@ -148,9 +144,8 @@ class SettingsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function ajaxTestEmail()
|
||||
public function ajaxTestEmail() : JsonResponse
|
||||
{
|
||||
if (!config('app.lock_passwords')) {
|
||||
try {
|
||||
@@ -170,9 +165,8 @@ class SettingsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v5.0.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function purgeBarcodes()
|
||||
public function purgeBarcodes() : JsonResponse
|
||||
{
|
||||
$file_count = 0;
|
||||
$files = Storage::disk('public')->files('barcodes');
|
||||
@@ -181,19 +175,19 @@ class SettingsController extends Controller
|
||||
|
||||
$file_parts = explode('.', $file);
|
||||
$extension = end($file_parts);
|
||||
\Log::debug($extension);
|
||||
Log::debug($extension);
|
||||
|
||||
// Only generated barcodes would have a .png file extension
|
||||
if ($extension == 'png') {
|
||||
\Log::debug('Deleting: '.$file);
|
||||
Log::debug('Deleting: '.$file);
|
||||
|
||||
|
||||
try {
|
||||
Storage::disk('public')->delete($file);
|
||||
\Log::debug('Deleting: '.$file);
|
||||
Log::debug('Deleting: '.$file);
|
||||
$file_count++;
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,9 +205,8 @@ class SettingsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v5.0.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array | JsonResponse
|
||||
*/
|
||||
public function showLoginAttempts(Request $request)
|
||||
public function showLoginAttempts(Request $request) : array
|
||||
{
|
||||
$allowed_columns = ['id', 'username', 'remote_ip', 'user_agent', 'successful', 'created_at'];
|
||||
|
||||
@@ -233,9 +226,9 @@ class SettingsController extends Controller
|
||||
* Lists backup files
|
||||
*
|
||||
* @author [A. Gianotto]
|
||||
* @return array | JsonResponse
|
||||
*/
|
||||
public function listBackups() {
|
||||
public function listBackups() : array
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
$path = 'app/backups';
|
||||
$backup_files = Storage::files($path);
|
||||
@@ -276,9 +269,9 @@ class SettingsController extends Controller
|
||||
* exhausts memory on larger files.
|
||||
*
|
||||
* @author [A. Gianotto]
|
||||
* @return JsonResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function downloadBackup($file) {
|
||||
public function downloadBackup($file) : JsonResponse | BinaryFileResponse
|
||||
{
|
||||
|
||||
$path = storage_path('app/backups');
|
||||
|
||||
@@ -296,9 +289,9 @@ class SettingsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto]
|
||||
* @since [v6.3.1]
|
||||
* @return JsonResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function downloadLatestBackup() {
|
||||
public function downloadLatestBackup() : JsonResponse | BinaryFileResponse
|
||||
{
|
||||
|
||||
$fileData = collect();
|
||||
foreach (Storage::files('app/backups') as $file) {
|
||||
|
||||
@@ -8,10 +8,11 @@ use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\StatuslabelsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Transformers\PieChartTransformer;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class StatuslabelsController extends Controller
|
||||
{
|
||||
@@ -20,9 +21,8 @@ class StatuslabelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : array
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$allowed_columns = ['id', 'name', 'created_at', 'assets_count', 'color', 'notes', 'default_label'];
|
||||
@@ -72,9 +72,8 @@ class StatuslabelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Statuslabel::class);
|
||||
$request->except('deployable', 'pending', 'archived');
|
||||
@@ -108,9 +107,8 @@ class StatuslabelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
@@ -126,9 +124,8 @@ class StatuslabelsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(Request $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
@@ -163,9 +160,8 @@ class StatuslabelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
@@ -188,13 +184,18 @@ class StatuslabelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return array
|
||||
*/
|
||||
public function getAssetCountByStatuslabel()
|
||||
public function getAssetCountByStatuslabel() : array
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$statuslabels = Statuslabel::withCount('assets')->get();
|
||||
$total = Array();
|
||||
|
||||
if (Setting::getSettings()->show_archived_in_list == 0 ) {
|
||||
$statuslabels = Statuslabel::withCount('assets')->where('archived','0')->get();
|
||||
} else {
|
||||
$statuslabels = Statuslabel::withCount('assets')->get();
|
||||
}
|
||||
|
||||
$total = [];
|
||||
|
||||
foreach ($statuslabels as $statuslabel) {
|
||||
|
||||
@@ -215,9 +216,8 @@ class StatuslabelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.0.11]
|
||||
* @return array
|
||||
*/
|
||||
public function getAssetCountByMetaStatus()
|
||||
public function getAssetCountByMetaStatus() : array
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
|
||||
@@ -245,9 +245,8 @@ class StatuslabelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function assets(Request $request, $id)
|
||||
public function assets(Request $request, $id) : array
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$this->authorize('index', Asset::class);
|
||||
@@ -281,9 +280,8 @@ class StatuslabelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return bool
|
||||
*/
|
||||
public function checkIfDeployable($id)
|
||||
public function checkIfDeployable($id) : string
|
||||
{
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
if ($statuslabel->getStatuslabelType() == 'deployable') {
|
||||
@@ -300,7 +298,7 @@ class StatuslabelsController extends Controller
|
||||
* @since [v6.1.1]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Models\Supplier;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class SuppliersController extends Controller
|
||||
{
|
||||
@@ -20,7 +21,7 @@ class SuppliersController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): array
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$allowed_columns = ['
|
||||
@@ -114,9 +115,8 @@ class SuppliersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', Supplier::class);
|
||||
$supplier = new Supplier;
|
||||
@@ -136,9 +136,8 @@ class SuppliersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : array
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$supplier = Supplier::findOrFail($id);
|
||||
@@ -154,9 +153,8 @@ class SuppliersController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $id)
|
||||
public function update(ImageUploadRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', Supplier::class);
|
||||
$supplier = Supplier::findOrFail($id);
|
||||
@@ -176,9 +174,8 @@ class SuppliersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Supplier::class);
|
||||
$supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances as asset_maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
@@ -209,7 +206,7 @@ class SuppliersController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
|
||||
$this->authorize('view.selectlists');
|
||||
|
||||
@@ -13,15 +13,18 @@ use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CurrentInventory;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Requests\DeleteUserRequest;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -31,9 +34,9 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return array
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
@@ -75,10 +78,14 @@ class UsersController extends Controller
|
||||
'users.autoassign_licenses',
|
||||
'users.website',
|
||||
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy')
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy', 'managesUsers', 'managedLocations')
|
||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count', 'managesUsers as manages_users_count', 'managedLocations as manages_locations_count');
|
||||
|
||||
|
||||
if ($request->filled('search') != '') {
|
||||
$users = $users->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
if ($request->filled('activated')) {
|
||||
$users = $users->where('users.activated', '=', $request->input('activated'));
|
||||
}
|
||||
@@ -199,8 +206,11 @@ class UsersController extends Controller
|
||||
$users->where('autoassign_licenses', '=', $request->input('autoassign_licenses'));
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->TextSearch($request->input('search'));
|
||||
|
||||
if (($request->filled('deleted')) && ($request->input('deleted') == 'true')) {
|
||||
$users = $users->onlyTrashed();
|
||||
} elseif (($request->filled('all')) && ($request->input('all') == 'true')) {
|
||||
$users = $users->withTrashed();
|
||||
}
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -238,10 +248,6 @@ class UsersController extends Controller
|
||||
'jobtitle',
|
||||
'username',
|
||||
'employee_num',
|
||||
'assets',
|
||||
'accessories',
|
||||
'consumables',
|
||||
'licenses',
|
||||
'groups',
|
||||
'activated',
|
||||
'created_at',
|
||||
@@ -252,7 +258,7 @@ class UsersController extends Controller
|
||||
'licenses_count',
|
||||
'consumables_count',
|
||||
'accessories_count',
|
||||
'manages_user_count',
|
||||
'manages_users_count',
|
||||
'manages_locations_count',
|
||||
'phone',
|
||||
'address',
|
||||
@@ -272,19 +278,11 @@ class UsersController extends Controller
|
||||
'website',
|
||||
];
|
||||
|
||||
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'first_name';
|
||||
$users = $users->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
if (($request->filled('deleted')) && ($request->input('deleted') == 'true')) {
|
||||
$users = $users->onlyTrashed();
|
||||
} elseif (($request->filled('all')) && ($request->input('all') == 'true')) {
|
||||
$users = $users->withTrashed();
|
||||
}
|
||||
|
||||
// Apply companyable scope
|
||||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
@@ -304,7 +302,7 @@ class UsersController extends Controller
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
public function selectlist(Request $request) : array
|
||||
{
|
||||
$users = User::select(
|
||||
[
|
||||
@@ -319,8 +317,6 @@ class UsersController extends Controller
|
||||
]
|
||||
)->where('show_in_list', '=', '1');
|
||||
|
||||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->where(function ($query) use ($request) {
|
||||
$query->SimpleNameSearch($request->get('search'))
|
||||
@@ -362,21 +358,20 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(SaveUserRequest $request)
|
||||
public function store(SaveUserRequest $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
|
||||
$user = new User;
|
||||
$user->fill($request->all());
|
||||
$user->created_by = Auth::user()->id;
|
||||
$user->created_by = auth()->id();
|
||||
|
||||
if ($request->has('permissions')) {
|
||||
$permissions_array = $request->input('permissions');
|
||||
|
||||
// Strip out the superuser permission if the API user isn't a superadmin
|
||||
if (! Auth::user()->isSuperUser()) {
|
||||
if (! auth()->user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
$user->permissions = $permissions_array;
|
||||
@@ -409,15 +404,12 @@ class UsersController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count', 'managesUsers as manages_users_count', 'managedLocations as manages_locations_count');
|
||||
|
||||
if ($user = Company::scopeCompanyables($user)->find($id)) {
|
||||
if ($user = User::withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count', 'managesUsers as manages_users_count', 'managedLocations as manages_locations_count')->find($id)) {
|
||||
$this->authorize('view', $user);
|
||||
return (new UsersTransformer)->transformUser($user);
|
||||
}
|
||||
@@ -434,86 +426,72 @@ class UsersController extends Controller
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(SaveUserRequest $request, $id)
|
||||
public function update(SaveUserRequest $request, User $user): JsonResponse
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
$user = User::findOrFail($id);
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('update', $user);
|
||||
$this->authorize('update', $user);
|
||||
|
||||
/**
|
||||
* This is a janky hack to prevent people from changing admin demo user data on the public demo.
|
||||
*
|
||||
* The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder.
|
||||
*
|
||||
* Thanks, jerks. You are why we can't have nice things. - snipe
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* This is a janky hack to prevent people from changing admin demo user data on the public demo.
|
||||
* The $ids 1 and 2 are special since they are seeded as superadmins in the demo seeder.
|
||||
* Thanks, jerks. You are why we can't have nice things. - snipe
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if ((($id == 1) || ($id == 2)) && (config('app.lock_passwords'))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Permission denied. You cannot update user information via API on the demo.'));
|
||||
}
|
||||
|
||||
|
||||
$user->fill($request->all());
|
||||
|
||||
if ($user->id == $request->input('manager_id')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot be your own manager'));
|
||||
}
|
||||
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
// We need to use has() instead of filled()
|
||||
// here because we need to overwrite permissions
|
||||
// if someone needs to null them out
|
||||
if ($request->has('permissions')) {
|
||||
$permissions_array = $request->input('permissions');
|
||||
|
||||
// Strip out the individual superuser permission if the API user isn't a superadmin
|
||||
if (! Auth::user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
if ((($user->id == 1) || ($user->id == 2)) && (config('app.lock_passwords'))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Permission denied. You cannot update user information via API on the demo.'));
|
||||
}
|
||||
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
$user->fill($request->all());
|
||||
|
||||
if ($user->id == $request->input('manager_id')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot be your own manager'));
|
||||
}
|
||||
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
->where('assigned_to', $user->id)->update(['location_id' => $request->input('location_id', null)]);
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
|
||||
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
|
||||
|
||||
if ($user->save()) {
|
||||
// We need to use has() instead of filled()
|
||||
// here because we need to overwrite permissions
|
||||
// if someone needs to null them out
|
||||
if ($request->has('permissions')) {
|
||||
$permissions_array = $request->input('permissions');
|
||||
|
||||
// Check if the request has groups passed and has a value, AND that the user us a superuser
|
||||
if (($request->has('groups')) && (Auth::user()->isSuperUser())) {
|
||||
|
||||
$validator = Validator::make($request->only('groups'), [
|
||||
'groups.*' => 'integer|exists:permission_groups,id',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()));
|
||||
// Strip out the individual superuser permission if the API user isn't a superadmin
|
||||
if (!auth()->user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
|
||||
// Sync the groups since the user is a superuser and the groups pass validation
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
|
||||
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update')));
|
||||
}
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
->where('assigned_to', $user->id)->update(['location_id' => $request->input('location_id', null)]);
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
|
||||
|
||||
if ($user->save()) {
|
||||
// Check if the request has groups passed and has a value, AND that the user us a superuser
|
||||
if (($request->has('groups')) && (auth()->user()->isSuperUser())) {
|
||||
|
||||
$validator = Validator::make($request->only('groups'), [
|
||||
'groups.*' => 'integer|exists:permission_groups,id',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()));
|
||||
}
|
||||
|
||||
// Sync the groups since the user is a superuser and the groups pass validation
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,34 +500,14 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
public function destroy(DeleteUserRequest $request, $id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', User::class);
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if ($user) {
|
||||
if ($user = User::withTrashed()->find($id)) {
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if (($user->assets) && ($user->assets->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
|
||||
}
|
||||
|
||||
if (($user->licenses) && ($user->licenses->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->licenses->count() . ' license(s) associated with them and cannot be deleted.'));
|
||||
}
|
||||
|
||||
if (($user->accessories) && ($user->accessories->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->accessories->count() . ' accessories associated with them.'));
|
||||
}
|
||||
|
||||
if (($user->managedLocations()) && ($user->managedLocations()->count() > 0)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.'));
|
||||
}
|
||||
|
||||
if ($user->delete()) {
|
||||
|
||||
@@ -558,15 +516,19 @@ class UsersController extends Controller
|
||||
try {
|
||||
Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug($e);
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -575,39 +537,41 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function assets(Request $request, $id)
|
||||
public function assets(Request $request, $id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed();
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('view', $user);
|
||||
if ($user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($id)) {
|
||||
$this->authorize('view', $user);
|
||||
|
||||
$assets = Asset::where('assigned_to', '=', $id)->where('assigned_type', '=', User::class)->with('model');
|
||||
$assets = Asset::where('assigned_to', '=', $id)->where('assigned_type', '=', User::class)->with('model');
|
||||
|
||||
|
||||
// Filter on category ID
|
||||
if ($request->filled('category_id')) {
|
||||
$assets = $assets->InCategory($request->input('category_id'));
|
||||
}
|
||||
|
||||
|
||||
// Filter on model ID
|
||||
if ($request->filled('model_id')) {
|
||||
|
||||
$model_ids = $request->input('model_id');
|
||||
if (!is_array($model_ids)) {
|
||||
$model_ids = array($model_ids);
|
||||
// Filter on category ID
|
||||
if ($request->filled('category_id')) {
|
||||
$assets = $assets->InCategory($request->input('category_id'));
|
||||
}
|
||||
$assets = $assets->InModelList($model_ids);
|
||||
|
||||
|
||||
// Filter on model ID
|
||||
if ($request->filled('model_id')) {
|
||||
|
||||
$model_ids = $request->input('model_id');
|
||||
if (!is_array($model_ids)) {
|
||||
$model_ids = array($model_ids);
|
||||
}
|
||||
$assets = $assets->InModelList($model_ids);
|
||||
}
|
||||
|
||||
$assets = $assets->get();
|
||||
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
$assets = $assets->get();
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found', compact('id'))));
|
||||
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,22 +581,26 @@ class UsersController extends Controller
|
||||
* @since [v6.0.13]
|
||||
* @param Request $request
|
||||
* @param $id
|
||||
* @return string JSON
|
||||
*/
|
||||
public function emailAssetList(Request $request, $id)
|
||||
public function emailAssetList(Request $request, $id) : JsonResponse
|
||||
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$user = Company::scopeCompanyables($user)->find($id);
|
||||
$this->authorize('update', $user);
|
||||
|
||||
if (empty($user->email)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.inventorynotification.error')));
|
||||
if ($user = User::find($id)) {
|
||||
$this->authorize('update', $user);
|
||||
|
||||
if (empty($user->email)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.inventorynotification.error')));
|
||||
}
|
||||
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.inventorynotification.success')));
|
||||
}
|
||||
|
||||
$user->notify((new CurrentInventory($user)));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found', compact('id'))));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.inventorynotification.success')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,14 +609,13 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function consumables(Request $request, $id)
|
||||
public function consumables(Request $request, $id) : array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', Consumable::class);
|
||||
$user = User::findOrFail($id);
|
||||
$this->authorize('update', $user);
|
||||
$this->authorize('view', $user);
|
||||
$consumables = $user->consumables;
|
||||
return (new ConsumablesTransformer)->transformConsumables($consumables, $consumables->count(), $request);
|
||||
}
|
||||
@@ -659,9 +626,8 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.6.14]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function accessories($id)
|
||||
public function accessories($id) : array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
@@ -678,9 +644,8 @@ class UsersController extends Controller
|
||||
* @author [N. Mathar] [<snipe@snipe.net>]
|
||||
* @since [v5.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function licenses($id)
|
||||
public function licenses($id) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$this->authorize('view', License::class);
|
||||
@@ -701,9 +666,8 @@ class UsersController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function postTwoFactorReset(Request $request)
|
||||
public function postTwoFactorReset(Request $request) : JsonResponse
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
@@ -722,7 +686,7 @@ class UsersController extends Controller
|
||||
$logaction->item_type = User::class;
|
||||
$logaction->item_id = $user->id;
|
||||
$logaction->created_at = date('Y-m-d H:i:s');
|
||||
$logaction->user_id = Auth::user()->id;
|
||||
$logaction->user_id = auth()->id();
|
||||
$logaction->logaction('2FA reset');
|
||||
|
||||
return response()->json(['message' => trans('admin/settings/general.two_factor_reset_success')], 200);
|
||||
@@ -741,9 +705,8 @@ class UsersController extends Controller
|
||||
* @author [Juan Font] [<juanfontalonso@gmail.com>]
|
||||
* @since [v4.4.2]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getCurrentUserInfo(Request $request)
|
||||
public function getCurrentUserInfo(Request $request) : array
|
||||
{
|
||||
return (new UsersTransformer)->transformUser($request->user());
|
||||
}
|
||||
@@ -754,12 +717,13 @@ class UsersController extends Controller
|
||||
* @author [E. Taylor] [<dev@evantaylor.name>]
|
||||
* @param int $userId
|
||||
* @since [v6.0.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function restore($userId = null)
|
||||
public function restore($userId) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', User::class);
|
||||
|
||||
if ($user = User::withTrashed()->find($userId)) {
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if ($user->deleted_at == '') {
|
||||
@@ -772,14 +736,12 @@ class UsersController extends Controller
|
||||
$logaction->item_type = User::class;
|
||||
$logaction->item_id = $user->id;
|
||||
$logaction->created_at = date('Y-m-d H:i:s');
|
||||
$logaction->user_id = Auth::user()->id;
|
||||
$logaction->user_id = auth()->id();
|
||||
$logaction->logaction('restore');
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.restored')), 200);
|
||||
}
|
||||
|
||||
// Check validation to make sure we're not restoring a user with the same username as an existing user
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')), 200);
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Company;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Slack;
|
||||
use Str;
|
||||
use TCPDF;
|
||||
use View;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Asset Maintenance for
|
||||
@@ -29,9 +26,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
private static function getInsufficientPermissionsRedirect()
|
||||
private static function getInsufficientPermissionsRedirect(): RedirectResponse
|
||||
{
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('error', trans('general.insufficient_permissions'));
|
||||
@@ -46,9 +42,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
public function index() : View
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
return view('asset_maintenances/index');
|
||||
@@ -63,7 +58,7 @@ class AssetMaintenancesController extends Controller
|
||||
* @since [v1.8]
|
||||
* @return mixed
|
||||
*/
|
||||
public function create()
|
||||
public function create() : View
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$asset = null;
|
||||
@@ -92,9 +87,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return mixed
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// create a new model instance
|
||||
@@ -144,9 +138,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return mixed
|
||||
*/
|
||||
public function edit($assetMaintenanceId = null)
|
||||
public function edit($assetMaintenanceId = null) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
@@ -162,14 +155,9 @@ class AssetMaintenancesController extends Controller
|
||||
return static::getInsufficientPermissionsRedirect();
|
||||
}
|
||||
|
||||
|
||||
// Prepare Improvement Type List
|
||||
$assetMaintenanceType = [
|
||||
'' => 'Select an improvement type',
|
||||
] + AssetMaintenance::getImprovementOptions();
|
||||
$assetMaintenanceType = ['' => 'Select an improvement type'] + AssetMaintenance::getImprovementOptions();
|
||||
|
||||
// Get Supplier List
|
||||
// Render the view
|
||||
return view('asset_maintenances/edit')
|
||||
->with('selectedAsset', null)
|
||||
->with('assetMaintenanceType', $assetMaintenanceType)
|
||||
@@ -183,11 +171,10 @@ class AssetMaintenancesController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @param Request $request
|
||||
* @param int $assetMaintenanceId
|
||||
* @return mixed
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
public function update(Request $request, $assetMaintenanceId = null) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
@@ -255,9 +242,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
public function destroy($assetMaintenanceId) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
@@ -284,9 +270,8 @@ class AssetMaintenancesController extends Controller
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
public function show($assetMaintenanceId) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
|
||||
@@ -4,20 +4,21 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Requests\StoreAssetModelRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\SnipeModel;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Redirect;
|
||||
use Request;
|
||||
use Storage;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls all actions related to asset models for
|
||||
@@ -34,10 +35,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
public function index() : View
|
||||
{
|
||||
$this->authorize('index', AssetModel::class);
|
||||
|
||||
@@ -49,10 +48,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
public function create() : View
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
|
||||
@@ -67,16 +64,12 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(StoreAssetModelRequest $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
// Create a new asset model
|
||||
$model = new AssetModel;
|
||||
|
||||
// Save the model data
|
||||
$model->eol = $request->input('eol');
|
||||
$model->depreciation_id = $request->input('depreciation_id');
|
||||
$model->name = $request->input('name');
|
||||
@@ -86,7 +79,7 @@ class AssetModelsController extends Controller
|
||||
$model->category_id = $request->input('category_id');
|
||||
$model->notes = $request->input('notes');
|
||||
$model->user_id = Auth::id();
|
||||
$model->requestable = Request::has('requestable');
|
||||
$model->requestable = $request->has('requestable');
|
||||
|
||||
if ($request->input('fieldset_id') != '') {
|
||||
$model->fieldset_id = $request->input('fieldset_id');
|
||||
@@ -94,7 +87,6 @@ class AssetModelsController extends Controller
|
||||
|
||||
$model = $request->handleImages($model);
|
||||
|
||||
// Was it created?
|
||||
if ($model->save()) {
|
||||
if ($this->shouldAddDefaultValues($request->input())) {
|
||||
if (!$this->assignCustomFieldsDefaultValues($model, $request->input('default_values'))){
|
||||
@@ -114,18 +106,14 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($modelId = null)
|
||||
public function edit($modelId = null) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
if ($item = AssetModel::find($modelId)) {
|
||||
$category_type = 'asset';
|
||||
$view = View::make('models/edit', compact('item', 'category_type'));
|
||||
$view->with('depreciation_list', Helper::depreciationList());
|
||||
return view('models/edit', compact('item', 'category_type'))->with('depreciation_list', Helper::depreciationList());
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
@@ -140,15 +128,14 @@ class AssetModelsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $modelId = null)
|
||||
public function update(StoreAssetModelRequest $request, $modelId) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
// Check if the model exists
|
||||
|
||||
if (is_null($model = AssetModel::find($modelId))) {
|
||||
// Redirect to the models management page
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
}
|
||||
|
||||
@@ -164,20 +151,17 @@ class AssetModelsController extends Controller
|
||||
$model->notes = $request->input('notes');
|
||||
$model->requestable = $request->input('requestable', '0');
|
||||
|
||||
$this->removeCustomFieldsDefaultValues($model);
|
||||
|
||||
$model->fieldset_id = $request->input('fieldset_id');
|
||||
|
||||
if ($this->shouldAddDefaultValues($request->input())) {
|
||||
if (!$this->assignCustomFieldsDefaultValues($model, $request->input('default_values'))){
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.fieldset_default_value.error'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ($model->save()) {
|
||||
$this->removeCustomFieldsDefaultValues($model);
|
||||
|
||||
if ($this->shouldAddDefaultValues($request->input())) {
|
||||
if (!$this->assignCustomFieldsDefaultValues($model, $request->input('default_values'))) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.fieldset_default_value.error'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($model->wasChanged('eol')) {
|
||||
if ($model->eol > 0) {
|
||||
$newEol = $model->eol;
|
||||
@@ -201,10 +185,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($modelId)
|
||||
public function destroy($modelId) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
// Check if the model exists
|
||||
@@ -220,8 +202,9 @@ class AssetModelsController extends Controller
|
||||
if ($model->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('models/'.$model->image);
|
||||
$model->update(['image' => null]);
|
||||
} catch (\Exception $e) {
|
||||
\Log::info($e);
|
||||
Log::info($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,10 +221,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $id
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function getRestore($id)
|
||||
public function getRestore($id) : RedirectResponse
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
|
||||
@@ -253,10 +234,10 @@ class AssetModelsController extends Controller
|
||||
|
||||
if ($model->restore()) {
|
||||
$logaction = new Actionlog();
|
||||
$logaction->item_type = User::class;
|
||||
$logaction->item_type = AssetModel::class;
|
||||
$logaction->item_id = $model->id;
|
||||
$logaction->created_at = date('Y-m-d H:i:s');
|
||||
$logaction->user_id = Auth::user()->id;
|
||||
$logaction->user_id = auth()->id();
|
||||
$logaction->logaction('restore');
|
||||
|
||||
|
||||
@@ -283,13 +264,11 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($modelId = null)
|
||||
public function show($modelId = null) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
$model = AssetModel::withTrashed()->withCount('assets')->find($modelId);
|
||||
$model = AssetModel::withTrashed()->find($modelId);
|
||||
|
||||
if (isset($model->id)) {
|
||||
return view('models/view', compact('model'));
|
||||
@@ -304,9 +283,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
public function getClone($modelId = null)
|
||||
public function getClone($modelId = null) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('create', AssetModel::class);
|
||||
// Check if the model exists
|
||||
@@ -332,9 +310,8 @@ class AssetModelsController extends Controller
|
||||
* @author [B. Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v2.0]
|
||||
* @param int $modelId
|
||||
* @return View
|
||||
*/
|
||||
public function getCustomFields($modelId)
|
||||
public function getCustomFields($modelId) : View
|
||||
{
|
||||
return view('models.custom_fields_form')->with('model', AssetModel::find($modelId));
|
||||
}
|
||||
@@ -346,9 +323,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function postBulkEdit(Request $request)
|
||||
public function postBulkEdit(Request $request) : View | RedirectResponse
|
||||
{
|
||||
$models_raw_array = $request->input('ids');
|
||||
|
||||
@@ -390,9 +366,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function postBulkEditSave(Request $request)
|
||||
public function postBulkEditSave(Request $request) : RedirectResponse
|
||||
{
|
||||
$models_raw_array = $request->input('ids');
|
||||
$update_array = [];
|
||||
@@ -430,9 +405,8 @@ class AssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postBulkDelete(Request $request)
|
||||
public function postBulkDelete(Request $request) : RedirectResponse
|
||||
{
|
||||
$models_raw_array = $request->input('ids');
|
||||
|
||||
@@ -471,9 +445,8 @@ class AssetModelsController extends Controller
|
||||
* any default values were entered into the form.
|
||||
*
|
||||
* @param array $input
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldAddDefaultValues(array $input)
|
||||
private function shouldAddDefaultValues(array $input) : bool
|
||||
{
|
||||
return ! empty($input['add_default_values'])
|
||||
&& ! empty($input['default_values'])
|
||||
@@ -485,9 +458,8 @@ class AssetModelsController extends Controller
|
||||
*
|
||||
* @param AssetModel $model
|
||||
* @param array $defaultValues
|
||||
* @return void
|
||||
*/
|
||||
private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues): bool
|
||||
private function assignCustomFieldsDefaultValues(AssetModel|SnipeModel $model, array $defaultValues): bool
|
||||
{
|
||||
$data = array();
|
||||
foreach ($defaultValues as $customFieldId => $defaultValue) {
|
||||
@@ -496,17 +468,17 @@ class AssetModelsController extends Controller
|
||||
$data[$customField->db_column] = $defaultValue;
|
||||
}
|
||||
|
||||
$fieldsets = $model->fieldset->validation_rules();
|
||||
$allRules = $model->fieldset->validation_rules();
|
||||
$rules = array();
|
||||
|
||||
foreach ($fieldsets as $fieldset => $validation){
|
||||
foreach ($allRules as $field => $validation) {
|
||||
// If the field is marked as required, eliminate the rule so it doesn't interfere with the default values
|
||||
// (we are at model level, the rule still applies when creating a new asset using this model)
|
||||
$index = array_search('required', $validation);
|
||||
if ($index !== false){
|
||||
$validation[$index] = 'nullable';
|
||||
}
|
||||
$rules[$fieldset] = $validation;
|
||||
$rules[$field] = $validation;
|
||||
}
|
||||
|
||||
$validator = Validator::make($data, $rules);
|
||||
@@ -528,9 +500,8 @@ class AssetModelsController extends Controller
|
||||
/**
|
||||
* Removes all default values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeCustomFieldsDefaultValues(AssetModel $model)
|
||||
private function removeCustomFieldsDefaultValues(AssetModel|SnipeModel $model): void
|
||||
{
|
||||
$model->defaultValues()->detach();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ use App\Helpers\StorageHelper;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class AssetModelsFilesController extends Controller
|
||||
{
|
||||
@@ -16,12 +19,12 @@ class AssetModelsFilesController extends Controller
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $modelId = null)
|
||||
public function store(UploadFileRequest $request, $modelId = null) : RedirectResponse
|
||||
{
|
||||
if (! $model = AssetModel::find($modelId)) {
|
||||
return redirect()->route('models.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
@@ -54,10 +57,8 @@ class AssetModelsFilesController extends Controller
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($modelId = null, $fileId = null)
|
||||
public function show($modelId = null, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse
|
||||
{
|
||||
$model = AssetModel::find($modelId);
|
||||
// the asset is valid
|
||||
@@ -101,10 +102,8 @@ class AssetModelsFilesController extends Controller
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($modelId = null, $fileId = null)
|
||||
public function destroy($modelId = null, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$model = AssetModel::find($modelId);
|
||||
$this->authorize('update', $model);
|
||||
|
||||
@@ -11,9 +11,9 @@ use App\Models\Asset;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
class AssetCheckinController extends Controller
|
||||
{
|
||||
@@ -25,11 +25,9 @@ class AssetCheckinController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param string $backto
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function create($assetId, $backto = null)
|
||||
public function create($assetId, $backto = null) : View | RedirectResponse
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset = Asset::find($assetId))) {
|
||||
@@ -45,7 +43,11 @@ class AssetCheckinController extends Controller
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in'));
|
||||
}
|
||||
|
||||
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
|
||||
if (!$asset->model) {
|
||||
return redirect()->route('hardware.show', $asset->id)->with('error', trans('admin/hardware/general.model_invalid_fix'));
|
||||
}
|
||||
|
||||
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto)->with('table_name', 'Assets');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,11 +57,9 @@ class AssetCheckinController extends Controller
|
||||
* @param AssetCheckinRequest $request
|
||||
* @param int $assetId
|
||||
* @param null $backto
|
||||
* @return Redirect
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function store(AssetCheckinRequest $request, $assetId = null, $backto = null)
|
||||
public function store(AssetCheckinRequest $request, $assetId = null, $backto = null) : RedirectResponse
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset = Asset::find($assetId))) {
|
||||
@@ -70,6 +70,11 @@ class AssetCheckinController extends Controller
|
||||
if (is_null($target = $asset->assignedTo)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in'));
|
||||
}
|
||||
|
||||
if (!$asset->model) {
|
||||
return redirect()->route('hardware.show', $asset->id)->with('error', trans('admin/hardware/general.model_invalid_fix'));
|
||||
}
|
||||
|
||||
$this->authorize('checkin', $asset);
|
||||
|
||||
if ($asset->assignedType() == Asset::USER) {
|
||||
@@ -77,7 +82,6 @@ class AssetCheckinController extends Controller
|
||||
}
|
||||
|
||||
$asset->expected_checkin = null;
|
||||
//$asset->last_checkout = null;
|
||||
$asset->last_checkin = now();
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->accepted = null;
|
||||
@@ -92,7 +96,7 @@ class AssetCheckinController extends Controller
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if ($request->filled('location_id')) {
|
||||
\Log::debug('NEW Location ID: '.$request->get('location_id'));
|
||||
Log::debug('NEW Location ID: '.$request->get('location_id'));
|
||||
$asset->location_id = $request->get('location_id');
|
||||
|
||||
if ($request->get('update_default_location') == 0){
|
||||
@@ -122,15 +126,12 @@ class AssetCheckinController extends Controller
|
||||
$acceptance->delete();
|
||||
});
|
||||
|
||||
// Was the asset updated?
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
|
||||
if ($asset->save()) {
|
||||
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at, $originalValues));
|
||||
|
||||
if ((isset($user)) && ($backto == 'user')) {
|
||||
return redirect()->route('users.show', $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.error').$asset->getErrors());
|
||||
|
||||
@@ -9,7 +9,9 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
||||
class AssetCheckoutController extends Controller
|
||||
{
|
||||
@@ -22,9 +24,9 @@ class AssetCheckoutController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create($assetId)
|
||||
public function create($assetId) : View | RedirectResponse
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset = Asset::with('company')->find(e($assetId)))) {
|
||||
@@ -33,11 +35,17 @@ class AssetCheckoutController extends Controller
|
||||
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
if (!$asset->model) {
|
||||
return redirect()->route('hardware.show', $asset->id)->with('error', trans('admin/hardware/general.model_invalid_fix'));
|
||||
}
|
||||
|
||||
if ($asset->availableForCheckout()) {
|
||||
return view('hardware/checkout', compact('asset'))
|
||||
->with('statusLabel_list', Helper::deployableStatusLabelList());
|
||||
->with('statusLabel_list', Helper::deployableStatusLabelList())
|
||||
->with('table_name', 'Assets');
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available'));
|
||||
}
|
||||
|
||||
@@ -46,11 +54,9 @@ class AssetCheckoutController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param AssetCheckoutRequest $request
|
||||
* @param int $assetId
|
||||
* @return Redirect
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function store(AssetCheckoutRequest $request, $assetId)
|
||||
public function store(AssetCheckoutRequest $request, $assetId) : RedirectResponse
|
||||
{
|
||||
try {
|
||||
// Check if the asset exists
|
||||
@@ -60,7 +66,12 @@ class AssetCheckoutController extends Controller
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available'));
|
||||
}
|
||||
$this->authorize('checkout', $asset);
|
||||
$admin = Auth::user();
|
||||
|
||||
if (!$asset->model) {
|
||||
return redirect()->route('hardware.show', $asset->id)->with('error', trans('admin/hardware/general.model_invalid_fix'));
|
||||
}
|
||||
|
||||
$admin = auth()->user();
|
||||
|
||||
$target = $this->determineCheckoutTarget();
|
||||
|
||||
@@ -97,11 +108,13 @@ class AssetCheckoutController extends Controller
|
||||
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('general.error_user_company'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) {
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) {
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))
|
||||
->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('admin/hardware/message.checkout.error').$asset->getErrors());
|
||||
} catch (ModelNotFoundException $e) {
|
||||
|
||||
@@ -7,8 +7,12 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use \Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class AssetFilesController extends Controller
|
||||
{
|
||||
@@ -17,12 +21,12 @@ class AssetFilesController extends Controller
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $assetId
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $assetId = null)
|
||||
public function store(UploadFileRequest $request, $assetId = null) : RedirectResponse
|
||||
{
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
@@ -54,10 +58,8 @@ class AssetFilesController extends Controller
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($assetId = null, $fileId = null)
|
||||
public function show($assetId = null, $fileId = null) : View | RedirectResponse | Response | StreamedResponse | BinaryFileResponse
|
||||
{
|
||||
$asset = Asset::find($assetId);
|
||||
// the asset is valid
|
||||
@@ -105,10 +107,8 @@ class AssetFilesController extends Controller
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($assetId = null, $fileId = null)
|
||||
public function destroy($assetId = null, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$asset = Asset::find($assetId);
|
||||
$this->authorize('update', $asset);
|
||||
@@ -131,7 +131,6 @@ class AssetFilesController extends Controller
|
||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,14 +20,16 @@ use Illuminate\Support\Facades\Auth;
|
||||
use App\View\Label;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use League\Csv\Reader;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to assets for
|
||||
@@ -55,10 +57,8 @@ class AssetsController extends Controller
|
||||
* @see AssetController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @param Request $request
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request) : View
|
||||
{
|
||||
$this->authorize('index', Asset::class);
|
||||
$company = Company::find($request->input('company_id'));
|
||||
@@ -72,13 +72,12 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param Request $request
|
||||
* @return View
|
||||
* @internal param int $model_id
|
||||
*/
|
||||
public function create(Request $request)
|
||||
public function create(Request $request) : View
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
$view = View::make('hardware/edit')
|
||||
$view = view('hardware/edit')
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('item', new Asset)
|
||||
->with('statuslabel_types', Helper::statusTypeList());
|
||||
@@ -96,9 +95,8 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize(Asset::class);
|
||||
|
||||
@@ -167,7 +165,7 @@ class AssetsController extends Controller
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||
if (is_array($request->input($field->db_column))) {
|
||||
$asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column)));
|
||||
} else {
|
||||
@@ -198,7 +196,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->get('name'), $location);
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->get('name'), $location);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
@@ -206,10 +204,13 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
|
||||
if ($success) {
|
||||
\Log::debug(e($asset->asset_tag));
|
||||
return redirect()->route('hardware.index')
|
||||
->with('success-unescaped', trans('admin/hardware/message.create.success_linked', ['link' => route('hardware.show', $asset->id), 'id', 'tag' => e($asset->asset_tag)]));
|
||||
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))
|
||||
->with('success-unescaped', trans('admin/hardware/message.create.success_linked', ['link' => route('hardware.show', ['hardware' => $asset->id]), 'id', 'tag' => e($asset->asset_tag)]));
|
||||
|
||||
|
||||
}
|
||||
@@ -217,11 +218,6 @@ class AssetsController extends Controller
|
||||
return redirect()->back()->withInput()->withErrors($asset->getErrors());
|
||||
}
|
||||
|
||||
public function getOptionCookie(Request $request){
|
||||
$value = $request->cookie('optional_info');
|
||||
echo $value;
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that presents a form to edit an existing asset.
|
||||
@@ -229,9 +225,9 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit($assetId = null)
|
||||
public function edit($assetId = null) : View | RedirectResponse
|
||||
{
|
||||
if (! $item = Asset::find($assetId)) {
|
||||
// Redirect to the asset management page with error
|
||||
@@ -252,9 +248,9 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($assetId = null)
|
||||
public function show($assetId = null) : View | RedirectResponse
|
||||
{
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$this->authorize('view', $asset);
|
||||
@@ -292,12 +288,12 @@ class AssetsController extends Controller
|
||||
* Validate and process asset edit form.
|
||||
*
|
||||
* @param int $assetId
|
||||
* @return \Illuminate\Http\RedirectResponse|Redirect
|
||||
* @since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $assetId = null)
|
||||
public function update(ImageUploadRequest $request, $assetId = null) : RedirectResponse
|
||||
{
|
||||
|
||||
// Check if the asset exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
// Redirect to the asset management page with error
|
||||
@@ -340,7 +336,7 @@ class AssetsController extends Controller
|
||||
|
||||
$status = Statuslabel::find($asset->status_id);
|
||||
|
||||
if($status->archived){
|
||||
if ($status && $status->archived) {
|
||||
$asset->assigned_to = null;
|
||||
}
|
||||
|
||||
@@ -359,14 +355,26 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
// Update the asset data
|
||||
$asset_tag = $request->input('asset_tags');
|
||||
|
||||
$serial = $request->input('serials');
|
||||
$asset->serial = $request->input('serials');
|
||||
|
||||
if (is_array($request->input('serials'))) {
|
||||
$asset->serial = $serial[1];
|
||||
}
|
||||
|
||||
$asset->name = $request->input('name');
|
||||
$asset->serial = $serial[1];
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->asset_tag = $asset_tag[1];
|
||||
|
||||
$asset_tags = $request->input('asset_tags');
|
||||
$asset->asset_tag = $request->input('asset_tags');
|
||||
|
||||
if (is_array($request->input('asset_tags'))) {
|
||||
$asset->asset_tag = $asset_tags[1];
|
||||
}
|
||||
|
||||
$asset->notes = $request->input('notes');
|
||||
|
||||
$asset = $request->handleImages($asset);
|
||||
@@ -378,8 +386,9 @@ class AssetsController extends Controller
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||
if (is_array($request->input($field->db_column))) {
|
||||
$asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column)));
|
||||
} else {
|
||||
@@ -396,9 +405,10 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
if ($asset->save()) {
|
||||
return redirect()->route('hardware.show', $assetId)
|
||||
return redirect()->to(Helper::getRedirectOption($request, $assetId, 'Assets'))
|
||||
->with('success', trans('admin/hardware/message.update.success'));
|
||||
}
|
||||
|
||||
@@ -411,9 +421,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy($assetId)
|
||||
public function destroy($assetId) : RedirectResponse
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset = Asset::find($assetId))) {
|
||||
@@ -445,9 +454,8 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function getAssetBySerial(Request $request)
|
||||
public function getAssetBySerial(Request $request) : RedirectResponse
|
||||
{
|
||||
$topsearch = ($request->get('topsearch')=="true");
|
||||
|
||||
@@ -463,16 +471,23 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function getAssetByTag(Request $request, $tag=null)
|
||||
public function getAssetByTag(Request $request, $tag=null) : RedirectResponse
|
||||
{
|
||||
$tag = $tag ? $tag : $request->get('assetTag');
|
||||
$topsearch = ($request->get('topsearch') == 'true');
|
||||
|
||||
if (! $asset = Asset::where('asset_tag', '=', $tag)->first()) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
// Search for an exact and unique asset tag match
|
||||
$assets = Asset::where('asset_tag', '=', $tag);
|
||||
|
||||
// If not a unique result, redirect to the index view
|
||||
if ($assets->count() != 1) {
|
||||
return redirect()->route('hardware.index')
|
||||
->with('search', $tag)
|
||||
->with('warning', trans('admin/hardware/message.does_not_exist_var', [ 'asset_tag' => $tag ]));
|
||||
}
|
||||
$asset = $assets->first();
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
@@ -485,9 +500,8 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return Response
|
||||
*/
|
||||
public function getQrCode($assetId = null)
|
||||
public function getQrCode($assetId = null) : Response | BinaryFileResponse | string | bool
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
@@ -514,6 +528,7 @@ class AssetsController extends Controller
|
||||
|
||||
return 'That asset is invalid';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -561,7 +576,7 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [L. Swartzendruber] [<logan.swartzendruber@gmail.com>
|
||||
* @param int $assetId
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getLabel($assetId = null)
|
||||
{
|
||||
@@ -585,28 +600,22 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getClone($assetId = null)
|
||||
public function getClone(Asset $asset)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset_to_clone = Asset::find($assetId))) {
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('create', $asset_to_clone);
|
||||
|
||||
$asset = clone $asset_to_clone;
|
||||
$asset->id = null;
|
||||
$asset->asset_tag = '';
|
||||
$asset->serial = '';
|
||||
$asset->assigned_to = '';
|
||||
$this->authorize('create', $asset);
|
||||
$cloned = clone $asset;
|
||||
$cloned->id = null;
|
||||
$cloned->asset_tag = '';
|
||||
$cloned->serial = '';
|
||||
$cloned->assigned_to = '';
|
||||
$cloned->deleted_at = '';
|
||||
|
||||
return view('hardware/edit')
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->with('item', $asset);
|
||||
->with('item', $cloned);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -614,7 +623,7 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getImportHistory()
|
||||
{
|
||||
@@ -636,7 +645,7 @@ class AssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.3]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function postImportHistory(Request $request)
|
||||
{
|
||||
@@ -730,8 +739,8 @@ class AssetsController extends Controller
|
||||
Actionlog::firstOrCreate([
|
||||
'item_id' => $asset->id,
|
||||
'item_type' => Asset::class,
|
||||
'user_id' => Auth::user()->id,
|
||||
'note' => 'Checkout imported by '.Auth::user()->present()->fullName().' from history importer',
|
||||
'user_id' => auth()->id(),
|
||||
'note' => 'Checkout imported by '.auth()->user()->present()->fullName().' from history importer',
|
||||
'target_id' => $item[$asset_tag][$batch_counter]['user_id'],
|
||||
'target_type' => User::class,
|
||||
'created_at' => $item[$asset_tag][$batch_counter]['checkout_date'],
|
||||
@@ -758,8 +767,8 @@ class AssetsController extends Controller
|
||||
Actionlog::firstOrCreate([
|
||||
'item_id' => $item[$asset_tag][$batch_counter]['asset_id'],
|
||||
'item_type' => Asset::class,
|
||||
'user_id' => Auth::user()->id,
|
||||
'note' => 'Checkin imported by '.Auth::user()->present()->fullName().' from history importer',
|
||||
'user_id' => auth()->id(),
|
||||
'note' => 'Checkin imported by '.auth()->user()->present()->fullName().' from history importer',
|
||||
'target_id' => null,
|
||||
'created_at' => $checkin_date,
|
||||
'action_type' => 'checkin',
|
||||
@@ -796,7 +805,7 @@ class AssetsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getRestore($assetId = null)
|
||||
{
|
||||
@@ -835,7 +844,7 @@ class AssetsController extends Controller
|
||||
{
|
||||
$this->authorize('checkin', Asset::class);
|
||||
|
||||
return view('hardware/quickscan-checkin');
|
||||
return view('hardware/quickscan-checkin')->with('statusLabel_list', Helper::statusLabelList());
|
||||
}
|
||||
|
||||
public function audit($id)
|
||||
@@ -905,7 +914,7 @@ class AssetsController extends Controller
|
||||
if ($request->input('update_location') == '1') {
|
||||
$asset->location_id = $request->input('location_id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Invoke Watson Validating to check the asset itself and check to make sure it saved correctly.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Models\Actionlog;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
@@ -12,14 +11,15 @@ use App\Models\Statuslabel;
|
||||
use App\Models\Setting;
|
||||
use App\View\Label;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
class BulkAssetsController extends Controller
|
||||
{
|
||||
@@ -36,12 +36,10 @@ class BulkAssetsController extends Controller
|
||||
* action would make a lot more sense here and make things a lot more clear.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return View
|
||||
* @internal param int $assetId
|
||||
* @since [v2.0]
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
public function edit(Request $request) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
@@ -94,7 +92,9 @@ class BulkAssetsController extends Controller
|
||||
// This handles all of the pivot sorting below (versus the assets.* fields in the allowed_columns array)
|
||||
$column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'assets.id';
|
||||
|
||||
$assets = Asset::with('assignedTo', 'location', 'model')->whereIn('assets.id', $asset_ids);
|
||||
$assets = Asset::with('assignedTo', 'location', 'model')
|
||||
->whereIn('assets.id', $asset_ids)
|
||||
->withTrashed();
|
||||
|
||||
$assets = $assets->get();
|
||||
|
||||
@@ -194,7 +194,7 @@ class BulkAssetsController extends Controller
|
||||
* @internal param array $assets
|
||||
* @since [v2.0]
|
||||
*/
|
||||
public function update(Request $request)
|
||||
public function update(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$has_errors = 0;
|
||||
@@ -227,7 +227,8 @@ class BulkAssetsController extends Controller
|
||||
* its checkout status.
|
||||
*/
|
||||
|
||||
if (($request->filled('purchase_date'))
|
||||
if (($request->filled('name'))
|
||||
|| ($request->filled('purchase_date'))
|
||||
|| ($request->filled('expected_checkin'))
|
||||
|| ($request->filled('purchase_cost'))
|
||||
|| ($request->filled('supplier_id'))
|
||||
@@ -239,6 +240,7 @@ class BulkAssetsController extends Controller
|
||||
|| ($request->filled('status_id'))
|
||||
|| ($request->filled('model_id'))
|
||||
|| ($request->filled('next_audit_date'))
|
||||
|| ($request->filled('null_name'))
|
||||
|| ($request->filled('null_purchase_date'))
|
||||
|| ($request->filled('null_expected_checkin_date'))
|
||||
|| ($request->filled('null_next_audit_date'))
|
||||
@@ -251,13 +253,14 @@ class BulkAssetsController extends Controller
|
||||
$this->update_array = [];
|
||||
|
||||
/**
|
||||
* Leave out model_id and status here because we do math on that later. We have to do some extra
|
||||
* validation and checks on those two.
|
||||
* Leave out model_id and status here because we do math on that later. We have to do some
|
||||
* extra validation and checks on those two.
|
||||
*
|
||||
* It's tempting to make these match the request check above, but some of these values require
|
||||
* extra work to make sure the data makes sense.
|
||||
*/
|
||||
$this->conditionallyAddItem('purchase_date')
|
||||
$this->conditionallyAddItem('name')
|
||||
->conditionallyAddItem('purchase_date')
|
||||
->conditionallyAddItem('expected_checkin')
|
||||
->conditionallyAddItem('order_number')
|
||||
->conditionallyAddItem('requestable')
|
||||
@@ -271,6 +274,11 @@ class BulkAssetsController extends Controller
|
||||
/**
|
||||
* Blank out fields that were requested to be blanked out via checkbox
|
||||
*/
|
||||
if ($request->input('null_name')=='1') {
|
||||
|
||||
$this->update_array['name'] = null;
|
||||
}
|
||||
|
||||
if ($request->input('null_purchase_date')=='1') {
|
||||
$this->update_array['purchase_date'] = null;
|
||||
}
|
||||
@@ -455,9 +463,8 @@ class BulkAssetsController extends Controller
|
||||
/**
|
||||
* Adds parameter to update array for an item if it exists in request
|
||||
* @param string $field field name
|
||||
* @return BulkAssetsController Model for Chaining
|
||||
*/
|
||||
protected function conditionallyAddItem($field)
|
||||
protected function conditionallyAddItem($field) : BulkAssetsController
|
||||
{
|
||||
if (request()->filled($field)) {
|
||||
$this->update_array[$field] = request()->input($field);
|
||||
@@ -471,12 +478,10 @@ class BulkAssetsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @return View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @internal param array $assets
|
||||
* @since [v2.0]
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
public function destroy(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', Asset::class);
|
||||
|
||||
@@ -488,12 +493,7 @@ class BulkAssetsController extends Controller
|
||||
if ($request->filled('ids')) {
|
||||
$assets = Asset::find($request->get('ids'));
|
||||
foreach ($assets as $asset) {
|
||||
$update_array['deleted_at'] = date('Y-m-d H:i:s');
|
||||
$update_array['assigned_to'] = null;
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $asset->id)
|
||||
->update($update_array);
|
||||
$asset->delete();
|
||||
} // endforeach
|
||||
|
||||
return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.delete.success'));
|
||||
@@ -505,27 +505,23 @@ class BulkAssetsController extends Controller
|
||||
|
||||
/**
|
||||
* Show Bulk Checkout Page
|
||||
* @return View View to checkout multiple assets
|
||||
*/
|
||||
public function showCheckout()
|
||||
public function showCheckout() : View
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
// Filter out assets that are not deployable.
|
||||
|
||||
return view('hardware/bulk-checkout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Multiple Checkout Request
|
||||
* @return View
|
||||
*/
|
||||
public function storeCheckout(AssetCheckoutRequest $request)
|
||||
public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse | ModelNotFoundException
|
||||
{
|
||||
|
||||
$this->authorize('checkout', Asset::class);
|
||||
|
||||
try {
|
||||
$admin = Auth::user();
|
||||
$admin = auth()->user();
|
||||
|
||||
$target = $this->determineCheckoutTarget();
|
||||
|
||||
@@ -584,17 +580,19 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
|
||||
}
|
||||
public function restore(Request $request) {
|
||||
public function restore(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$assetIds = $request->get('ids');
|
||||
if (empty($assetIds)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
||||
$assetIds = $request->get('ids');
|
||||
|
||||
if (empty($assetIds)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
||||
} else {
|
||||
foreach ($assetIds as $key => $assetId) {
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$asset->restore();
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$asset->restore();
|
||||
}
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.restore.success'));
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.restore.success'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Http\Controllers\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
@@ -79,16 +79,16 @@ class ForgotPasswordController extends Controller
|
||||
)
|
||||
);
|
||||
} catch(\Exception $e) {
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').'failed with exception: '.$e );
|
||||
Log::info('Password reset attempt: User '.$request->input('username').'failed with exception: '.$e );
|
||||
}
|
||||
|
||||
// Prevent timing attack to enumerate users.
|
||||
usleep(500000 + random_int(0, 1500000));
|
||||
|
||||
if ($response === \Password::RESET_LINK_SENT) {
|
||||
\Log::info('Password reset attempt: User '.$request->input('username').' WAS found, password reset sent');
|
||||
Log::info('Password reset attempt: User '.$request->input('username').' WAS found, password reset sent');
|
||||
} else {
|
||||
\Log::info('Password reset attempt: User matching username '.$request->input('username').' NOT FOUND or user is inactive');
|
||||
Log::info('Password reset attempt: User matching username '.$request->input('username').' NOT FOUND or user is inactive');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Redirect;
|
||||
|
||||
/**
|
||||
@@ -122,12 +122,12 @@ class LoginController extends Controller
|
||||
Auth::login($user);
|
||||
} else {
|
||||
$username = $saml->getUsername();
|
||||
\Log::debug("SAML user '$username' could not be found in database.");
|
||||
Log::debug("SAML user '$username' could not be found in database.");
|
||||
$request->session()->flash('error', trans('auth/message.signin.error'));
|
||||
$saml->clearData();
|
||||
}
|
||||
|
||||
if ($user = Auth::user()) {
|
||||
if ($user = auth()->user()) {
|
||||
$user->last_login = \Carbon::now();
|
||||
$user->saveQuietly();
|
||||
}
|
||||
@@ -137,7 +137,7 @@ class LoginController extends Controller
|
||||
$s->save();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('There was an error authenticating the SAML user: '.$e->getMessage());
|
||||
Log::debug('There was an error authenticating the SAML user: '.$e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ class LoginController extends Controller
|
||||
|
||||
// Better logging
|
||||
if (empty($samlData)) {
|
||||
\Log::debug("SAML page requested, but samlData seems empty.");
|
||||
Log::debug("SAML page requested, but samlData seems empty.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,19 +261,19 @@ class LoginController extends Controller
|
||||
/**
|
||||
* Account sign in form processing.
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
|
||||
//If the environment is set to ALWAYS require SAML, return access denied
|
||||
if (config('app.require_saml')) {
|
||||
\Log::debug('require SAML is enabled in the .env - return a 403');
|
||||
Log::debug('require SAML is enabled in the .env - return a 403');
|
||||
return view('errors.403');
|
||||
}
|
||||
|
||||
if (Setting::getSettings()->login_common_disabled == '1') {
|
||||
\Log::debug('login_common_disabled is set to 1 - return a 403');
|
||||
Log::debug('login_common_disabled is set to 1 - return a 403');
|
||||
return view('errors.403');
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ class LoginController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ($user = Auth::user()) {
|
||||
if ($user = auth()->user()) {
|
||||
$user->last_login = \Carbon::now();
|
||||
$user->activated = 1;
|
||||
$user->saveQuietly();
|
||||
@@ -339,7 +339,7 @@ class LoginController extends Controller
|
||||
/**
|
||||
* Two factor enrollment page
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function getTwoFactorEnroll()
|
||||
{
|
||||
@@ -350,7 +350,7 @@ class LoginController extends Controller
|
||||
}
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
$user = Auth::user();
|
||||
$user = auth()->user();
|
||||
|
||||
// We wouldn't normally see this page if 2FA isn't enforced via the
|
||||
// \App\Http\Middleware\CheckForTwoFactor middleware AND if a device isn't enrolled,
|
||||
@@ -389,7 +389,7 @@ class LoginController extends Controller
|
||||
/**
|
||||
* Two factor code form page
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function getTwoFactorAuth()
|
||||
{
|
||||
@@ -398,7 +398,7 @@ class LoginController extends Controller
|
||||
return redirect()->route('login')->with('error', trans('auth/general.login_prompt'));
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$user = auth()->user();
|
||||
|
||||
// Check whether there is a device enrolled.
|
||||
// This *should* be handled via the \App\Http\Middleware\CheckForTwoFactor middleware
|
||||
@@ -415,7 +415,7 @@ class LoginController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postTwoFactorAuth(Request $request)
|
||||
{
|
||||
@@ -427,11 +427,7 @@ class LoginController extends Controller
|
||||
return redirect()->route('two-factor')->with('error', trans('auth/message.two_factor.code_required'));
|
||||
}
|
||||
|
||||
if (! $request->has('two_factor_secret')) { // TODO this seems almost the same as above?
|
||||
return redirect()->route('two-factor')->with('error', 'Two-factor code is required.');
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$user = auth()->user();
|
||||
$secret = $request->input('two_factor_secret');
|
||||
|
||||
if (Google2FA::verifyKey($user->two_factor_secret, $secret)) {
|
||||
@@ -439,7 +435,7 @@ class LoginController extends Controller
|
||||
$user->saveQuietly();
|
||||
$request->session()->put('2fa_authed', $user->id);
|
||||
|
||||
return redirect()->route('home')->with('success', 'You are logged in!');
|
||||
return redirect()->route('home')->with('success', trans('auth/message.signin.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('two-factor')->with('error', trans('auth/message.two_factor.invalid_code'));
|
||||
@@ -451,7 +447,7 @@ class LoginController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
* @return Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
@@ -512,8 +508,8 @@ class LoginController extends Controller
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'username' => 'required',
|
||||
'password' => 'required',
|
||||
'username' => 'required|not_array',
|
||||
'password' => 'required|not_array',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -537,7 +533,7 @@ class LoginController extends Controller
|
||||
|
||||
$minutes = round($seconds / 60);
|
||||
|
||||
$message = \Lang::get('auth/message.throttle', ['minutes' => $minutes]);
|
||||
$message = trans('auth/message.throttle', ['minutes' => $minutes]);
|
||||
|
||||
return redirect()->back()
|
||||
->withInput($request->only($this->username(), 'remember'))
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
@@ -66,7 +66,7 @@ class ResetPasswordController extends Controller
|
||||
$credentials = $request->only('email', 'token');
|
||||
|
||||
if (is_null($this->broker()->getUser($credentials))) {
|
||||
\Log::debug('Password reset form FAILED - this token is not valid.');
|
||||
Log::debug('Password reset form FAILED - this token is not valid.');
|
||||
return redirect()->route('password.request')->with('error', trans('passwords.token'));
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ class ResetPasswordController extends Controller
|
||||
'password.not_in' => trans('validation.disallow_same_pwd_as_user_fields'),
|
||||
];
|
||||
|
||||
$request->validate($this->rules(), $request->all(), $this->validationErrorMessages());
|
||||
$request->validate($this->rules());
|
||||
|
||||
\Log::debug('Checking if '.$request->input('username').' exists');
|
||||
Log::debug('Checking if '.$request->input('username').' exists');
|
||||
// Check to see if the user even exists - we'll treat the response the same to prevent user sniffing
|
||||
if ($user = User::where('username', '=', $request->input('username'))->where('activated', '1')->whereNotNull('email')->first()) {
|
||||
\Log::debug($user->username.' exists');
|
||||
Log::debug($user->username.' exists');
|
||||
|
||||
|
||||
// handle the password validation rules set by the admin settings
|
||||
@@ -112,17 +112,17 @@ class ResetPasswordController extends Controller
|
||||
|
||||
// Check if the password reset above actually worked
|
||||
if ($response == \Password::PASSWORD_RESET) {
|
||||
\Log::debug('Password reset for '.$user->username.' worked');
|
||||
Log::debug('Password reset for '.$user->username.' worked');
|
||||
return redirect()->guest('login')->with('success', trans('passwords.reset'));
|
||||
}
|
||||
|
||||
\Log::debug('Password reset for '.$user->username.' FAILED - this user exists but the token is not valid');
|
||||
Log::debug('Password reset for '.$user->username.' FAILED - this user exists but the token is not valid');
|
||||
return redirect()->back()->withInput($request->only('email'))->with('success', trans('passwords.reset'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
\Log::debug('Password reset for '.$request->input('username').' FAILED - user does not exist or does not have an email address - but make it look like it succeeded');
|
||||
Log::debug('Password reset for '.$request->input('username').' FAILED - user does not exist or does not have an email address - but make it look like it succeeded');
|
||||
return redirect()->guest('login')->with('success', trans('passwords.reset'));
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Http\Controllers\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\Saml;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* This controller provides the endpoint for SAML communication and metadata.
|
||||
@@ -51,7 +51,7 @@ class SamlController extends Controller
|
||||
$metadata = $this->saml->getSPMetadata();
|
||||
|
||||
if (empty($metadata)) {
|
||||
\Log::debug('SAML metadata is empty - return a 403');
|
||||
Log::debug('SAML metadata is empty - return a 403');
|
||||
return response()->view('errors.403', [], 403);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class SamlController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
@@ -93,18 +93,24 @@ class SamlController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function acs(Request $request)
|
||||
{
|
||||
$saml = $this->saml;
|
||||
$auth = $saml->getAuth();
|
||||
$auth->processResponse();
|
||||
$saml_exception = false;
|
||||
try {
|
||||
$auth->processResponse();
|
||||
} catch (\Exception $e) {
|
||||
Log::warning("Exception caught in SAML login: " . $e->getMessage());
|
||||
$saml_exception = true;
|
||||
}
|
||||
$errors = $auth->getErrors();
|
||||
|
||||
if (! empty($errors)) {
|
||||
Log::error('There was an error with SAML ACS: '.implode(', ', $errors));
|
||||
Log::error('Reason: '.$auth->getLastErrorReason());
|
||||
if (!empty($errors) || $saml_exception) {
|
||||
Log::warning('There was an error with SAML ACS: ' . implode(', ', $errors));
|
||||
Log::warning('Reason: ' . $auth->getLastErrorReason());
|
||||
|
||||
return redirect()->route('login')->with('error', trans('auth/message.signin.error'));
|
||||
}
|
||||
@@ -126,18 +132,24 @@ class SamlController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function sls(Request $request)
|
||||
{
|
||||
$auth = $this->saml->getAuth();
|
||||
$retrieveParametersFromServer = $this->saml->getSetting('retrieveParametersFromServer', false);
|
||||
$sloUrl = $auth->processSLO(true, null, $retrieveParametersFromServer, null, true);
|
||||
$saml_exception = false;
|
||||
try {
|
||||
$sloUrl = $auth->processSLO(true, null, $retrieveParametersFromServer, null, true);
|
||||
} catch (\Exception $e) {
|
||||
Log::warning("Exception caught in SAML single-logout: " . $e->getMessage());
|
||||
$saml_exception = true;
|
||||
}
|
||||
$errors = $auth->getErrors();
|
||||
|
||||
if (! empty($errors)) {
|
||||
Log::error('There was an error with SAML SLS: '.implode(', ', $errors));
|
||||
Log::error('Reason: '.$auth->getLastErrorReason());
|
||||
if (!empty($errors) || $saml_exception) {
|
||||
Log::warning('There was an error with SAML SLS: ' . implode(', ', $errors));
|
||||
Log::warning('Reason: ' . $auth->getLastErrorReason());
|
||||
|
||||
return view('errors.403');
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace App\Http\Controllers;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
|
||||
class BulkAssetModelsController extends Controller
|
||||
{
|
||||
@@ -16,9 +16,8 @@ class BulkAssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Request $request)
|
||||
public function edit(Request $request) : View | RedirectResponse
|
||||
{
|
||||
$models_raw_array = $request->input('ids');
|
||||
|
||||
@@ -61,9 +60,8 @@ class BulkAssetModelsController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function update(Request $request)
|
||||
public function update(Request $request): View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', AssetModel::class);
|
||||
|
||||
@@ -105,9 +103,8 @@ class BulkAssetModelsController extends Controller
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
public function destroy(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', AssetModel::class);
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Category as Category;
|
||||
use Auth;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Str;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Categories for
|
||||
@@ -25,10 +26,8 @@ class CategoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function index()
|
||||
public function index() : View
|
||||
{
|
||||
// Show the page
|
||||
$this->authorize('view', Category::class);
|
||||
@@ -42,10 +41,8 @@ class CategoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::store() method that stores the data
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function create()
|
||||
public function create() : View
|
||||
{
|
||||
// Show the page
|
||||
$this->authorize('create', Category::class);
|
||||
@@ -61,10 +58,8 @@ class CategoriesController extends Controller
|
||||
* @see CategoriesController::create() method that makes the form.
|
||||
* @since [v1.0]
|
||||
* @param ImageUploadRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
public function store(ImageUploadRequest $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('create', Category::class);
|
||||
$category = new Category();
|
||||
@@ -91,10 +86,8 @@ class CategoriesController extends Controller
|
||||
* @see CategoriesController::postEdit() method saves the data
|
||||
* @param int $categoryId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function edit($categoryId = null)
|
||||
public function edit($categoryId = null) : RedirectResponse | View
|
||||
{
|
||||
$this->authorize('update', Category::class);
|
||||
if (is_null($item = Category::find($categoryId))) {
|
||||
@@ -112,23 +105,31 @@ class CategoriesController extends Controller
|
||||
* @see CategoriesController::getEdit() method that makes the form.
|
||||
* @param ImageUploadRequest $request
|
||||
* @param int $categoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, $categoryId = null)
|
||||
public function update(ImageUploadRequest $request, $categoryId = null) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Category::class);
|
||||
if (is_null($category = Category::find($categoryId))) {
|
||||
// Redirect to the categories management page
|
||||
return redirect()->to('admin/categories')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the category data
|
||||
$category->name = $request->input('name');
|
||||
// If the item count is > 0, we disable the category type in the edit. Disabled items
|
||||
// don't POST, so if the category_type is blank we just set it to the default.
|
||||
|
||||
|
||||
// Don't allow the user to change the category_type once it's been created
|
||||
if (($request->filled('category_type') && ($category->itemCount() > 0))) {
|
||||
$request->validate(['category_type' => 'in:'.$category->category_type]);
|
||||
}
|
||||
|
||||
$category->category_type = $request->input('category_type', $category->category_type);
|
||||
|
||||
$category->fill($request->all());
|
||||
|
||||
$category->eula_text = $request->input('eula_text');
|
||||
$category->use_default_eula = $request->input('use_default_eula', '0');
|
||||
$category->require_acceptance = $request->input('require_acceptance', '0');
|
||||
@@ -150,10 +151,8 @@ class CategoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $categoryId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($categoryId)
|
||||
public function destroy($categoryId) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', Category::class);
|
||||
// Check if the category exists
|
||||
@@ -178,11 +177,9 @@ class CategoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see CategoriesController::getDataView() method that generates the JSON response
|
||||
* @param $id
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function show($id)
|
||||
public function show($id) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
if ($category = Category::find($id)) {
|
||||
|
||||
@@ -11,9 +11,8 @@ trait CheckInOutRequest
|
||||
{
|
||||
/**
|
||||
* Find target for checkout
|
||||
* @return SnipeModel Target asset is being checked out to.
|
||||
*/
|
||||
protected function determineCheckoutTarget()
|
||||
protected function determineCheckoutTarget() : ?SnipeModel
|
||||
{
|
||||
// This item is checked out to a location
|
||||
switch (request('checkout_to_type')) {
|
||||
@@ -21,7 +20,7 @@ trait CheckInOutRequest
|
||||
return Location::findOrFail(request('assigned_location'));
|
||||
case 'asset':
|
||||
return Asset::findOrFail(request('assigned_asset'));
|
||||
case 'user':
|
||||
default:
|
||||
return User::findOrFail(request('assigned_user'));
|
||||
}
|
||||
|
||||
@@ -34,7 +33,7 @@ trait CheckInOutRequest
|
||||
* @param SnipeModel $target Target with location
|
||||
* @return Asset Asset being updated
|
||||
*/
|
||||
protected function updateAssetLocation($asset, $target)
|
||||
protected function updateAssetLocation($asset, $target) : Asset
|
||||
{
|
||||
switch (request('checkout_to_type')) {
|
||||
case 'location':
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user