Compare commits

..

1124 Commits

Author SHA1 Message Date
4514396818 change 2024-01-22 12:12:15 +10:00
b028856eb5 php 8.2 now required 2024-01-19 10:04:51 +10:00
1925b2ef0c dependency updates 2024-01-19 09:53:52 +10:00
f2e84b63fa dependency updates 2024-01-15 09:02:21 +10:00
ac6257ed6d vs settings change 2024-01-15 09:02:16 +10:00
2486dec824 added rel="nofollow" to download links 2024-01-15 09:01:36 +10:00
04e6c0d0fc fix bad param 2024-01-06 15:57:46 +10:00
b948c42fe2 check if file_security is missing 2024-01-06 15:57:39 +10:00
5d7be1a482 dependency updates 2024-01-06 15:57:22 +10:00
4e81d06a6e dep updates 2023-12-25 19:23:46 +10:00
7ed2332a3e dependency updates 2023-12-01 10:52:49 +10:00
James Collins
c432b32d08 Merge pull request #319 from STEMMechanics/dependabot/composer/laravel/framework-10.30.1
Bump laravel/framework from 10.30.0 to 10.30.1
2023-11-02 10:39:26 +10:00
James Collins
8cf628153c Merge pull request #318 from STEMMechanics/dependabot/npm_and_yarn/knip-2.38.6
Bump knip from 2.38.4 to 2.38.6
2023-11-02 10:38:24 +10:00
dependabot[bot]
ab0bd9e7d9 Bump laravel/framework from 10.30.0 to 10.30.1
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.30.0 to 10.30.1.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.30.0...v10.30.1)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-02 00:26:04 +00:00
dependabot[bot]
51cd70f2ec Bump knip from 2.38.4 to 2.38.6
Bumps [knip](https://github.com/webpro/knip) from 2.38.4 to 2.38.6.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.38.4...2.38.6)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-02 00:15:36 +00:00
235d4e3784 Merge pull request #317 from STEMMechanics/dependabot/composer/laravel/framework-10.30.0 2023-11-01 10:52:42 +10:00
dependabot[bot]
dd0bbad18f Bump laravel/framework from 10.29.0 to 10.30.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.29.0 to 10.30.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.29.0...v10.30.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 00:51:33 +00:00
f32059c3e7 Merge pull request #316 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.9.1 2023-10-31 11:24:17 +10:00
dependabot[bot]
92578ef738 Bump @typescript-eslint/parser from 6.9.0 to 6.9.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.0 to 6.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-31 01:21:23 +00:00
367205f955 Merge pull request #315 from STEMMechanics/dependabot/npm_and_yarn/eslint-8.52.0 2023-10-31 11:20:58 +10:00
1fdf36669f Merge pull request #314 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.9.1 2023-10-31 11:20:43 +10:00
dependabot[bot]
dfa06b148f Bump eslint from 8.51.0 to 8.52.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.51.0 to 8.52.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.51.0...v8.52.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-31 01:08:07 +00:00
dependabot[bot]
139b437118 Bump @typescript-eslint/eslint-plugin from 6.9.0 to 6.9.1
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.9.0 to 6.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-31 01:07:54 +00:00
4dca636359 Merge pull request #312 from STEMMechanics/dependabot/npm_and_yarn/vue-3.3.7 2023-10-30 15:59:16 +10:00
4f1d2a179b Merge pull request #311 from STEMMechanics/dependabot/npm_and_yarn/knip-2.38.4 2023-10-30 15:59:02 +10:00
dependabot[bot]
ede28f375a Bump knip from 2.35.0 to 2.38.4
Bumps [knip](https://github.com/webpro/knip) from 2.35.0 to 2.38.4.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.35.0...2.38.4)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 01:38:00 +00:00
dependabot[bot]
06dfb8d7f6 Bump vue from 3.3.4 to 3.3.7
Bumps [vue](https://github.com/vuejs/core) from 3.3.4 to 3.3.7.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.3.4...v3.3.7)

---
updated-dependencies:
- dependency-name: vue
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 01:37:46 +00:00
2d4090922f Merge pull request #313 from STEMMechanics/dependabot/npm_and_yarn/vite-plugin-compression2-0.11.0 2023-10-30 11:37:04 +10:00
3d58a09c21 Merge pull request #310 from STEMMechanics/dependabot/npm_and_yarn/sass-1.69.5 2023-10-30 11:36:40 +10:00
05da5f016c Merge pull request #309 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-vue-9.18.1 2023-10-30 11:36:27 +10:00
dependabot[bot]
256eead944 Bump vite-plugin-compression2 from 0.10.6 to 0.11.0
Bumps [vite-plugin-compression2](https://github.com/nonzzz/vite-plugin-compression) from 0.10.6 to 0.11.0.
- [Release notes](https://github.com/nonzzz/vite-plugin-compression/releases)
- [Changelog](https://github.com/nonzzz/vite-plugin-compression/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nonzzz/vite-plugin-compression/compare/v0.10.6...v0.11.0)

---
updated-dependencies:
- dependency-name: vite-plugin-compression2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 00:26:20 +00:00
dependabot[bot]
dcb8ffaa0d Bump sass from 1.69.4 to 1.69.5
Bumps [sass](https://github.com/sass/dart-sass) from 1.69.4 to 1.69.5.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.69.4...1.69.5)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 00:24:57 +00:00
dependabot[bot]
def671dd47 Bump eslint-plugin-vue from 9.17.0 to 9.18.1
Bumps [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) from 9.17.0 to 9.18.1.
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v9.17.0...v9.18.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-vue
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-30 00:24:30 +00:00
717f360952 Merge pull request #302 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.9.0 2023-10-29 11:59:09 +10:00
dependabot[bot]
1c0b91f52c Bump @typescript-eslint/parser from 6.8.0 to 6.9.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.8.0 to 6.9.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-28 07:52:11 +00:00
c733d39d30 Merge pull request #301 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.9.0 2023-10-28 17:51:41 +10:00
87bdea3bba Merge pull request #308 from STEMMechanics/dependabot/composer/phpunit/phpunit-10.4.2 2023-10-28 17:51:28 +10:00
efe80694f9 Merge pull request #307 from STEMMechanics/dependabot/composer/laravel/pint-1.13.5 2023-10-28 17:51:19 +10:00
be7e6ee400 Merge pull request #306 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.57.1 2023-10-28 17:51:09 +10:00
319a7b27c5 Merge pull request #304 from STEMMechanics/dependabot/composer/laravel/sail-1.26.0 2023-10-28 17:51:00 +10:00
dbe20ac724 Merge pull request #303 from STEMMechanics/dependabot/composer/laravel/framework-10.29.0 2023-10-28 17:50:51 +10:00
dependabot[bot]
dc6ed3f43a Bump @typescript-eslint/eslint-plugin from 6.8.0 to 6.9.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.8.0 to 6.9.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-28 07:50:16 +00:00
ecddb5c6d3 Merge pull request #299 from STEMMechanics/dependabot/npm_and_yarn/ls-lint/ls-lint-2.2.2 2023-10-28 17:49:35 +10:00
34e5a37e24 Merge pull request #297 from STEMMechanics/dependabot/composer/square/square-32.0.0.20231018 2023-10-28 17:49:23 +10:00
eaca6bcc72 Merge pull request #283 from STEMMechanics/dependabot/npm_and_yarn/vitejs/plugin-vue-4.4.0 2023-10-28 17:49:04 +10:00
dependabot[bot]
bad588d4b2 Bump phpunit/phpunit from 10.4.1 to 10.4.2
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 10.4.1 to 10.4.2.
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.4.2/ChangeLog-10.4.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/10.4.1...10.4.2)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 01:15:59 +00:00
dependabot[bot]
d5daf20351 Bump laravel/pint from 1.13.3 to 1.13.5
Bumps [laravel/pint](https://github.com/laravel/pint) from 1.13.3 to 1.13.5.
- [Release notes](https://github.com/laravel/pint/releases)
- [Changelog](https://github.com/laravel/pint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/pint/compare/v1.13.3...v1.13.5)

---
updated-dependencies:
- dependency-name: laravel/pint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 01:15:53 +00:00
dependabot[bot]
f512ab96fc Bump unocss from 0.55.7 to 0.57.1
Bumps [unocss](https://github.com/unocss/unocss) from 0.55.7 to 0.57.1.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.55.7...v0.57.1)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 01:10:26 +00:00
dependabot[bot]
0cfa9a5483 Bump laravel/sail from 1.25.0 to 1.26.0
Bumps [laravel/sail](https://github.com/laravel/sail) from 1.25.0 to 1.26.0.
- [Release notes](https://github.com/laravel/sail/releases)
- [Changelog](https://github.com/laravel/sail/blob/1.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sail/compare/v1.25.0...v1.26.0)

---
updated-dependencies:
- dependency-name: laravel/sail
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 00:17:49 +00:00
dependabot[bot]
979f934f22 Bump laravel/framework from 10.28.0 to 10.29.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.28.0 to 10.29.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.28.0...v10.29.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-25 00:17:39 +00:00
dependabot[bot]
1fa5820550 Bump @ls-lint/ls-lint from 2.2.1 to 2.2.2
Bumps [@ls-lint/ls-lint](https://github.com/loeffel-io/ls-lint) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/loeffel-io/ls-lint/releases)
- [Commits](https://github.com/loeffel-io/ls-lint/compare/v2.2.1...v2.2.2)

---
updated-dependencies:
- dependency-name: "@ls-lint/ls-lint"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-23 01:09:34 +00:00
8233afa825 codesniffer fixes 2023-10-20 11:10:33 +10:00
ba6f67798d obsolete 2023-10-20 09:47:29 +10:00
daabbaa3e4 ignore codesniffer 2023-10-20 09:22:30 +10:00
caa68b24d6 dependency updates 2023-10-20 09:21:09 +10:00
114db744b4 better error handling 2023-10-19 19:20:17 +10:00
8c910ed5f3 show error 2023-10-19 19:02:37 +10:00
1ef4332df6 cleanup 2023-10-19 18:55:57 +10:00
6e98269a0b dependency updates 2023-10-19 18:55:57 +10:00
dependabot[bot]
c918b91438 Bump square/square from 30.0.0.20230816 to 32.0.0.20231018
Bumps [square/square](https://github.com/square/square-php-sdk) from 30.0.0.20230816 to 32.0.0.20231018.
- [Release notes](https://github.com/square/square-php-sdk/releases)
- [Changelog](https://github.com/square/square-php-sdk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/square-php-sdk/compare/30.0.0.20230816...32.0.0.20231018)

---
updated-dependencies:
- dependency-name: square/square
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 00:19:35 +00:00
2a1e634b34 added YT Link 2023-10-04 08:20:19 +10:00
dependabot[bot]
d45165d759 Bump @vitejs/plugin-vue from 4.3.4 to 4.4.0
Bumps [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) from 4.3.4 to 4.4.0.
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@4.4.0/packages/plugin-vue)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-vue"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-03 00:51:18 +00:00
a0a885e004 fix media dialog title 2023-09-29 17:05:28 +10:00
52f7070311 bad comma 2023-09-29 17:03:11 +10:00
e0650da5e9 fix new getURLPath 2023-09-29 16:57:55 +10:00
bf5cf3bce4 fix public validation 2023-09-29 16:45:42 +10:00
07d1dc4955 home button 2023-09-29 16:23:26 +10:00
11db41b900 accept media or string 2023-09-29 16:02:57 +10:00
3bca959d49 set field to user friendly url 2023-09-29 16:00:56 +10:00
3fee673314 remove console.log 2023-09-29 15:59:23 +10:00
3121d12f3a sort media list in reverse 2023-09-29 15:55:35 +10:00
b8731c3f37 clear unneeded initalize 2023-09-29 13:20:26 +10:00
b445a42896 reload 2023-09-29 13:19:06 +10:00
dbab224a9d fix pageloading 2023-09-29 13:17:18 +10:00
03f9659243 reload 2023-09-29 13:15:45 +10:00
0fb56133ff reload 2023-09-29 13:12:44 +10:00
afa7ca629c reload 2023-09-29 13:10:30 +10:00
9a9c382d7f fix reload 2023-09-29 13:08:39 +10:00
518b8d67bc reload page 2023-09-29 13:04:54 +10:00
ff0f8194e0 remove debug 2023-09-29 13:01:44 +10:00
f84f982c29 add retry button 2023-09-29 13:00:30 +10:00
420d81866c back button detection 2023-09-29 12:53:24 +10:00
1cd78ce93a back button fix 2023-09-29 12:47:47 +10:00
7cae8af89a catch back button 2023-09-29 12:45:33 +10:00
5088cea413 reset mounted 2023-09-29 12:36:39 +10:00
d670d52083 catch bad selectors 2023-09-29 12:33:23 +10:00
004aa116fb allow security_data in the correct contexts 2023-09-29 12:22:48 +10:00
32a08e1e10 better handling of storage exists 2023-09-29 12:16:43 +10:00
30d39c5326 cleanup 2023-09-29 12:16:25 +10:00
8affea3360 ignore empty mime_types 2023-09-29 12:00:01 +10:00
3b6b4dc388 support null $medium 2023-09-29 11:58:11 +10:00
9a9e75d96d remove empty mime_type ignore 2023-09-29 11:57:54 +10:00
ad6e4f0a23 fix case where new media has no security type 2023-09-29 11:52:17 +10:00
f66bc6d8aa updated lock icons and small views 2023-09-29 11:47:28 +10:00
845bb4763b fix thumb always overriding 2023-09-29 11:31:26 +10:00
e476b203c7 add download query 2023-09-29 11:22:29 +10:00
dd163630cb dependency updates 2023-09-29 11:14:43 +10:00
5d8a5ede7d add security icons 2023-09-29 11:10:08 +10:00
35ccb03c2b cleanup of styling 2023-09-29 11:10:01 +10:00
f6df068787 fix bad local storage url 2023-09-29 11:01:37 +10:00
b60a3601cb urlencode variables 2023-09-29 11:01:28 +10:00
8676844930 fix security policy notification styling 2023-09-29 07:40:14 +10:00
7e80e19eec fix change password dialog 2023-09-29 07:34:29 +10:00
e21c7ce1d0 add defaults for missing filter data 2023-09-29 07:28:21 +10:00
42f2baca5e media security_type updates 2023-09-29 07:19:33 +10:00
d9c0c8f1d8 fix sqlite error with renameColumn 2023-09-28 20:23:38 +10:00
b98e184d32 dependency updates 2023-09-28 10:09:48 +10:00
f764466199 ensure duplicate media items are not readded 2023-09-28 10:06:53 +10:00
6adfd9f3fa complete secure files 2023-09-28 09:59:40 +10:00
dbf9db1c92 create generic variants and thumbnail for secure documents 2023-09-27 17:08:45 +10:00
6cb7a8cb43 update secure media backend 2023-09-25 19:36:44 +10:00
2913960bcb update dependencies 2023-09-25 15:33:37 +10:00
8d0382a279 added 2023-09-25 15:33:29 +10:00
aa5ef50ed0 push params 2023-09-14 21:56:42 +10:00
d87b869633 added url support 2023-09-14 21:53:00 +10:00
99782bdf67 added helper function 2023-09-14 21:52:52 +10:00
6fa459e88e fix margin 2023-09-14 21:34:43 +10:00
954f2beea7 dependency updates 2023-09-14 21:32:55 +10:00
f216413a23 pagination on bottom 2023-09-14 21:30:35 +10:00
63572a2740 fix query comparison 2023-09-14 08:35:01 +10:00
aeb7595166 no default date if filter params exist 2023-09-14 08:32:03 +10:00
f507d198a7 fix query operators 2023-09-14 08:24:34 +10:00
9b5166c570 remove unused componets 2023-09-13 20:10:46 +10:00
2271aae557 use rawurlencode 2023-09-13 20:08:53 +10:00
8ed07e539f use new urlencode function 2023-09-13 20:04:43 +10:00
b029574fa5 add URLEncode function 2023-09-13 20:04:37 +10:00
e9d903ce79 autoload urlencode 2023-09-13 20:04:30 +10:00
1c9100e5de page not found error 2023-09-13 19:55:47 +10:00
1a59ac955d encode url 2023-09-13 19:23:31 +10:00
4d8e58f920 added scratch icon 2023-09-13 19:13:22 +10:00
James Collins
55ce8e0d9e Merge pull request #246 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.7.0
Bump @typescript-eslint/eslint-plugin from 6.6.0 to 6.7.0
2023-09-12 11:09:15 +10:00
dependabot[bot]
0d1a3f8dbf Bump @typescript-eslint/eslint-plugin from 6.6.0 to 6.7.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.6.0 to 6.7.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 01:08:20 +00:00
James Collins
9687a3c7a8 Merge pull request #247 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.7.0
Bump @typescript-eslint/parser from 6.6.0 to 6.7.0
2023-09-12 11:07:38 +10:00
dependabot[bot]
471534021e Bump @typescript-eslint/parser from 6.6.0 to 6.7.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.6.0 to 6.7.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.7.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 00:53:48 +00:00
8c75abf16a add index to controller 2023-09-11 21:04:12 +10:00
472abaf30b use new routes 2023-09-11 21:04:02 +10:00
35426e1189 use new routes 2023-09-11 21:03:52 +10:00
6507d57424 change job to jobs and add index 2023-09-11 21:03:45 +10:00
4252878019 support the | (or) operator 2023-09-11 21:03:12 +10:00
James Collins
8451cc1547 Merge pull request #245 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-46.6.0
Bump eslint-plugin-jsdoc from 46.5.1 to 46.6.0
2023-09-11 11:24:52 +10:00
dependabot[bot]
70ecefb007 Bump eslint-plugin-jsdoc from 46.5.1 to 46.6.0
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 46.5.1 to 46.6.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v46.5.1...v46.6.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 01:15:29 +00:00
4e7be1a18c remove stale jobs 2023-09-10 21:16:00 +10:00
d1cc468dfa added clean temp files schedule 2023-09-10 21:06:00 +10:00
484512f2c7 fix spacing 2023-09-10 20:43:28 +10:00
83b4df3462 fix icon text 2023-09-10 20:34:39 +10:00
8ea46b4ea8 update message 2023-09-10 20:34:34 +10:00
a68faa11b0 increase max chunks count 2023-09-10 20:26:51 +10:00
541cd93c99 cleanup 2023-09-10 20:26:00 +10:00
c5a7982945 update file icons 2023-09-10 20:25:54 +10:00
5cee36453e Transferring to CDN, not Uploading 2023-09-10 20:13:12 +10:00
47ea87b614 improve upload progress indicator 2023-09-10 20:11:22 +10:00
4ad0df2c39 dependency updates 2023-09-10 20:11:11 +10:00
f2ff8398eb dont rotate non images/video 2023-09-10 20:06:48 +10:00
3f915d6964 fixes to uploading in chunks 2023-09-10 19:59:26 +10:00
3e6a9da0d1 media job now uses progress_max 2023-09-10 18:33:54 +10:00
James Collins
ca5f4ffd84 Merge pull request #244 from STEMMechanics/dependabot/npm_and_yarn/knip-2.22.0
Bump knip from 2.21.2 to 2.22.0
2023-09-08 11:19:41 +10:00
James Collins
b66f9f79d2 Merge pull request #243 from STEMMechanics/dependabot/composer/league/flysystem-aws-s3-v3-3.16.0
Bump league/flysystem-aws-s3-v3 from 3.15.0 to 3.16.0
2023-09-08 11:17:58 +10:00
dependabot[bot]
dc0bfe6d7a Bump knip from 2.21.2 to 2.22.0
Bumps [knip](https://github.com/webpro/knip) from 2.21.2 to 2.22.0.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.21.2...2.22.0)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-08 01:01:38 +00:00
dependabot[bot]
5de463bd02 Bump league/flysystem-aws-s3-v3 from 3.15.0 to 3.16.0
Bumps [league/flysystem-aws-s3-v3](https://github.com/thephpleague/flysystem-aws-s3-v3) from 3.15.0 to 3.16.0.
- [Commits](https://github.com/thephpleague/flysystem-aws-s3-v3/compare/3.15.0...3.16.0)

---
updated-dependencies:
- dependency-name: league/flysystem-aws-s3-v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-08 00:59:15 +00:00
James Collins
f3d858d785 Merge pull request #242 from STEMMechanics/dependabot/composer/laravel/pint-1.13.1
Bump laravel/pint from 1.13.0 to 1.13.1
2023-09-07 17:52:51 +10:00
dependabot[bot]
0e537a6b46 Bump laravel/pint from 1.13.0 to 1.13.1
Bumps [laravel/pint](https://github.com/laravel/pint) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/laravel/pint/releases)
- [Changelog](https://github.com/laravel/pint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/pint/compare/v1.13.0...v1.13.1)

---
updated-dependencies:
- dependency-name: laravel/pint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-07 00:21:35 +00:00
8d78b15751 block access to the .git directory 2023-09-06 12:25:03 +10:00
James Collins
e1fc2fa271 Merge pull request #239 from STEMMechanics/dependabot/npm_and_yarn/knip-2.21.2
Bump knip from 2.21.1 to 2.21.2
2023-09-06 11:08:00 +10:00
James Collins
27466ad3a6 Merge pull request #241 from STEMMechanics/dependabot/npm_and_yarn/tiptap/starter-kit-2.1.8
Bump @tiptap/starter-kit from 2.1.7 to 2.1.8
2023-09-06 11:06:48 +10:00
dependabot[bot]
f0d63b4120 Bump @tiptap/starter-kit from 2.1.7 to 2.1.8
Bumps [@tiptap/starter-kit](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/starter-kit) from 2.1.7 to 2.1.8.
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v2.1.8/packages/starter-kit/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v2.1.8/packages/starter-kit)

---
updated-dependencies:
- dependency-name: "@tiptap/starter-kit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 01:00:47 +00:00
dependabot[bot]
163dd98b7b Bump knip from 2.21.1 to 2.21.2
Bumps [knip](https://github.com/webpro/knip) from 2.21.1 to 2.21.2.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.21.1...2.21.2)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 00:58:27 +00:00
8610a1678d dependency updates 2023-09-06 10:57:21 +10:00
James Collins
d20c7832da Merge pull request #234 from STEMMechanics/dependabot/composer/laravel/sail-1.24.1
Bump laravel/sail from 1.24.0 to 1.24.1
2023-09-06 10:45:38 +10:00
James Collins
fcba4015ed Merge pull request #233 from STEMMechanics/dependabot/composer/laravel/pint-1.13.0
Bump laravel/pint from 1.12.0 to 1.13.0
2023-09-06 10:45:25 +10:00
James Collins
bb34a3c33a Merge pull request #232 from STEMMechanics/dependabot/composer/phpunit/phpunit-10.3.3
Bump phpunit/phpunit from 10.3.2 to 10.3.3
2023-09-06 10:45:13 +10:00
James Collins
dbded3ba14 Merge pull request #231 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.6.0
Bump @typescript-eslint/parser from 6.5.0 to 6.6.0
2023-09-06 10:44:59 +10:00
dependabot[bot]
3a654e0480 Bump laravel/sail from 1.24.0 to 1.24.1
Bumps [laravel/sail](https://github.com/laravel/sail) from 1.24.0 to 1.24.1.
- [Release notes](https://github.com/laravel/sail/releases)
- [Changelog](https://github.com/laravel/sail/blob/1.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sail/compare/v1.24.0...v1.24.1)

---
updated-dependencies:
- dependency-name: laravel/sail
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 00:44:55 +00:00
James Collins
4b358fba4f Merge pull request #230 from STEMMechanics/dependabot/npm_and_yarn/tiptap/extension-superscript-2.1.8
Bump @tiptap/extension-superscript from 2.1.7 to 2.1.8
2023-09-06 10:44:44 +10:00
dependabot[bot]
5aaeab686d Bump @typescript-eslint/parser from 6.5.0 to 6.6.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.5.0 to 6.6.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.6.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 00:43:06 +00:00
James Collins
5ff0a4e86f Merge pull request #229 from STEMMechanics/dependabot/npm_and_yarn/tiptap/extension-highlight-2.1.8
Bump @tiptap/extension-highlight from 2.1.7 to 2.1.8
2023-09-06 10:42:52 +10:00
James Collins
0c866ed009 Merge pull request #228 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.6.0
Bump @typescript-eslint/eslint-plugin from 6.5.0 to 6.6.0
2023-09-06 10:42:24 +10:00
James Collins
f09bf02c10 Merge pull request #227 from STEMMechanics/dependabot/composer/laravel/sanctum-3.3.0
Bump laravel/sanctum from 3.2.6 to 3.3.0
2023-09-06 10:42:07 +10:00
James Collins
ee2c30f938 Merge pull request #220 from STEMMechanics/dependabot/npm_and_yarn/prettier-3.0.3
Bump prettier from 3.0.2 to 3.0.3
2023-09-06 10:41:41 +10:00
dependabot[bot]
82f28bc712 Bump laravel/pint from 1.12.0 to 1.13.0
Bumps [laravel/pint](https://github.com/laravel/pint) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/laravel/pint/releases)
- [Changelog](https://github.com/laravel/pint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/pint/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: laravel/pint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 00:28:51 +00:00
dependabot[bot]
8020baf9d1 Bump phpunit/phpunit from 10.3.2 to 10.3.3
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 10.3.2 to 10.3.3.
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.3.3/ChangeLog-10.3.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/10.3.2...10.3.3)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-06 00:28:46 +00:00
dependabot[bot]
b1cac44432 Bump @tiptap/extension-superscript from 2.1.7 to 2.1.8
Bumps [@tiptap/extension-superscript](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/extension-superscript) from 2.1.7 to 2.1.8.
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v2.1.8/packages/extension-superscript/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v2.1.8/packages/extension-superscript)

---
updated-dependencies:
- dependency-name: "@tiptap/extension-superscript"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-05 00:37:11 +00:00
dependabot[bot]
ab46b6118d Bump @tiptap/extension-highlight from 2.1.7 to 2.1.8
Bumps [@tiptap/extension-highlight](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/extension-highlight) from 2.1.7 to 2.1.8.
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v2.1.8/packages/extension-highlight/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v2.1.8/packages/extension-highlight)

---
updated-dependencies:
- dependency-name: "@tiptap/extension-highlight"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-05 00:36:45 +00:00
dependabot[bot]
52a1bfe804 Bump @typescript-eslint/eslint-plugin from 6.5.0 to 6.6.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.5.0 to 6.6.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.6.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-05 00:36:20 +00:00
dependabot[bot]
c7c5b5298c Bump laravel/sanctum from 3.2.6 to 3.3.0
Bumps [laravel/sanctum](https://github.com/laravel/sanctum) from 3.2.6 to 3.3.0.
- [Release notes](https://github.com/laravel/sanctum/releases)
- [Changelog](https://github.com/laravel/sanctum/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sanctum/compare/v3.2.6...v3.3.0)

---
updated-dependencies:
- dependency-name: laravel/sanctum
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-05 00:17:28 +00:00
James Collins
4c07917542 Merge pull request #225 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.55.6
Bump unocss from 0.55.4 to 0.55.6
2023-09-04 11:11:03 +10:00
dependabot[bot]
fe06a2dd55 Bump unocss from 0.55.4 to 0.55.6
Bumps [unocss](https://github.com/unocss/unocss) from 0.55.4 to 0.55.6.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.55.4...v0.55.6)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 01:03:15 +00:00
143f002ead allow blank 2023-09-02 21:09:36 +10:00
83c0ae5841 bug fixes 2023-09-02 21:01:19 +10:00
0c05386804 bug fixes 2023-09-02 20:44:56 +10:00
9a70d4de0d bugfix 2023-09-02 19:59:26 +10:00
8950b5f50b titlecase to fix CDN 2023-09-02 19:56:06 +10:00
59e077fd6a bug fixes 2023-09-02 19:55:55 +10:00
c9fc5b2157 bugfix 2023-09-02 19:40:38 +10:00
e128bcfaf9 bugfix 2023-09-02 19:36:55 +10:00
7cf6b0bba6 bug fixes 2023-09-02 19:30:45 +10:00
c36d4783e7 dependency updates 2023-09-02 19:02:19 +10:00
29acd76051 fixes 2023-09-02 18:58:13 +10:00
eacf33b642 updates 2023-09-01 16:51:46 +10:00
46666db231 prevent truncation of urls 2023-09-01 13:00:07 +10:00
3dfa753f33 fix path truncates 2023-09-01 12:58:20 +10:00
41ae64a8c9 new media job support 2023-09-01 12:22:25 +10:00
fcf5400f71 added 2023-09-01 08:43:57 +10:00
2257736ad9 bug fixes 2023-08-31 23:21:20 +10:00
147b55ae78 updates 2023-08-30 15:20:24 +10:00
5b6c951dc0 use new mediaJob 2023-08-30 14:22:27 +10:00
0840d65011 added respondServerError 2023-08-30 12:00:44 +10:00
6394234960 more rules 2023-08-30 11:08:24 +10:00
e1dde655cb rename class 2023-08-30 10:55:36 +10:00
e01d59cbd8 use mediajob 2023-08-30 10:54:44 +10:00
22d1e195ed change id to job_id 2023-08-30 10:54:44 +10:00
c776e7b102 media job model 2023-08-30 10:52:26 +10:00
dependabot[bot]
3cd95a5a6b Bump prettier from 3.0.2 to 3.0.3
Bumps [prettier](https://github.com/prettier/prettier) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-30 00:35:52 +00:00
aba7845a4b changes 2023-08-30 08:19:23 +10:00
f23c4c42b5 added location_url rule 2023-08-30 06:54:27 +10:00
05149dc723 update full description 2023-08-29 18:14:48 +10:00
a615c9d1d8 added full status 2023-08-29 18:11:29 +10:00
eed9ac8ff4 bugfix 2023-08-29 15:51:55 +10:00
258e7fe307 bugfix 2023-08-29 15:47:58 +10:00
a49a86a597 debug 2023-08-29 15:43:21 +10:00
b01c5d57c7 debug 2023-08-29 15:38:37 +10:00
4b0c113941 bug fix 2023-08-29 15:32:18 +10:00
277a0ae2e3 debug 2023-08-29 15:29:43 +10:00
a61aafdc6a debug 2023-08-29 15:25:31 +10:00
3a2899f913 debug 2023-08-29 15:22:27 +10:00
05b172cd47 bug fix 2023-08-29 15:07:40 +10:00
351259909c fix rule validation 2023-08-29 15:02:33 +10:00
0af44ffe02 bug fix 2023-08-29 14:56:02 +10:00
06799a90b0 bug fixes 2023-08-29 14:54:40 +10:00
c7fc9a1480 support chunk uploading 2023-08-29 14:51:30 +10:00
d5b8a89776 support file upload chunking 2023-08-29 14:34:59 +10:00
eada83aaf8 added chunking rules 2023-08-29 14:34:51 +10:00
9a63a9de80 additional helpers 2023-08-29 14:34:42 +10:00
b4859fd97f cleanup 2023-08-29 11:56:05 +10:00
794a18cfa0 updates to media handling on frontend 2023-08-29 11:31:57 +10:00
581b732b05 layout fixes 2023-08-29 08:44:56 +10:00
0119875d22 cache persistant 2023-08-29 08:03:06 +10:00
0f34c7dfb9 use new caching 2023-08-28 23:16:12 +10:00
04be7fdb3c implement callback/caching 2023-08-28 23:16:04 +10:00
123d45d172 removed debug log 2023-08-28 23:02:04 +10:00
James Collins
864ae189af Merge pull request #213 from STEMMechanics/dependabot/npm_and_yarn/vitest-0.34.3
Bump vitest from 0.33.0 to 0.34.3
2023-08-28 22:19:43 +10:00
dependabot[bot]
13b2620d2e Bump vitest from 0.33.0 to 0.34.3
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 0.33.0 to 0.34.3.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v0.34.3/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 12:19:18 +00:00
James Collins
75c4ad73ed Merge pull request #198 from STEMMechanics/dependabot/npm_and_yarn/prettier-3.0.2
Bump prettier from 3.0.0 to 3.0.2
2023-08-28 22:18:45 +10:00
James Collins
2c2f5621df Merge pull request #212 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.55.3
Bump unocss from 0.54.3 to 0.55.3
2023-08-28 22:18:31 +10:00
James Collins
855accab4f Merge pull request #199 from STEMMechanics/dependabot/composer/square/square-30.0.0.20230816
Bump square/square from 29.0.0.20230720 to 30.0.0.20230816
2023-08-28 22:17:38 +10:00
dependabot[bot]
afaa702a02 Bump prettier from 3.0.0 to 3.0.2
Bumps [prettier](https://github.com/prettier/prettier) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.0.0...3.0.2)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 12:17:32 +00:00
James Collins
15637d398e Merge pull request #197 from STEMMechanics/dependabot/npm_and_yarn/laravel-vite-plugin-0.8.0
Bump laravel-vite-plugin from 0.7.8 to 0.8.0
2023-08-28 22:17:07 +10:00
James Collins
f346625bb1 Merge pull request #188 from STEMMechanics/dependabot/npm_and_yarn/eslint-config-prettier-9.0.0
Bump eslint-config-prettier from 8.9.0 to 9.0.0
2023-08-28 22:16:36 +10:00
9764fef01c dependency updates 2023-08-28 22:13:56 +10:00
338d6c6f9d bug fix 2023-08-28 15:40:12 +10:00
9da6f39e6e bug fix 2023-08-28 15:37:45 +10:00
5759794f71 dont process video if not changed 2023-08-28 15:31:31 +10:00
ee9d96a5bf fix increment 2023-08-28 15:31:20 +10:00
9197a86670 fix progress bar 2023-08-28 15:21:10 +10:00
64e45b1892 fixes 2023-08-28 15:11:18 +10:00
6890a0939d fix rotate error 2023-08-28 14:29:47 +10:00
61c78534d8 loading status and fixes 2023-08-28 14:21:09 +10:00
5a611f96a8 added x-small 2023-08-28 14:21:00 +10:00
3e7f34d5c4 fix video uploads 2023-08-28 14:00:07 +10:00
dependabot[bot]
78d16bec5f Bump unocss from 0.54.3 to 0.55.3
Bumps [unocss](https://github.com/unocss/unocss) from 0.54.3 to 0.55.3.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.54.3...v0.55.3)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-28 01:13:24 +00:00
33f658e088 provide progress 2023-08-28 07:39:41 +10:00
0b46c34abe Probe video format 2023-08-27 07:08:31 +10:00
f1ad20cb0b Change hiding workshops from 14 to 8 days old 2023-08-27 06:50:30 +10:00
511da54909 dont force refresh alll files 2023-08-25 20:08:09 +10:00
104407646c fix missing filter 2023-08-25 19:48:36 +10:00
622229cfc9 fixes 2023-08-25 11:30:57 +10:00
f50e6ad209 dependency updates 2023-08-24 22:17:44 +10:00
d7529cef80 updated to media management 2023-08-24 22:14:43 +10:00
dependabot[bot]
f7432158e1 Bump square/square from 29.0.0.20230720 to 30.0.0.20230816
Bumps [square/square](https://github.com/square/square-php-sdk) from 29.0.0.20230720 to 30.0.0.20230816.
- [Release notes](https://github.com/square/square-php-sdk/releases)
- [Changelog](https://github.com/square/square-php-sdk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/square-php-sdk/compare/29.0.0.20230720...30.0.0.20230816)

---
updated-dependencies:
- dependency-name: square/square
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-16 00:34:01 +00:00
dependabot[bot]
2df6597771 Bump laravel-vite-plugin from 0.7.8 to 0.8.0
Bumps [laravel-vite-plugin](https://github.com/laravel/vite-plugin) from 0.7.8 to 0.8.0.
- [Release notes](https://github.com/laravel/vite-plugin/releases)
- [Changelog](https://github.com/laravel/vite-plugin/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/vite-plugin/compare/v0.7.8...v0.8.0)

---
updated-dependencies:
- dependency-name: laravel-vite-plugin
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 00:44:20 +00:00
60a15c2227 cleanup slug formatting 2023-08-14 10:06:08 +10:00
a369db9ca1 move css out of app.blade.php 2023-08-14 10:02:01 +10:00
dependabot[bot]
ac35d61ae2 Bump eslint-config-prettier from 8.9.0 to 9.0.0
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.9.0 to 9.0.0.
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.9.0...v9.0.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-13 10:22:44 +00:00
489668a2ff dependency updates 2023-08-13 20:21:52 +10:00
c9087d5df4 cleanup 2023-08-13 19:39:56 +10:00
ac06b3700c cleanup 2023-08-13 19:37:47 +10:00
31578f5ed3 cleanup 2023-08-13 18:58:52 +10:00
9b178ade4b use generateVariants in model 2023-08-13 07:58:19 +10:00
92522b5494 added generateVariants 2023-08-13 07:57:20 +10:00
ccebb4eb73 dont distort thumbnail 2023-08-13 07:39:36 +10:00
16873e7477 move generateThumbnail to model 2023-08-13 07:36:34 +10:00
79318e2f28 cleanup 2023-08-13 07:09:55 +10:00
f44a4f5d9d resize pagination 2023-08-13 07:05:29 +10:00
b28925079b add margin to pagination bottom 2023-08-13 07:05:22 +10:00
cbf6803812 Merge pull request #174 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.2.1 2023-08-01 12:27:01 +10:00
dependabot[bot]
a0e804aa62 Bump @typescript-eslint/parser from 6.2.0 to 6.2.1
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 02:26:18 +00:00
d1b87bd64b Merge pull request #175 from STEMMechanics/dependabot/npm_and_yarn/knip-2.17.2 2023-08-01 12:25:57 +10:00
5b783035a3 Merge pull request #173 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.54.1 2023-08-01 12:25:38 +10:00
a06363da75 Merge pull request #172 from STEMMechanics/dependabot/npm_and_yarn/sass-1.64.2 2023-08-01 12:25:11 +10:00
a68c691f75 Merge pull request #171 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.2.1 2023-08-01 12:24:53 +10:00
dependabot[bot]
8a61d258fb Bump knip from 2.17.1 to 2.17.2
Bumps [knip](https://github.com/webpro/knip) from 2.17.1 to 2.17.2.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.17.1...2.17.2)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 00:27:18 +00:00
dependabot[bot]
fd3f220752 Bump unocss from 0.54.0 to 0.54.1
Bumps [unocss](https://github.com/unocss/unocss) from 0.54.0 to 0.54.1.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.54.0...v0.54.1)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 00:25:37 +00:00
dependabot[bot]
0a0b2927ae Bump sass from 1.64.1 to 1.64.2
Bumps [sass](https://github.com/sass/dart-sass) from 1.64.1 to 1.64.2.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.64.1...1.64.2)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 00:25:03 +00:00
dependabot[bot]
4c19773818 Bump @typescript-eslint/eslint-plugin from 6.2.0 to 6.2.1
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 00:24:46 +00:00
James Collins
071af03577 Merge pull request #170 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-vue-9.16.1
Bump eslint-plugin-vue from 9.16.0 to 9.16.1
2023-07-31 11:06:23 +10:00
James Collins
58da0b54b3 Merge pull request #169 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.54.0
Bump unocss from 0.53.6 to 0.54.0
2023-07-31 11:06:10 +10:00
dependabot[bot]
528ea4bcfb Bump eslint-plugin-vue from 9.16.0 to 9.16.1
Bumps [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) from 9.16.0 to 9.16.1.
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v9.16.0...v9.16.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-vue
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 01:05:16 +00:00
dependabot[bot]
ca124d34cd Bump unocss from 0.53.6 to 0.54.0
Bumps [unocss](https://github.com/unocss/unocss) from 0.53.6 to 0.54.0.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.53.6...v0.54.0)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 01:04:51 +00:00
70b53ce21a clean up attributes 2023-07-31 10:05:13 +10:00
6dc226ab0b do not send email on unit testing 2023-07-31 10:05:04 +10:00
d6524942f7 fix permissions vs permissions() 2023-07-31 09:33:23 +10:00
3ca5e81e34 dependency updates 2023-07-30 07:20:19 +10:00
561b5ad1b9 install clockwork for dev 2023-07-30 07:15:01 +10:00
229bb9a5e0 fix arrays 2023-07-30 07:15:01 +10:00
280d3e9043 Update HasAttachments.php 2023-07-30 07:03:16 +10:00
a2384f4b35 caching 2023-07-29 23:04:14 +10:00
d65bf5bcd5 mobile fix 2023-07-28 15:37:04 +10:00
e763a9140c fix search bar on mobile 2023-07-28 14:59:22 +10:00
3a06a375ef fix on mobiles 2023-07-28 14:56:20 +10:00
bdf3f38190 improve table on mobile 2023-07-28 14:06:34 +10:00
5b2f6e44b1 fix label padding 2023-07-28 14:06:27 +10:00
250401fd62 show image loader/errors 2023-07-28 13:46:40 +10:00
c1fb03add1 Merge pull request #168 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-46.4.5 2023-07-28 10:25:08 +10:00
dependabot[bot]
56bf7efcef Bump eslint-plugin-jsdoc from 46.4.4 to 46.4.5
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 46.4.4 to 46.4.5.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v46.4.4...v46.4.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-28 00:24:19 +00:00
cc0508683e Merge pull request #167 from STEMMechanics/dependabot/npm_and_yarn/eslint-config-prettier-8.9.0 2023-07-28 10:23:36 +10:00
dependabot[bot]
b232b65860 Bump eslint-config-prettier from 8.8.0 to 8.9.0
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.8.0 to 8.9.0.
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.8.0...v8.9.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-28 00:19:25 +00:00
406d1d31c0 fix typedefs 2023-07-28 09:42:03 +10:00
f8fe5c92aa cleanup 2023-07-28 09:29:05 +10:00
69623bd248 add variant support for thumbnails 2023-07-28 09:28:54 +10:00
6d4995074b attachments do not have users 2023-07-28 08:40:39 +10:00
ac94068864 cleanuip 2023-07-28 08:38:41 +10:00
31ed355d64 cleanup 2023-07-28 08:17:33 +10:00
8a54fb272a remove old code 2023-07-27 22:23:05 +10:00
6ecf807081 update method name 2023-07-27 22:22:46 +10:00
728472b897 expose 2023-07-27 22:21:01 +10:00
30a8c8a03a wait until mounted 2023-07-27 22:13:47 +10:00
00e7490037 test 2023-07-27 22:12:04 +10:00
1d152d730a fix form progress 2023-07-27 22:04:17 +10:00
a010d91da2 show error 2023-07-27 21:59:17 +10:00
3717248764 fixed flatten 2023-07-27 21:55:35 +10:00
27753e903b added exception handling 2023-07-27 20:58:38 +10:00
b621f71b54 remove mail logging 2023-07-27 20:43:16 +10:00
d4b3300b88 update config 2023-07-27 19:48:04 +10:00
242fb9dda0 added email logging 2023-07-27 19:47:09 +10:00
4f505cd155 fix BelongsTo association 2023-07-27 19:44:09 +10:00
dca70a0f53 fix bad mimetype requests 2023-07-27 19:37:45 +10:00
b9a8c826ec pass in accepts to show relevant files 2023-07-27 16:06:13 +10:00
363deb3ca7 fix showing error on empty 2023-07-27 15:50:55 +10:00
f77b5f7556 fix accepts 2023-07-27 15:50:46 +10:00
d60efe38e2 add uploads to selection list 2023-07-27 15:37:32 +10:00
f779342e02 fix z-index and add delete button 2023-07-27 15:29:35 +10:00
204e62b3bb fix z-index 2023-07-27 15:29:28 +10:00
5adc24f997 dont shrink 2023-07-27 15:09:58 +10:00
ab25b0f64a update selection details on change 2023-07-27 15:07:24 +10:00
dd8e59cd4f thumbnail support 2023-07-27 14:36:46 +10:00
0c4c36eb74 dependency updates 2023-07-27 06:28:43 +10:00
James Collins
3481f10033 Merge pull request #166 from STEMMechanics/dependabot/composer/laravel/framework-10.16.0
Bump laravel/framework from 10.15.0 to 10.16.0
2023-07-26 11:03:38 +10:00
James Collins
fdf61fef3d Merge pull request #165 from STEMMechanics/dependabot/npm_and_yarn/knip-2.17.0
Bump knip from 2.16.1 to 2.17.0
2023-07-26 11:03:22 +10:00
James Collins
30c3c5d33f Merge pull request #164 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-6.2.0
Bump @typescript-eslint/parser from 6.1.0 to 6.2.0
2023-07-26 11:03:09 +10:00
dependabot[bot]
6cd7df79d9 Bump @typescript-eslint/parser from 6.1.0 to 6.2.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-26 01:02:30 +00:00
James Collins
b5b0b5d7bd Merge pull request #162 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.2.0
Bump @typescript-eslint/eslint-plugin from 6.1.0 to 6.2.0
2023-07-26 11:01:53 +10:00
James Collins
d0266c7d0c Merge pull request #161 from STEMMechanics/dependabot/npm_and_yarn/vite-4.4.7
Bump vite from 4.4.6 to 4.4.7
2023-07-26 11:01:38 +10:00
dependabot[bot]
283fd30c19 Bump vite from 4.4.6 to 4.4.7
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.6 to 4.4.7.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.7/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-26 01:00:23 +00:00
James Collins
5d13135bd0 Merge pull request #160 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.53.6
Bump unocss from 0.53.5 to 0.53.6
2023-07-26 10:59:46 +10:00
dependabot[bot]
6c2961eef6 Bump laravel/framework from 10.15.0 to 10.16.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.15.0 to 10.16.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.15.0...v10.16.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-26 00:39:12 +00:00
dependabot[bot]
f9c006403e Bump knip from 2.16.1 to 2.17.0
Bumps [knip](https://github.com/webpro/knip) from 2.16.1 to 2.17.0.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.16.1...2.17.0)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-26 00:11:54 +00:00
dependabot[bot]
1f65f0fe30 Bump @typescript-eslint/eslint-plugin from 6.1.0 to 6.2.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.2.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-25 00:42:34 +00:00
dependabot[bot]
a49a287855 Bump unocss from 0.53.5 to 0.53.6
Bumps [unocss](https://github.com/unocss/unocss) from 0.53.5 to 0.53.6.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.53.5...v0.53.6)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-25 00:41:48 +00:00
bf7f830f9e fix formatted date 2023-07-24 20:25:27 +10:00
ffce564a47 fix info box icon shrinkage 2023-07-24 20:25:27 +10:00
2cdcd9a424 fix button types not displayed correctly 2023-07-24 20:25:27 +10:00
ffbc733571 fix undefined method 2023-07-24 15:02:13 +10:00
3ea7188253 updated logo 2023-07-24 13:05:57 +10:00
97c6a4c4ef cleanup 2023-07-24 12:51:34 +10:00
f3fe112427 fix params 2023-07-24 12:39:29 +10:00
189e4ef230 set null value to empty string 2023-07-24 12:36:34 +10:00
d35b895ff4 incorrect table name 2023-07-24 12:35:12 +10:00
c47c511674 fix bad call to gallery() 2023-07-24 12:32:55 +10:00
20be21c87d allow nullable useragent 2023-07-24 12:31:16 +10:00
1d57dc519f fix margin 2023-07-24 12:13:12 +10:00
644b42afe9 enable form on error 2023-07-24 12:12:15 +10:00
9ad11f24c2 update event controller to save attachments 2023-07-24 11:58:10 +10:00
1e2564f753 open links in new window 2023-07-24 11:52:58 +10:00
f1ab544aae fix attachments editor not shown 2023-07-24 11:50:04 +10:00
James Collins
aa85d24952 Merge pull request #159 from STEMMechanics/dependabot/npm_and_yarn/pinia-plugin-persistedstate-3.2.0
Bump pinia-plugin-persistedstate from 3.1.0 to 3.2.0
2023-07-24 11:48:41 +10:00
dependabot[bot]
b0f8817aae Bump pinia-plugin-persistedstate from 3.1.0 to 3.2.0
Bumps [pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/prazdevs/pinia-plugin-persistedstate/releases)
- [Commits](https://github.com/prazdevs/pinia-plugin-persistedstate/compare/v3.1.0...v3.2.0)

---
updated-dependencies:
- dependency-name: pinia-plugin-persistedstate
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 01:48:25 +00:00
James Collins
b9e3e9f5f2 Merge pull request #158 from STEMMechanics/dependabot/npm_and_yarn/knip-2.16.1
Bump knip from 2.16.0 to 2.16.1
2023-07-24 11:48:21 +10:00
dependabot[bot]
ea05f5992d Bump knip from 2.16.0 to 2.16.1
Bumps [knip](https://github.com/webpro/knip) from 2.16.0 to 2.16.1.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.16.0...2.16.1)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 01:48:14 +00:00
James Collins
9c138d6bee Merge pull request #157 from STEMMechanics/dependabot/npm_and_yarn/sass-1.64.1
Bump sass from 1.64.0 to 1.64.1
2023-07-24 11:47:44 +10:00
James Collins
7325880a70 Merge pull request #156 from STEMMechanics/dependabot/npm_and_yarn/postcss-8.4.27
Bump postcss from 8.4.26 to 8.4.27
2023-07-24 11:47:30 +10:00
James Collins
320631e91d Merge pull request #155 from STEMMechanics/dependabot/npm_and_yarn/vite-4.4.6
Bump vite from 4.4.5 to 4.4.6
2023-07-24 11:47:09 +10:00
James Collins
0997864cd6 Merge pull request #154 from STEMMechanics/dependabot/composer/doctrine/dbal-3.6.5
Bump doctrine/dbal from 3.6.4 to 3.6.5
2023-07-24 11:46:50 +10:00
James Collins
9e0451d541 Merge pull request #149 from STEMMechanics/dependabot/composer/square/square-29.0.0.20230720
Bump square/square from 28.0.1.20230608 to 29.0.0.20230720
2023-07-24 11:46:35 +10:00
dependabot[bot]
84245c5584 Bump sass from 1.64.0 to 1.64.1
Bumps [sass](https://github.com/sass/dart-sass) from 1.64.0 to 1.64.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.64.0...1.64.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 00:56:49 +00:00
dependabot[bot]
d72c0ea9f5 Bump postcss from 8.4.26 to 8.4.27
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.26 to 8.4.27.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.26...8.4.27)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 00:56:24 +00:00
dependabot[bot]
bf9500f960 Bump vite from 4.4.5 to 4.4.6
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.5 to 4.4.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 00:56:11 +00:00
dependabot[bot]
f18cda6c00 Bump doctrine/dbal from 3.6.4 to 3.6.5
Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.6.4 to 3.6.5.
- [Release notes](https://github.com/doctrine/dbal/releases)
- [Commits](https://github.com/doctrine/dbal/compare/3.6.4...3.6.5)

---
updated-dependencies:
- dependency-name: doctrine/dbal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-24 00:48:53 +00:00
0ab20a75ac duplicates should be draft, fix hour column 2023-07-21 11:34:48 +10:00
133a6ed4ea added duplication support 2023-07-21 11:30:16 +10:00
bc424b7a00 update event to new attachments API 2023-07-21 11:25:35 +10:00
be3c6d89ee Fix #150 2023-07-21 11:18:08 +10:00
d814ed1972 use transparent background instead of white 2023-07-21 11:10:07 +10:00
8322229001 dependency updates 2023-07-21 10:54:45 +10:00
da2a76d6cf only show current events if date is empty 2023-07-21 10:52:16 +10:00
dependabot[bot]
abf7a2783c Bump square/square from 28.0.1.20230608 to 29.0.0.20230720
Bumps [square/square](https://github.com/square/square-php-sdk) from 28.0.1.20230608 to 29.0.0.20230720.
- [Release notes](https://github.com/square/square-php-sdk/releases)
- [Changelog](https://github.com/square/square-php-sdk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/square-php-sdk/compare/28.0.1.20230608...29.0.0.20230720)

---
updated-dependencies:
- dependency-name: square/square
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-20 00:36:30 +00:00
6690c69efe fix sqlite error 2023-07-19 17:04:40 +10:00
67044b7cf9 use variant thumb 2023-07-19 15:53:58 +10:00
048d3af39b dont show duplicates 2023-07-19 15:35:10 +10:00
816989d472 display initial items in editor 2023-07-19 15:31:16 +10:00
8f6310b463 added delete item button 2023-07-19 15:19:35 +10:00
3cebdd838b fix typecasting 2023-07-19 15:05:56 +10:00
9996404e29 missing trait 2023-07-19 15:00:07 +10:00
1598efac35 updated attachments 2023-07-19 14:56:56 +10:00
bfacb86f35 allow uploads 2023-07-19 12:48:17 +10:00
James Collins
e5e5c7e19c Merge pull request #145 from STEMMechanics/dependabot/composer/mockery/mockery-1.6.3
Bump mockery/mockery from 1.6.2 to 1.6.3
2023-07-19 12:12:55 +10:00
dependabot[bot]
9ede1d7eea Bump mockery/mockery from 1.6.2 to 1.6.3
Bumps [mockery/mockery](https://github.com/mockery/mockery) from 1.6.2 to 1.6.3.
- [Release notes](https://github.com/mockery/mockery/releases)
- [Changelog](https://github.com/mockery/mockery/blob/1.6.x/CHANGELOG.md)
- [Commits](https://github.com/mockery/mockery/compare/1.6.2...1.6.3)

---
updated-dependencies:
- dependency-name: mockery/mockery
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-19 00:19:04 +00:00
ff8cf83f1b fix test 2023-07-18 19:36:17 +10:00
326c8e7b81 migrate configuration 2023-07-18 19:34:03 +10:00
daeecfbd4f allow image upload 2023-07-18 19:16:59 +10:00
15c330c784 dependency updates 2023-07-18 18:44:27 +10:00
7ba80ccc58 fixes 2023-07-18 18:41:17 +10:00
ef4efe723f gallery support 2023-07-18 18:37:49 +10:00
64ef8e9acd removed gallery item 2023-07-18 18:36:12 +10:00
d88b6f6e95 changed attachment to addendum 2023-07-18 18:36:12 +10:00
440d66322c add drop column 2023-07-18 18:36:12 +10:00
James Collins
469a646ae3 changed layout for consistency 2023-07-15 21:56:56 +10:00
9cb9ebbe4f fix robots seo to not follow/index authenticated pages 2023-07-14 14:12:27 +10:00
James Collins
d004855dd8 Merge pull request #132 from STEMMechanics/dependabot/npm_and_yarn/postcss-8.4.26
Bump postcss from 8.4.25 to 8.4.26
2023-07-14 11:16:10 +10:00
dependabot[bot]
911645c9f5 Bump postcss from 8.4.25 to 8.4.26
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.25 to 8.4.26.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.25...8.4.26)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 01:13:15 +00:00
James Collins
6a16e78d80 Merge pull request #133 from STEMMechanics/dependabot/npm_and_yarn/knip-2.15.5
Bump knip from 2.15.2 to 2.15.5
2023-07-14 11:12:32 +10:00
937c5024cb add support to convert HEIC files 2023-07-14 11:09:46 +10:00
dependabot[bot]
7e12ba1a00 Bump knip from 2.15.2 to 2.15.5
Bumps [knip](https://github.com/webpro/knip) from 2.15.2 to 2.15.5.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.15.2...2.15.5)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-14 00:16:15 +00:00
89d57bb915 better handling of selection list 2023-07-14 08:57:02 +10:00
a111387a3f fix date in banner not using UTC 2023-07-13 20:10:06 +10:00
234fcb13af fix lists in html 2023-07-13 13:11:15 +10:00
377fdad6e0 allow uploading of images 2023-07-13 13:00:12 +10:00
68020b0201 fix small block 2023-07-13 11:46:43 +10:00
f0628c5c05 fix small block 2023-07-13 11:28:00 +10:00
66d2a2c48c fix display small 2023-07-13 11:25:52 +10:00
6f1229418e added small option 2023-07-13 11:19:56 +10:00
a430fee568 fix page padding 2023-07-13 08:28:08 +10:00
53b7ce651e updated minecraft information 2023-07-13 07:34:17 +10:00
1028064abe fix link underline 2023-07-12 22:54:22 +10:00
ab285870e3 package fixes 2023-07-12 22:41:12 +10:00
1a02d46151 add support for multiple selections 2023-07-12 22:30:44 +10:00
1bb70bbe66 fix bubble menu 2023-07-12 22:30:37 +10:00
c158155194 fix setValidationResult 2023-07-12 22:30:12 +10:00
7bfd4c1198 added mimeMatches 2023-07-12 22:29:51 +10:00
ea959d1a10 fix alignment on small screens 2023-07-12 22:29:43 +10:00
9fc5d81877 fix toolbar on mobile 2023-07-12 13:43:24 +10:00
719aac6727 fix shorthand time parsing 2023-07-12 13:29:19 +10:00
c8398920c5 bubble updates 2023-07-12 12:52:48 +10:00
James Collins
55bd914b8f Merge pull request #126 from STEMMechanics/dependabot/npm_and_yarn/vite-4.4.3
Bump vite from 4.4.2 to 4.4.3
2023-07-12 11:29:42 +10:00
dependabot[bot]
2b06a52705 Bump vite from 4.4.2 to 4.4.3
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.2 to 4.4.3.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.3/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 01:27:06 +00:00
James Collins
2c9c997d5a Merge pull request #119 from STEMMechanics/dependabot/npm_and_yarn/vite-plugin-compression2-0.10.2
Bump vite-plugin-compression2 from 0.9.3 to 0.10.2
2023-07-12 11:26:29 +10:00
James Collins
17f305d9cb Merge pull request #128 from STEMMechanics/dependabot/composer/laravel/sail-1.23.1
Bump laravel/sail from 1.23.0 to 1.23.1
2023-07-12 11:26:13 +10:00
James Collins
44d071696f Merge pull request #127 from STEMMechanics/dependabot/npm_and_yarn/knip-2.15.2
Bump knip from 2.15.1 to 2.15.2
2023-07-12 11:25:55 +10:00
dependabot[bot]
fa8f44135c Bump vite-plugin-compression2 from 0.9.3 to 0.10.2
Bumps [vite-plugin-compression2](https://github.com/nonzzz/vite-compression-plugin) from 0.9.3 to 0.10.2.
- [Release notes](https://github.com/nonzzz/vite-compression-plugin/releases)
- [Changelog](https://github.com/nonzzz/vite-plugin-compression/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nonzzz/vite-compression-plugin/compare/v0.9.3...v0.10.2)

---
updated-dependencies:
- dependency-name: vite-plugin-compression2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 01:25:52 +00:00
dependabot[bot]
b38e79ef8f Bump laravel/sail from 1.23.0 to 1.23.1
Bumps [laravel/sail](https://github.com/laravel/sail) from 1.23.0 to 1.23.1.
- [Release notes](https://github.com/laravel/sail/releases)
- [Changelog](https://github.com/laravel/sail/blob/1.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sail/compare/v1.23.0...v1.23.1)

---
updated-dependencies:
- dependency-name: laravel/sail
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 01:25:41 +00:00
James Collins
e2e39fbdf5 Merge pull request #123 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-6.0.0
Bump @typescript-eslint/eslint-plugin from 5.61.0 to 6.0.0
2023-07-12 11:25:35 +10:00
James Collins
a8262932cc Merge pull request #117 from STEMMechanics/dependabot/npm_and_yarn/vitest-0.33.0
Bump vitest from 0.32.4 to 0.33.0
2023-07-12 11:24:55 +10:00
James Collins
6d3e9b3c1d Merge pull request #129 from STEMMechanics/dependabot/composer/laravel/framework-10.15.0
Bump laravel/framework from 10.14.1 to 10.15.0
2023-07-12 11:24:41 +10:00
James Collins
b91619801d Merge pull request #130 from STEMMechanics/dependabot/composer/laravel/pint-1.10.4
Bump laravel/pint from 1.10.3 to 1.10.4
2023-07-12 11:24:26 +10:00
dependabot[bot]
f1e32096f3 Bump laravel/pint from 1.10.3 to 1.10.4
Bumps [laravel/pint](https://github.com/laravel/pint) from 1.10.3 to 1.10.4.
- [Release notes](https://github.com/laravel/pint/releases)
- [Changelog](https://github.com/laravel/pint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/pint/compare/v1.10.3...v1.10.4)

---
updated-dependencies:
- dependency-name: laravel/pint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 00:48:53 +00:00
dependabot[bot]
f5a327e72c Bump laravel/framework from 10.14.1 to 10.15.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.14.1 to 10.15.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.14.1...v10.15.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 00:48:49 +00:00
4fe05e39f7 updates 2023-07-12 10:21:45 +10:00
dependabot[bot]
c3779bf371 Bump knip from 2.15.1 to 2.15.2
Bumps [knip](https://github.com/webpro/knip) from 2.15.1 to 2.15.2.
- [Release notes](https://github.com/webpro/knip/releases)
- [Changelog](https://github.com/webpro/knip/blob/main/docs/release-notes-v2.md)
- [Commits](https://github.com/webpro/knip/compare/2.15.1...2.15.2)

---
updated-dependencies:
- dependency-name: knip
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-12 00:20:21 +00:00
54aa7e249e fix allowUploads permission 2023-07-12 09:11:04 +10:00
1744d192b5 fix error on url 2023-07-11 21:55:01 +10:00
3f7426c550 fix class 2023-07-11 21:52:29 +10:00
c4e017c7b7 fix content parsing 2023-07-11 21:50:49 +10:00
e723831548 added bubble menu 2023-07-11 21:50:33 +10:00
56b5dcd7d8 fix ignore allowUpload in file drop 2023-07-11 19:34:07 +10:00
dependabot[bot]
913d229630 Bump @typescript-eslint/eslint-plugin from 5.61.0 to 6.0.0
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.61.0 to 6.0.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.0.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 09:32:05 +00:00
3dfb11d692 dependency updates 2023-07-11 19:31:09 +10:00
759ab14899 fix calculation 2023-07-11 19:29:08 +10:00
329ff7c478 fix incorrect key 2023-07-11 19:28:59 +10:00
a6022f7251 final media dialog 2023-07-11 19:22:18 +10:00
d345be889e work 2023-07-11 16:37:04 +10:00
2dbe9955d9 added info api 2023-07-11 10:36:57 +10:00
dependabot[bot]
8fcd33e0a1 Bump vitest from 0.32.4 to 0.33.0
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 0.32.4 to 0.33.0.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v0.33.0/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-10 06:05:41 +00:00
14aa5e3b28 additons 2023-07-10 16:05:00 +10:00
2cb9aac070 dependency updates 2023-07-10 08:38:08 +10:00
1c6a5c9d04 editor expansion 2023-07-07 22:54:34 +10:00
936aabf412 dependency updates 2023-07-07 18:37:06 +10:00
fa7478a5b5 remove bad dependency 2023-07-07 18:36:36 +10:00
8992554ba6 started toolbar 2023-07-07 16:40:23 +10:00
c8895137fa show loading icon 2023-07-07 11:31:43 +10:00
f8bc75f1f9 fix styling 2023-07-07 11:27:23 +10:00
43faa0f020 styling editor 2023-07-07 11:22:04 +10:00
8e76a18590 add loader option 2023-07-07 11:14:17 +10:00
9c1df26b4b remove obsolete css 2023-07-07 11:14:07 +10:00
6d89a499b1 pagination bar margin bottom 2023-07-07 09:54:32 +10:00
03430c272f reduce posts to 18 2023-07-07 09:52:04 +10:00
baf15296ce add toast loaders 2023-07-07 09:44:12 +10:00
56f74964ed removed mdpreview and added SMHTML 2023-07-07 07:21:14 +10:00
afad2df8f5 cleanup 2023-07-07 07:12:32 +10:00
d17ff1f2e7 dependency updates 2023-07-07 07:12:25 +10:00
4d9be34b4e changed to TipTap 2023-07-06 13:53:24 +10:00
James Collins
5213b28c2e Merge pull request #116 from STEMMechanics/dependabot/npm_and_yarn/prettier-3.0.0
Bump prettier from 2.8.8 to 3.0.0
2023-07-06 10:34:05 +10:00
dependabot[bot]
e0df5a53dc Bump prettier from 2.8.8 to 3.0.0
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.0.0)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-06 00:30:28 +00:00
James Collins
f13022ee1d update dependencies 2023-07-06 00:08:39 +00:00
James Collins
c063badb38 install tiptap dep 2023-07-06 00:06:35 +00:00
James Collins
693cf4cd2a remove md-editor 2023-07-06 00:05:15 +00:00
cc70b1a67f update dependencies 2023-07-04 09:28:41 +10:00
08d3366fe1 remove display name 2023-07-04 09:25:53 +10:00
080b2fcfc4 fixed bad link 2023-07-02 10:17:25 +10:00
5b1d02e3c1 reload value when late change 2023-07-01 19:36:55 +10:00
b322a405c7 fix form 2023-07-01 19:32:22 +10:00
0ed05b103b added 2023-07-01 19:32:15 +10:00
5431da3930 fix offset 2023-06-23 19:09:41 +10:00
2a6e5b7992 fix md-editor css crossover 2023-06-23 19:07:56 +10:00
85af95a8a0 dont wrap action column 2023-06-23 18:55:00 +10:00
e0b04a57ae fix starts at column not showing correct relative date 2023-06-23 18:53:57 +10:00
0533cd24fe fix relative dates in the future 2023-06-23 18:53:44 +10:00
9598031dd1 replace copy icon 2023-06-23 18:32:51 +10:00
9f808717d2 fix page padding 2023-06-23 18:30:32 +10:00
b4aa71b81b fix margin pagination 2023-06-23 12:07:55 +10:00
James Collins
321a8f0946 Merge pull request #98 from STEMMechanics/dependabot/npm_and_yarn/sass-1.63.6
Bump sass from 1.63.1 to 1.63.6
2023-06-23 11:32:38 +10:00
James Collins
93124cdad0 Merge pull request #99 from STEMMechanics/dependabot/npm_and_yarn/unocss-0.53.3
Bump unocss from 0.53.1 to 0.53.3
2023-06-23 11:32:17 +10:00
dependabot[bot]
26eae9b1cf Bump unocss from 0.53.1 to 0.53.3
Bumps [unocss](https://github.com/unocss/unocss) from 0.53.1 to 0.53.3.
- [Release notes](https://github.com/unocss/unocss/releases)
- [Commits](https://github.com/unocss/unocss/compare/v0.53.1...v0.53.3)

---
updated-dependencies:
- dependency-name: unocss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-23 01:09:48 +00:00
f803bc0a59 fix editor passing changes 2023-06-23 10:50:12 +10:00
be5925f40d margin below pagination 2023-06-23 10:20:50 +10:00
b25b697e7b disable payments 2023-06-23 10:12:13 +10:00
66e2a68cde added open_at for events 2023-06-23 09:54:52 +10:00
673f6051c1 disable cart icon 2023-06-23 09:48:09 +10:00
0478ab9eb2 fix incorrect select image control 2023-06-23 09:43:09 +10:00
b7fde520be add type=button to button elements 2023-06-23 08:44:44 +10:00
6f031f78e8 remove component 2023-06-23 08:40:45 +10:00
2f850ce152 remove last SMButton 2023-06-23 08:40:18 +10:00
dependabot[bot]
a6240a3ca9 Bump sass from 1.63.1 to 1.63.6
Bumps [sass](https://github.com/sass/dart-sass) from 1.63.1 to 1.63.6.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.63.1...1.63.6)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-22 21:57:27 +00:00
8906936e51 updates 2023-06-23 07:56:45 +10:00
fd6867740e fix preload 2023-06-22 21:46:13 +10:00
183231206b add loader 2023-06-22 17:42:04 +10:00
d4e832b526 show loader 2023-06-22 17:28:16 +10:00
667ff5cf94 rewrite 2023-06-22 17:16:22 +10:00
6d2db21a62 added api error callback with toast display 2023-06-12 13:13:38 +10:00
df398faddb fix permission check 2023-06-12 11:45:41 +10:00
e07e2d2e2c check item exists in object 2023-06-12 11:45:33 +10:00
ca29189f9e fix formatting 2023-06-12 11:45:20 +10:00
James Collins
15a1a3f666 Merge pull request #82 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-46.2.6
Bump eslint-plugin-jsdoc from 46.2.4 to 46.2.6
2023-06-08 11:21:11 +10:00
James Collins
8c4c09bc90 Merge pull request #81 from STEMMechanics/dependabot/npm_and_yarn/sass-1.63.1
Bump sass from 1.62.1 to 1.63.1
2023-06-08 11:20:58 +10:00
James Collins
5a926d2d41 Merge pull request #79 from STEMMechanics/dependabot/composer/laravel/pint-1.10.1
Bump laravel/pint from 1.10.0 to 1.10.1
2023-06-08 11:20:42 +10:00
James Collins
5127d8b283 Merge pull request #77 from STEMMechanics/dependabot/npm_and_yarn/vitest-0.32.0
Bump vitest from 0.31.4 to 0.32.0
2023-06-08 11:20:28 +10:00
dependabot[bot]
c043a43fc5 Bump eslint-plugin-jsdoc from 46.2.4 to 46.2.6
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 46.2.4 to 46.2.6.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v46.2.4...v46.2.6)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-08 01:18:52 +00:00
dependabot[bot]
013930d7c3 Bump sass from 1.62.1 to 1.63.1
Bumps [sass](https://github.com/sass/dart-sass) from 1.62.1 to 1.63.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.62.1...1.63.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-08 01:18:20 +00:00
James Collins
6b0d66be25 Merge pull request #80 from STEMMechanics/dependabot/composer/mockery/mockery-1.6.2
Bump mockery/mockery from 1.6.1 to 1.6.2
2023-06-08 11:11:58 +10:00
dependabot[bot]
3b492d2005 Bump mockery/mockery from 1.6.1 to 1.6.2
Bumps [mockery/mockery](https://github.com/mockery/mockery) from 1.6.1 to 1.6.2.
- [Release notes](https://github.com/mockery/mockery/releases)
- [Changelog](https://github.com/mockery/mockery/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mockery/mockery/compare/1.6.1...1.6.2)

---
updated-dependencies:
- dependency-name: mockery/mockery
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-08 01:08:18 +00:00
dependabot[bot]
29f4bfd3cc Bump laravel/pint from 1.10.0 to 1.10.1
Bumps [laravel/pint](https://github.com/laravel/pint) from 1.10.0 to 1.10.1.
- [Release notes](https://github.com/laravel/pint/releases)
- [Changelog](https://github.com/laravel/pint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/laravel/pint/compare/v1.10.0...v1.10.1)

---
updated-dependencies:
- dependency-name: laravel/pint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-07 01:10:20 +00:00
dependabot[bot]
86e42c36cb Bump vitest from 0.31.4 to 0.32.0
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 0.31.4 to 0.32.0.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v0.32.0/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-07 01:08:47 +00:00
James Collins
c1d81c65d2 Merge pull request #74 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-5.59.9
Bump @typescript-eslint/eslint-plugin from 5.59.8 to 5.59.9
2023-06-06 11:08:00 +10:00
dependabot[bot]
fd864b03d9 Bump @typescript-eslint/eslint-plugin from 5.59.8 to 5.59.9
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.59.8 to 5.59.9.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.9/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 01:07:42 +00:00
James Collins
97eb51a434 Merge pull request #73 from STEMMechanics/dependabot/composer/mockery/mockery-1.6.1
Bump mockery/mockery from 1.6.0 to 1.6.1
2023-06-06 11:07:29 +10:00
James Collins
76f9b96369 Merge pull request #72 from STEMMechanics/dependabot/composer/laravel/framework-10.13.2
Bump laravel/framework from 10.13.1 to 10.13.2
2023-06-06 11:07:16 +10:00
James Collins
13e5cf2133 Merge pull request #75 from STEMMechanics/dependabot/npm_and_yarn/vite-plugin-compression2-0.9.2
Bump vite-plugin-compression2 from 0.9.1 to 0.9.2
2023-06-06 11:07:00 +10:00
James Collins
1c92f6449e Merge pull request #76 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-5.59.9
Bump @typescript-eslint/parser from 5.59.8 to 5.59.9
2023-06-06 11:06:46 +10:00
dependabot[bot]
3ed6cc8d5c Bump @typescript-eslint/parser from 5.59.8 to 5.59.9
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.59.8 to 5.59.9.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.9/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 01:06:17 +00:00
dependabot[bot]
5b79e415e0 Bump vite-plugin-compression2 from 0.9.1 to 0.9.2
Bumps [vite-plugin-compression2](https://github.com/nonzzz/vite-compression-plugin) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/nonzzz/vite-compression-plugin/releases)
- [Changelog](https://github.com/nonzzz/vite-plugin-compression/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nonzzz/vite-compression-plugin/compare/v0.9.1...v0.9.2)

---
updated-dependencies:
- dependency-name: vite-plugin-compression2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 01:06:02 +00:00
dependabot[bot]
98036c7266 Bump mockery/mockery from 1.6.0 to 1.6.1
Bumps [mockery/mockery](https://github.com/mockery/mockery) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/mockery/mockery/releases)
- [Changelog](https://github.com/mockery/mockery/blob/1.6.1/CHANGELOG.md)
- [Commits](https://github.com/mockery/mockery/compare/1.6.0...1.6.1)

---
updated-dependencies:
- dependency-name: mockery/mockery
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 01:05:46 +00:00
dependabot[bot]
8c8c59d8bd Bump laravel/framework from 10.13.1 to 10.13.2
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.13.1 to 10.13.2.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.13.1...v10.13.2)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 01:05:36 +00:00
fdbadbac7f added convertFileNameToTitle 2023-06-06 10:47:21 +10:00
9d788f919a show draft banner correctly 2023-06-05 20:15:45 +10:00
fac00bc4f6 support tbc, tbd 2023-06-05 19:55:47 +10:00
6e511fc4a9 support TBC/TBD 2023-06-05 19:53:11 +10:00
2f6214c48d convert dates from utc before parsing 2023-06-05 19:46:50 +10:00
b2f791fc5f remove debug 2023-06-05 19:09:51 +10:00
39140611ca fix combined filters and empty values 2023-06-05 19:09:36 +10:00
567ee3062b cleanup 2023-06-05 18:55:30 +10:00
584e0903c8 log exception and continue 2023-06-05 18:55:20 +10:00
8990006d4c remove s3 disk 2023-06-05 18:55:08 +10:00
7feb78ba70 dependency updates 2023-06-05 18:25:09 +10:00
d67ca133eb fix incorrect JsonResponse 2023-06-05 15:48:47 +10:00
f95557aa3a updated 2023-06-05 15:28:30 +10:00
f539ab7294 dependency updates 2023-06-05 15:05:45 +10:00
James Collins
79284e2271 Merge pull request #71 from STEMMechanics/dependabot/npm_and_yarn/vue-loader-17.2.2
Bump vue-loader from 17.1.1 to 17.2.2
2023-06-05 12:11:34 +10:00
James Collins
e303b565fc Merge pull request #62 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/parser-5.59.8
Bump @typescript-eslint/parser from 5.59.7 to 5.59.8
2023-06-05 12:11:16 +10:00
dependabot[bot]
985e8a5cd6 Bump vue-loader from 17.1.1 to 17.2.2
Bumps [vue-loader](https://github.com/vuejs/vue-loader) from 17.1.1 to 17.2.2.
- [Release notes](https://github.com/vuejs/vue-loader/releases)
- [Changelog](https://github.com/vuejs/vue-loader/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-loader/compare/v17.1.1...v17.2.2)

---
updated-dependencies:
- dependency-name: vue-loader
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 02:09:12 +00:00
dependabot[bot]
541e1c4c2c Bump @typescript-eslint/parser from 5.59.7 to 5.59.8
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.59.7 to 5.59.8.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.8/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 02:04:46 +00:00
James Collins
10c1d500f3 Merge pull request #67 from STEMMechanics/dependabot/composer/laravel/framework-10.13.1
Bump laravel/framework from 10.12.0 to 10.13.1
2023-06-05 12:00:19 +10:00
James Collins
678f16788c Merge pull request #68 from STEMMechanics/dependabot/composer/phpunit/phpunit-10.2.0
Bump phpunit/phpunit from 10.1.3 to 10.2.0
2023-06-05 12:00:02 +10:00
James Collins
8871a1b7ae Merge pull request #69 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-46.2.4
Bump eslint-plugin-jsdoc from 45.0.0 to 46.2.4
2023-06-05 11:59:40 +10:00
James Collins
05c2f28f25 Merge pull request #70 from STEMMechanics/dependabot/composer/doctrine/dbal-3.6.3
Bump doctrine/dbal from 3.6.2 to 3.6.3
2023-06-05 11:59:26 +10:00
James Collins
30179fe353 Merge pull request #61 from STEMMechanics/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-5.59.8
Bump @typescript-eslint/eslint-plugin from 5.59.7 to 5.59.8
2023-06-05 11:58:46 +10:00
James Collins
6846dd760d Merge pull request #59 from STEMMechanics/dependabot/npm_and_yarn/vue-router-4.2.2
Bump vue-router from 4.2.1 to 4.2.2
2023-06-05 11:58:33 +10:00
dependabot[bot]
408f285cf3 Bump doctrine/dbal from 3.6.2 to 3.6.3
Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/doctrine/dbal/releases)
- [Commits](https://github.com/doctrine/dbal/compare/3.6.2...3.6.3)

---
updated-dependencies:
- dependency-name: doctrine/dbal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 01:40:07 +00:00
dependabot[bot]
fa76fc0f78 Bump eslint-plugin-jsdoc from 45.0.0 to 46.2.4
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 45.0.0 to 46.2.4.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v45.0.0...v46.2.4)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 01:40:02 +00:00
dependabot[bot]
ade9cd6b05 Bump phpunit/phpunit from 10.1.3 to 10.2.0
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 10.1.3 to 10.2.0.
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.2.0/ChangeLog-10.2.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/10.1.3...10.2.0)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 01:40:01 +00:00
dependabot[bot]
933d18b784 Bump laravel/framework from 10.12.0 to 10.13.1
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.12.0 to 10.13.1.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.12.0...v10.13.1)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-05 01:39:55 +00:00
48bae3b181 remove debug 2023-06-03 18:40:22 +10:00
78f6ed1ef6 allow : in filter values 2023-06-03 18:38:12 +10:00
6d503939a5 temp filter fix 2023-06-03 08:39:12 +10:00
3677f1c45b fix upcoming events filter 2023-06-02 20:44:42 +10:00
dependabot[bot]
a23ce4e0e6 Bump @typescript-eslint/eslint-plugin from 5.59.7 to 5.59.8
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.59.7 to 5.59.8.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.8/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-30 01:07:19 +00:00
dependabot[bot]
e7c43fa53a Bump vue-router from 4.2.1 to 4.2.2
Bumps [vue-router](https://github.com/vuejs/router) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/compare/v4.2.1...v4.2.2)

---
updated-dependencies:
- dependency-name: vue-router
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-30 01:05:49 +00:00
James Collins
0de6735855 Merge pull request #58 from STEMMechanics/dependabot/npm_and_yarn/postcss-8.4.24
Bump postcss from 8.4.23 to 8.4.24
2023-05-29 12:20:49 +10:00
James Collins
aa274b1df4 Merge pull request #57 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-45.0.0
Bump eslint-plugin-jsdoc from 44.2.7 to 45.0.0
2023-05-29 12:20:34 +10:00
dependabot[bot]
51261a4a5c Bump postcss from 8.4.23 to 8.4.24
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.23 to 8.4.24.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.23...8.4.24)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-29 01:44:28 +00:00
dependabot[bot]
9e92561502 Bump eslint-plugin-jsdoc from 44.2.7 to 45.0.0
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 44.2.7 to 45.0.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v44.2.7...v45.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-29 01:43:37 +00:00
2b28ebc014 dependency updates 2023-05-27 12:41:37 +10:00
196d9c358c Merge pull request #56 from STEMMechanics:dependabot/composer/spatie/laravel-ignition-2.1.3
Bump spatie/laravel-ignition from 2.1.2 to 2.1.3
2023-05-27 12:38:44 +10:00
dependabot[bot]
38d58d92b4 Bump spatie/laravel-ignition from 2.1.2 to 2.1.3
Bumps [spatie/laravel-ignition](https://github.com/spatie/laravel-ignition) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/spatie/laravel-ignition/releases)
- [Changelog](https://github.com/spatie/laravel-ignition/blob/main/CHANGELOG.md)
- [Commits](https://github.com/spatie/laravel-ignition/compare/2.1.2...2.1.3)

---
updated-dependencies:
- dependency-name: spatie/laravel-ignition
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-26 01:14:39 +00:00
e136c910b5 support analytics dashboard 2023-05-25 21:54:59 +10:00
d0c4f7eea2 allow updating ended_at 2023-05-25 21:54:46 +10:00
bf9b0f3973 update session ended_at on new requests 2023-05-25 21:54:37 +10:00
4534b46e97 added AA key for uppercase AM/PM 2023-05-25 21:27:36 +10:00
68affe4e4c update table field names 2023-05-25 20:04:53 +10:00
aa2671f167 reset server error on reload 2023-05-25 20:04:38 +10:00
2178b61602 updated analytics structure 2023-05-25 19:35:20 +10:00
6a6b8ed9b2 added rename macro to Request 2023-05-25 19:35:05 +10:00
784e8cf787 added unmangle request params 2023-05-25 19:34:40 +10:00
89a8b6926a update getVariantsAttribute return type 2023-05-25 12:21:23 +10:00
9c926d15c1 updated dependencies 2023-05-25 12:19:19 +10:00
James Collins
1b1144c628 Merge pull request #55 from STEMMechanics/dependabot/npm_and_yarn/vue-dompurify-html-4.1.4
Bump vue-dompurify-html from 3.1.2 to 4.1.4
2023-05-25 12:16:29 +10:00
James Collins
e9b1802af3 Merge pull request #54 from STEMMechanics/dependabot/npm_and_yarn/vuepic/vue-datepicker-5.1.2
Bump @vuepic/vue-datepicker from 3.6.8 to 5.1.2
2023-05-25 12:16:16 +10:00
James Collins
fe7c1d93ae Merge pull request #53 from STEMMechanics/dependabot/npm_and_yarn/vitest-0.31.1
Bump vitest from 0.28.5 to 0.31.1
2023-05-25 12:09:09 +10:00
James Collins
8d1be827a7 Merge pull request #52 from STEMMechanics/dependabot/npm_and_yarn/typescript-5.0.4
Bump typescript from 4.9.5 to 5.0.4
2023-05-25 12:08:43 +10:00
dependabot[bot]
cd4fe13117 Bump vue-dompurify-html from 3.1.2 to 4.1.4
Bumps [vue-dompurify-html](https://github.com/LeSuisse/vue-dompurify-html/tree/HEAD/packages/vue-dompurify-html) from 3.1.2 to 4.1.4.
- [Release notes](https://github.com/LeSuisse/vue-dompurify-html/releases)
- [Commits](https://github.com/LeSuisse/vue-dompurify-html/commits/v4.1.4/packages/vue-dompurify-html)

---
updated-dependencies:
- dependency-name: vue-dompurify-html
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 01:08:06 +00:00
dependabot[bot]
34e169adba Bump @vuepic/vue-datepicker from 3.6.8 to 5.1.2
Bumps [@vuepic/vue-datepicker](https://github.com/Vuepic/vue-datepicker) from 3.6.8 to 5.1.2.
- [Release notes](https://github.com/Vuepic/vue-datepicker/releases)
- [Commits](https://github.com/Vuepic/vue-datepicker/compare/v3.6.8...v5.1.2)

---
updated-dependencies:
- dependency-name: "@vuepic/vue-datepicker"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 01:07:58 +00:00
dependabot[bot]
d064756cc6 Bump vitest from 0.28.5 to 0.31.1
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 0.28.5 to 0.31.1.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v0.31.1/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 01:07:35 +00:00
dependabot[bot]
bf7e1658f4 Bump typescript from 4.9.5 to 5.0.4
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.5 to 5.0.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.0.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-25 01:07:21 +00:00
8de3c5dcba added .phpunit.result.cache 2023-05-25 08:20:19 +10:00
e8827cbd50 fix hinting and tests for L10 and PHP8 2023-05-25 08:18:51 +10:00
f839003f5e dependency updates 2023-05-25 07:54:35 +10:00
b68d97455b remove gunk 2023-05-25 07:54:35 +10:00
James Collins
e9dcb8b3f0 Merge pull request #51 from STEMMechanics/shift-91888
PHPUnit 10 Shift
2023-05-25 07:53:54 +10:00
Shift
5e838ad61e Define test classes as final 2023-05-24 21:53:18 +00:00
Shift
a365977702 Ignore PHPUnit cache folder 2023-05-24 21:53:17 +00:00
8b2542ebef removed obsolete recaptcha 2023-05-25 07:49:09 +10:00
James Collins
69c5018367 Merge pull request #49 from STEMMechanics/shift-91885
Laravel 10.x Shift
2023-05-25 07:47:14 +10:00
James Collins
4f536ae5a9 Merge branch 'main' into shift-91885 2023-05-25 07:46:59 +10:00
James Collins
95395d1da7 Merge pull request #50 from STEMMechanics/shift-91887
Laravel Consolidate Namespaces Shift
2023-05-25 07:38:32 +10:00
Shift
c6c639afc2 Apply code style 2023-05-24 21:36:42 +00:00
41147b26f2 dependency updates 2023-05-25 07:35:33 +10:00
Shift
fbf437ac99 Shift cleanup 2023-05-24 21:33:19 +00:00
Shift
5faf49688d Remove redundant typing from DocBlocks 2023-05-24 21:33:17 +00:00
Shift
4d7d0ed74d Add type hints from DocBlocks 2023-05-24 21:33:16 +00:00
Shift
979b9f704c Add type hints for Laravel 10 2023-05-24 21:33:15 +00:00
Shift
4124cf39db Set return type of base TestCase methods
From the [PHPUnit 8 release notes][1], the `TestCase` methods below now declare a `void` return type:

- `setUpBeforeClass()`
- `setUp()`
- `assertPreConditions()`
- `assertPostConditions()`
- `tearDown()`
- `tearDownAfterClass()`
- `onNotSuccessfulTest()`

[1]: https://phpunit.de/announcements/phpunit-8.html
2023-05-24 21:33:13 +00:00
Shift
c83e21d588 Rename password_resets table 2023-05-24 21:33:13 +00:00
Shift
c88630e9af Adopt anonymous migrations 2023-05-24 21:33:12 +00:00
Shift
40b265e145 Bump Laravel dependencies 2023-05-24 21:33:11 +00:00
Shift
3ad2b2fb8e Default config files
In an effort to make upgrading the constantly changing config files
easier, Shift defaulted them and merged your true customizations -
where ENV variables may not be used.
2023-05-24 21:33:11 +00:00
Shift
8b671065e9 Shift config files 2023-05-24 21:33:11 +00:00
Shift
028e1a191e Shift core files 2023-05-24 21:33:08 +00:00
Shift
a133f82997 Remove explicit call to register policies 2023-05-24 21:33:00 +00:00
Shift
c4f3eb9a4e Remove default lang files 2023-05-24 21:32:59 +00:00
Shift
8a52c4529f Use Faker methods
Accessing Faker properties was deprecated in Faker 1.14.
2023-05-24 21:32:59 +00:00
Shift
d0493f3dd0 Convert string references to ::class
PHP 5.5.9 adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.
2023-05-24 21:32:58 +00:00
Shift
b845552c37 Apply code style 2023-05-24 21:32:56 +00:00
4e97209494 fixes to support analytics 2023-05-25 07:18:28 +10:00
aa0b010bed ignore certain spellings 2023-05-25 07:18:28 +10:00
cb79ea64cf filter changes to support collections 2023-05-25 07:18:28 +10:00
James Collins
38409d0d63 Merge pull request #48 from STEMMechanics/dependabot/npm_and_yarn/eslint-plugin-jsdoc-44.2.5
Bump eslint-plugin-jsdoc from 39.9.1 to 44.2.5
2023-05-25 07:17:35 +10:00
James Collins
32dfb4eef3 Merge pull request #47 from STEMMechanics/dependabot/composer/guzzlehttp/guzzle-7.7.0
Bump guzzlehttp/guzzle from 7.6.1 to 7.7.0
2023-05-25 07:17:19 +10:00
James Collins
a6de64a089 Merge pull request #41 from STEMMechanics/dependabot/composer/phpunit/phpunit-10.1.3
Bump phpunit/phpunit from 9.6.7 to 10.1.3
2023-05-25 07:17:01 +10:00
James Collins
b226814676 Merge pull request #34 from STEMMechanics/dependabot/npm_and_yarn/vite-plugin-compression2-0.9.1
Bump vite-plugin-compression2 from 0.8.4 to 0.9.1
2023-05-25 07:16:45 +10:00
James Collins
805de3291b Merge pull request #30 from STEMMechanics/dependabot/npm_and_yarn/vue-final-modal-4.4.2
Bump vue-final-modal from 3.4.11 to 4.4.2
2023-05-25 07:16:13 +10:00
James Collins
b0ab63e30e Merge pull request #27 from STEMMechanics/dependabot/npm_and_yarn/prettier-2.8.8
Bump prettier from 2.8.2 to 2.8.8
2023-05-25 07:15:50 +10:00
James Collins
13bfc52b77 Merge pull request #23 from STEMMechanics/dependabot/npm_and_yarn/tinymce/tinymce-vue-5.1.0
Bump @tinymce/tinymce-vue from 4.0.7 to 5.1.0
2023-05-25 07:15:22 +10:00
dependabot[bot]
bbce78cab4 Bump phpunit/phpunit from 9.6.7 to 10.1.3
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.6.7 to 10.1.3.
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.1.3/ChangeLog-10.1.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.6.7...10.1.3)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-24 21:13:12 +00:00
James Collins
1e084d5131 Merge pull request #22 from STEMMechanics/dependabot/composer/nunomaduro/collision-7.1.0
Bump nunomaduro/collision from 6.4.0 to 7.1.0
2023-05-25 07:12:27 +10:00
dependabot[bot]
af699161da Bump eslint-plugin-jsdoc from 39.9.1 to 44.2.5
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 39.9.1 to 44.2.5.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v39.9.1...v44.2.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-24 01:11:37 +00:00
2e1c2cd0b2 added autocomplete 2023-05-22 17:31:50 +10:00
cd7366b8ff remove debug 2023-05-22 16:45:22 +10:00
ec74f6594c prettier 2023-05-22 16:29:27 +10:00
5d2e9affc0 support editing/deleting multiple items 2023-05-22 16:17:44 +10:00
06b7ce4db0 added 2023-05-22 16:17:26 +10:00
dependabot[bot]
4bf695f559 Bump guzzlehttp/guzzle from 7.6.1 to 7.7.0
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 7.6.1 to 7.7.0.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.7/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.6.1...7.7.0)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 01:46:03 +00:00
59daa1ff08 fix disabling css 2023-05-21 17:51:27 +10:00
04044673e2 added gap 2023-05-21 17:51:19 +10:00
3b837dc6b0 fix checkboxes not always checking 2023-05-21 09:27:51 +10:00
2f029e2523 dont reduce size of checkbox labels when active 2023-05-21 09:02:42 +10:00
66d477795f better handle 503 errors 2023-05-21 08:50:14 +10:00
78f23db801 updated maintenance page 2023-05-21 07:50:29 +10:00
e62a21c469 loop images 2023-05-20 22:02:49 +10:00
9756622148 fix click propagation 2023-05-20 21:57:39 +10:00
065cb1b746 added prev/next arrows 2023-05-20 21:49:43 +10:00
54a7ad86dc dependencies update 2023-05-20 20:56:44 +10:00
0e7c86ac2b fix properties on email inputs 2023-05-20 20:46:37 +10:00
e023964cb2 added media sorting to editor 2023-05-20 20:13:35 +10:00
16f4eb65ef empty sort now reverts to default instead of 503 2023-05-20 19:24:28 +10:00
11eb12324e when saving object, show original query list 2023-05-20 18:34:06 +10:00
7a0d3fc8a0 fix delete option 2023-05-20 17:57:52 +10:00
3ed2aadc34 media controller should not directly delete files 2023-05-20 17:56:48 +10:00
b2004e3483 fix not uploading multiple files 2023-05-20 17:49:04 +10:00
55f363a64f reduce gap around images 2023-05-20 16:55:55 +10:00
7a6ed9f7f4 reduce banner height 2023-05-20 16:55:47 +10:00
8fa8c85077 fix status check 2023-05-20 16:42:15 +10:00
245ffc9d45 include tinymce themes 2023-05-20 16:42:05 +10:00
6a9a2f0a9e firefox fix 2023-05-19 14:17:18 +10:00
9dbefe5a8a add page loading icon 2023-05-19 14:00:15 +10:00
cce2a79ee4 fix table name 2023-05-19 13:41:38 +10:00
8e94ab2d7d rel=prefetch 2023-05-19 13:37:32 +10:00
6e0337cdeb prefetching and performance improvements 2023-05-19 13:21:02 +10:00
1c3b8f065e remove older code 2023-05-19 13:20:53 +10:00
c43d5574b4 removed elements page 2023-05-19 12:50:49 +10:00
0e5c654b02 fix potential sql injections 2023-05-18 09:33:57 +10:00
14d6d59581 dependency updates 2023-05-16 15:29:51 +10:00
3796961293 added copy shortlink option to dropdown 2023-05-16 11:19:34 +10:00
c471a97a23 add event users 2023-05-11 16:49:12 +10:00
fc853bd5f1 add private option to attachments 2023-05-11 13:37:40 +10:00
d0ea0ae4d3 support empty values with prefixes 2023-05-11 09:14:37 +10:00
8a6d1281bb remove debug 2023-05-11 09:06:17 +10:00
8797d51ef4 default filter on status is OK 2023-05-11 09:04:58 +10:00
2c8ac1f155 Revert media status to OK 2023-05-11 09:04:39 +10:00
42706de9df added defaultFilters option 2023-05-11 09:04:23 +10:00
3ce99b8751 improve error handling on upload failures 2023-05-11 08:40:30 +10:00
44c4f16c5c fix test styling 2023-05-11 08:40:10 +10:00
cdccde528e added --loading variables 2023-05-11 08:12:32 +10:00
f32655c156 fix firefox missing :has selector 2023-05-10 20:31:53 +10:00
d7255f004d use const form 2023-05-10 20:21:16 +10:00
56a1aaa19c duplicate form object 2023-05-10 20:20:59 +10:00
86491bfb2e use seperate form id 2023-05-10 20:20:50 +10:00
8dc43ccfce support form-id and check form exists 2023-05-10 20:20:34 +10:00
7ff49700fd support form-id 2023-05-10 20:20:27 +10:00
e14c7aafb3 added status page link 2023-05-10 12:42:21 +10:00
0f727168be dependency updates 2023-05-09 14:39:30 +10:00
0de47b3104 added location url option 2023-05-09 10:58:51 +10:00
6b3eb97568 dont validate empty url strings 2023-05-09 10:58:43 +10:00
bd4ba41b0b fix small screens and make full height 2023-05-09 10:30:41 +10:00
fb2f2d9739 removed forgot-username 2023-05-09 10:22:10 +10:00
a468ae01ff fix rules 2023-05-09 10:07:59 +10:00
6d534bd1c3 revert put requirements 2023-05-08 21:59:42 +10:00
31820317de check if password exists on login 2023-05-08 21:53:37 +10:00
e2efa1f1bd updated rules 2023-05-08 21:51:52 +10:00
86a0936cd4 only allow ghost users by admins 2023-05-08 21:46:07 +10:00
645b623a40 ignore id on fallback 2023-05-08 21:45:27 +10:00
96bd56a828 obsolete 2023-05-08 21:45:11 +10:00
870f1c5194 fix phone requirement 2023-05-08 20:28:26 +10:00
5d1adf7af8 support creating ghost users 2023-05-08 20:25:01 +10:00
a1170a1347 added RequiredIf option 2023-05-08 20:24:54 +10:00
9b5aab6e6e modelValue should support boolean 2023-05-08 20:08:23 +10:00
a25776fbbb fix grammer 2023-05-08 19:40:46 +10:00
54b5929aa4 forced 0 margin top 2023-05-08 19:40:41 +10:00
729fc3fd39 added shortlinks on frontend 2023-05-08 19:28:07 +10:00
b4cf05ad44 fixed error code 2023-05-08 19:28:01 +10:00
4da8b32b1a added Length 2023-05-08 19:26:02 +10:00
c35342df59 fix active watch 2023-05-08 19:18:27 +10:00
7d8d407d07 fix button dropdown colours in dark mode 2023-05-08 19:16:46 +10:00
1ceb109a28 fix append item height 2023-05-08 19:11:40 +10:00
a8181ff2b7 fix static active 2023-05-08 19:09:53 +10:00
e42c4c3023 fix row column + buttonrow 2023-05-08 17:29:22 +10:00
ff040eec58 added title and description upload support 2023-05-08 17:27:01 +10:00
5d663d21b3 check lastDialog exists before resolving 2023-05-08 17:26:52 +10:00
b73c2d3726 emit value if non set on init 2023-05-08 16:53:17 +10:00
ee96acbe4f use modelValue to automatic selection changes 2023-05-08 16:39:42 +10:00
fd22b79d42 dynamic disabling 2023-05-08 16:39:27 +10:00
99f56b9ef8 cleanup hovering 2023-05-08 16:09:52 +10:00
9a686c1112 added tab-color-hover 2023-05-08 16:09:44 +10:00
ffcf823a7f reduced top margin 2023-05-08 15:16:50 +10:00
a85c4bf115 added no-help property 2023-05-08 15:16:25 +10:00
29d7167c24 fix borders 2023-05-08 15:11:09 +10:00
3c6a570394 fix label padding on small controls 2023-05-08 14:43:46 +10:00
419fa322a3 use default alignment of toolbar 2023-05-08 14:41:34 +10:00
71a2e1b6dd update media button to medium size 2023-05-08 14:41:25 +10:00
a352c21198 fix typing 2023-05-08 12:36:11 +10:00
4accb60a24 use new format 2023-05-08 12:34:33 +10:00
88b92a9572 remove footer top margin 2023-05-08 12:32:20 +10:00
e39fa78981 cleanup 2023-05-08 12:25:59 +10:00
4205113b00 block width 100% 2023-05-08 12:25:45 +10:00
ad47efefaf cleanup 2023-05-08 12:21:03 +10:00
890399dd74 set default first/last name 2023-05-08 12:20:57 +10:00
2698ede55e added fallback 2023-05-08 12:11:20 +10:00
c9f0ea2512 remove macros 2023-05-08 12:11:14 +10:00
228f9c7c6b remove obsolete fields 2023-05-08 12:11:09 +10:00
63e05e924a fix footer on small displays 2023-05-08 11:16:56 +10:00
a66cde3934 show form errors 2023-05-08 11:14:53 +10:00
0b8a2904ec cleaned up 2023-05-08 11:14:44 +10:00
5fffa97ea7 lightened danger lighter 2023-05-08 11:14:36 +10:00
1d14d86d8e added 2023-05-08 11:14:21 +10:00
217ab89667 fix padding 2023-05-08 10:43:48 +10:00
ac2dd23ad7 remove usernames 2023-05-08 10:40:48 +10:00
7a4f72378d control-help div always shown 2023-05-08 10:40:33 +10:00
8190839823 added new rules 2023-05-08 10:40:04 +10:00
4e9d97268f remove any query items 2023-05-06 22:38:32 +10:00
985f7c94da force ssl and remove obsolete stuff 2023-05-06 22:38:24 +10:00
3d28e73369 added used counter 2023-05-06 18:29:03 +10:00
4076b138b9 wrong schema 2023-05-06 18:23:24 +10:00
dependabot[bot]
99d4c709bd Bump nunomaduro/collision from 6.4.0 to 7.1.0
Bumps [nunomaduro/collision](https://github.com/nunomaduro/collision) from 6.4.0 to 7.1.0.
- [Release notes](https://github.com/nunomaduro/collision/releases)
- [Changelog](https://github.com/nunomaduro/collision/blob/v7.x/CHANGELOG.md)
- [Commits](https://github.com/nunomaduro/collision/compare/v6.4.0...v7.1.0)

---
updated-dependencies:
- dependency-name: nunomaduro/collision
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-06 08:21:01 +00:00
93951cfbc8 shortlink support 2023-05-06 18:20:17 +10:00
4ac86c434e added phpdotenv 2023-05-06 18:17:07 +10:00
171cfa7aab added table 2023-05-06 18:16:53 +10:00
a494dbe662 remove recapcha statement 2023-05-06 15:30:33 +10:00
c9d02fb11c dont parse data 2023-05-05 21:35:02 +10:00
3ba65385c5 override padding 2023-05-04 19:02:09 +10:00
58a2da1996 updated homepage 2023-05-04 18:58:53 +10:00
845d6ba12b use correct timezone 2023-05-04 18:46:58 +10:00
f0b55b7b2e added total to UserCollection 2023-05-04 16:49:32 +10:00
e6dd75c2a8 dont show 4th card on single column 2023-05-04 06:52:03 +10:00
7b7154085e dependency updates 2023-05-04 06:48:06 +10:00
1c119e80e9 fix style colouring 2023-05-04 06:46:15 +10:00
3d86f859c6 darkmode support and new variables 2023-05-03 21:49:55 +10:00
0bfad00df7 fix saving attachments 2023-05-03 20:46:14 +10:00
64efa723b3 fix incorrect index 2023-05-03 20:46:07 +10:00
0072b28965 updated front page layout 2023-05-03 20:23:35 +10:00
21fa5d24af added 3rd accent 2023-05-03 20:23:19 +10:00
16ec3c515e added align-items-stretch 2023-05-03 20:23:13 +10:00
6868144e25 fix identifying sessions 2023-05-03 07:35:55 +10:00
0e5af96900 added use 2023-05-02 21:42:25 +10:00
ded5caf271 restructure api request 2023-05-02 21:31:30 +10:00
e8e1e91d1c update the media value url 2023-05-02 21:05:07 +10:00
6a16d545ec remove debug 2023-05-02 20:51:05 +10:00
976b6fbb78 update image gallery 2023-05-02 20:49:36 +10:00
efc5571fb3 hide container when no toasts are present 2023-05-02 20:28:43 +10:00
6ad4b3a6c4 embed variant types into Media model 2023-05-02 19:16:39 +10:00
cc0fe080cf analytics backend update 2023-05-01 19:04:08 +10:00
dependabot[bot]
1de89fba5f Bump vite-plugin-compression2 from 0.8.4 to 0.9.1
Bumps [vite-plugin-compression2](https://github.com/nonzzz/vite-compression-plugin) from 0.8.4 to 0.9.1.
- [Release notes](https://github.com/nonzzz/vite-compression-plugin/releases)
- [Changelog](https://github.com/nonzzz/vite-compression-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nonzzz/vite-compression-plugin/compare/v0.8.4...v0.9.1)

---
updated-dependencies:
- dependency-name: vite-plugin-compression2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 01:25:02 +00:00
0c668c9c62 fix styling on smaller screens 2023-04-28 08:57:17 +10:00
6a3c3a3566 fix small screen layout 2023-04-27 16:51:52 +10:00
e17f79e0b1 improve small screen layout 2023-04-27 16:51:46 +10:00
f0461fb65f update to buttonrow 2023-04-27 16:51:38 +10:00
aa38927522 upgrade to large 2023-04-27 15:57:01 +10:00
881d06deea reduce margin for edit button 2023-04-27 15:45:32 +10:00
683869214b added view opton 2023-04-27 15:43:36 +10:00
3322a6e005 added margin between buttons 2023-04-27 15:33:17 +10:00
65a48454ba missing button-block class 2023-04-27 15:33:11 +10:00
0de8e17593 declare time before usage 2023-04-27 14:42:21 +10:00
17beb4152b fix helper text 2023-04-27 14:42:13 +10:00
b09097294f fix const 2023-04-27 14:09:33 +10:00
c6e1b0248d performance improvements 2023-04-27 14:05:34 +10:00
0a956e1fc5 show large images 2023-04-27 13:35:02 +10:00
e2dee426bf fix test expectation 2023-04-27 13:33:29 +10:00
37a738c094 fix toTitleCase 2023-04-27 13:31:02 +10:00
bef4c3440b performance improvements 2023-04-27 13:24:40 +10:00
b36ad8042f use webp image 2023-04-27 08:34:50 +10:00
6ec38853ff store images locally by default 2023-04-27 07:25:13 +10:00
69144a665f updated config 2023-04-27 06:55:33 +10:00
382a1d0ef8 move cdn 2023-04-27 05:47:23 +10:00
41c751a76d just use medium size 2023-04-26 21:45:34 +10:00
01e46042fb change to webp 2023-04-26 21:42:01 +10:00
f1a28b6efe change to webp 2023-04-26 21:41:43 +10:00
7fddeeeaae dont force webp as original is not 2023-04-26 21:16:33 +10:00
bacf35bb4b use webp 2023-04-26 21:15:27 +10:00
4a83c7e171 explicitly use webp 2023-04-26 20:58:39 +10:00
3cbce25394 performance improvements 2023-04-26 20:34:04 +10:00
dependabot[bot]
c2b58cc82d Bump vue-final-modal from 3.4.11 to 4.4.2
Bumps [vue-final-modal](https://github.com/vue-final/vue-final-modal/tree/HEAD/packages/vue-final-modal) from 3.4.11 to 4.4.2.
- [Release notes](https://github.com/vue-final/vue-final-modal/releases)
- [Changelog](https://github.com/vue-final/vue-final-modal/blob/master/packages/vue-final-modal/CHANGELOG.md)
- [Commits](https://github.com/vue-final/vue-final-modal/commits/v4.4.2/packages/vue-final-modal)

---
updated-dependencies:
- dependency-name: vue-final-modal
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-26 10:26:28 +00:00
ac326d2d74 disable recaptcha 2023-04-26 20:25:38 +10:00
50aaf8b343 added analytics box 2023-04-26 20:08:25 +10:00
f667ac6430 fix margins 2023-04-26 20:01:50 +10:00
e2e599ed35 bugfixes 2023-04-26 20:00:19 +10:00
897e422e15 dont replace some statuses after end 2023-04-26 19:55:24 +10:00
0031be6882 add progress text 2023-04-26 19:55:10 +10:00
45880ed7a8 remove debug 2023-04-26 18:52:39 +10:00
b7e964174a add upload progress 2023-04-26 18:52:23 +10:00
77b8f60cb1 fix styling 2023-04-26 18:52:16 +10:00
4cbde00ef3 added disabled to other types 2023-04-26 18:32:15 +10:00
196472181e added disabled class 2023-04-26 18:32:05 +10:00
2fa7a0c7a5 update fields when file changes 2023-04-26 18:19:11 +10:00
38e982e70b fix styling 2023-04-26 18:08:35 +10:00
8a9b57547a fix double search 2023-04-26 18:01:20 +10:00
6dd3d6255d fix small styling 2023-04-26 18:01:13 +10:00
656de567d7 fix css for disabled input 2023-04-26 17:54:16 +10:00
24e80d7851 fix hero loading in edit 2023-04-26 17:47:22 +10:00
bc642b48da move edit button higher 2023-04-26 17:45:41 +10:00
cc07998a8a bugfix temp file creation 2023-04-26 17:33:34 +10:00
178309bb1e updated autoload 2023-04-26 17:33:23 +10:00
40c19f47c7 added temp helper 2023-04-26 17:33:16 +10:00
7f82b24b0c fix css priority 2023-04-26 16:02:35 +10:00
f31a8da0e1 added edit button 2023-04-26 13:22:20 +10:00
8ed158ab3c input select shows current value 2023-04-26 12:30:47 +10:00
08af379a57 bug fixes 2023-04-26 12:29:34 +10:00
79dbdd3e5a fix margin 2023-04-26 12:29:28 +10:00
f7e8d5bdf7 remove obsolete options 2023-04-26 12:29:23 +10:00
52eba56e34 remove obsolete variable 2023-04-26 12:13:39 +10:00
4c42276deb bug fixes 2023-04-26 12:00:26 +10:00
b4eb772662 whitespacing 2023-04-26 12:00:11 +10:00
825730c3f9 reduce margins on medium size 2023-04-26 12:00:04 +10:00
b7a2253b01 add userHasPermission helper 2023-04-26 11:59:53 +10:00
ce1174d41b remove download options 2023-04-26 11:32:02 +10:00
f2da168a03 updated 2023-04-26 11:29:22 +10:00
fec4b29261 updated 2023-04-26 11:29:18 +10:00
01b8dadd5f rounded corners 2023-04-26 11:29:06 +10:00
3ee97468f9 change posts to articles 2023-04-26 10:57:27 +10:00
c6d318bbc3 use large instead of scaled image 2023-04-26 09:38:31 +10:00
4ebb07a79a fix missing calc 2023-04-26 09:35:34 +10:00
2580d0874f bug fixes 2023-04-25 19:34:01 +10:00
2168e693d8 support dark-mode 2023-04-25 19:24:20 +10:00
bc2a25346b dont display if no items 2023-04-25 11:57:39 +10:00
03e969e08c fix icon spacing 2023-04-25 11:55:18 +10:00
37e3872782 fix margins on small devices 2023-04-25 11:44:29 +10:00
71442e4160 remove debug code 2023-04-25 11:39:40 +10:00
c2b69a769a use new range input 2023-04-24 21:56:31 +10:00
c0bc0e03c0 added range type 2023-04-24 21:56:25 +10:00
f49bef1112 added rules 2023-04-24 21:30:37 +10:00
191b2978ec update css 2023-04-24 21:23:25 +10:00
2771cdd053 remove debug 2023-04-24 20:53:33 +10:00
2d576645d8 update community images and links 2023-04-24 19:21:09 +10:00
be9884b468 set dialog width 2023-04-24 18:31:04 +10:00
df280ce7a6 change discord button name 2023-04-24 18:29:50 +10:00
c1182b3b90 fix classes 2023-04-24 15:38:58 +10:00
425a3561ac change SMFooter to SMPageFooter 2023-04-24 15:37:11 +10:00
12be354cc9 remove sm- prefix 2023-04-24 15:25:36 +10:00
7e2917d447 obsolete 2023-04-24 15:25:31 +10:00
cb0de6a2d5 obsolete 2023-04-24 15:21:48 +10:00
95318d1b36 update SMFormFooter to SMButtonRow 2023-04-24 15:21:05 +10:00
b92456c178 update all SMHeaders 2023-04-24 14:59:59 +10:00
bcb25b5d5e grammar 2023-04-24 14:42:31 +10:00
6a79204204 update position 2023-04-24 14:41:48 +10:00
d3776a8d3f bugfix SMHeader scroll 2023-04-24 14:40:48 +10:00
325c6a0448 update to new SMHeader 2023-04-24 14:14:49 +10:00
7c089eed80 remove old smheading 2023-04-24 14:14:43 +10:00
8b40a46c1b added component 2023-04-24 14:11:33 +10:00
ef4061b96c updates rules page 2023-04-24 13:40:59 +10:00
dependabot[bot]
506849b450 Bump prettier from 2.8.2 to 2.8.8
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.2 to 2.8.8.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.2...2.8.8)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 02:25:08 +00:00
dependabot[bot]
e73ce8c943 Bump @tinymce/tinymce-vue from 4.0.7 to 5.1.0
Bumps [@tinymce/tinymce-vue](https://github.com/tinymce/tinymce-vue) from 4.0.7 to 5.1.0.
- [Release notes](https://github.com/tinymce/tinymce-vue/releases)
- [Changelog](https://github.com/tinymce/tinymce-vue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tinymce/tinymce-vue/compare/4.0.7...5.1.0)

---
updated-dependencies:
- dependency-name: "@tinymce/tinymce-vue"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 02:24:28 +00:00
bb4543bc65 dependency update 2023-04-24 12:24:09 +10:00
James Collins
f8d5850a89 Create dependabot.yml 2023-04-24 12:24:03 +10:00
cce994d35c added minecraft curve 2023-04-24 12:18:06 +10:00
02cfb53147 Added SMSocialIcons component 2023-04-24 12:16:48 +10:00
0755df03cf use exact active class 2023-04-24 10:35:28 +10:00
51f0ad7497 only add variant if created 2023-04-24 09:53:47 +10:00
b4a49d20c8 fix styling 2023-04-24 08:40:41 +10:00
44ccaf10d4 test for NaN price 2023-04-24 08:22:29 +10:00
967c14b93a bug fixes 2023-04-23 20:44:11 +10:00
0e42fc657b missing handleinput on select 2023-04-23 20:37:02 +10:00
2d7a91e368 fix params.id 2023-04-23 20:35:31 +10:00
072ab038fe fix missimg media icon and select styling 2023-04-23 20:34:52 +10:00
6723c27d5e ignore missing media 2023-04-23 20:28:17 +10:00
f5fc700886 typos 2023-04-23 20:25:15 +10:00
96a5ba0ceb media create 2023-04-23 20:21:08 +10:00
dfe5e72526 fix event create 2023-04-23 20:20:07 +10:00
d1cbebee84 sort oldest to newest 2023-04-23 20:02:23 +10:00
eac313feb8 footer spacing 2023-04-23 20:00:23 +10:00
a71ed56cf2 align text center 2023-04-23 19:57:08 +10:00
e3bc72e8d2 bugfix 2023-04-23 19:55:39 +10:00
0fadfed7f6 bug fixes 2023-04-23 19:53:10 +10:00
031db78590 bug fixes 2023-04-23 19:25:52 +10:00
6fd32fb84b support small 2023-04-23 16:42:58 +10:00
98e6464be6 support media input 2023-04-23 16:19:15 +10:00
52ce2afad2 added media type 2023-04-23 16:19:05 +10:00
28f89c9469 cleanup 2023-04-23 16:18:57 +10:00
6f7de8da66 reduce margin 2023-04-23 15:42:10 +10:00
50caf2753d added checkbox 2023-04-23 15:42:05 +10:00
30c0caa04d FormControl value is know unknown 2023-04-23 15:41:53 +10:00
e53d8c14a9 added Booleanish 2023-04-23 15:41:41 +10:00
eca89358db show status 2023-04-23 14:35:45 +10:00
1e58c71e67 fix search fields 2023-04-23 14:32:20 +10:00
43beaefc07 reverse sort 2023-04-23 14:32:00 +10:00
f74faadace fix date range filter 2023-04-23 14:30:05 +10:00
77aa622610 bug fixes 2023-04-23 13:56:27 +10:00
95aadd45ee bug fixes 2023-04-23 12:18:14 +10:00
89880016ea loading icon 2023-04-22 22:34:35 +10:00
beb91553ef min height 2023-04-22 22:31:05 +10:00
b2037c9575 css updates 2023-04-22 22:25:42 +10:00
ce4cec5589 fix 2023-04-22 21:25:04 +10:00
e8a597ec6b disable dark mode temp 2023-04-22 21:21:25 +10:00
a663e2bd56 updates 2023-04-22 21:18:07 +10:00
84bfd3cda2 updates 2023-04-21 15:46:12 +10:00
3dfe96fa89 updated css 2023-04-21 11:49:37 +10:00
93cbcef93f updated 2023-04-21 11:37:20 +10:00
5c758536a4 renamed 2023-04-21 11:37:13 +10:00
bc5a9aa9f1 remove image 2023-04-21 11:37:05 +10:00
b8ed77f6d5 add option to replace existing files 2023-04-21 10:07:17 +10:00
6c25cd029f added support to ignore existing files 2023-04-21 10:05:40 +10:00
68d59eda69 fix migration rename column issues 2023-04-21 09:58:05 +10:00
2534d4c159 dependency update 2023-04-21 08:55:32 +10:00
54252e768c dependency updates 2023-04-21 07:12:41 +10:00
7a2f263061 updates 2023-04-21 07:11:00 +10:00
5ae6e02ce8 updates 2023-04-19 22:31:47 +10:00
fb9944ef14 lots of changes 2023-04-19 16:26:13 +10:00
190493179f cleanup 2023-04-19 14:52:32 +10:00
4b1bc23622 added loading support 2023-04-19 14:49:15 +10:00
2ad5b04a48 added large option 2023-04-19 14:49:03 +10:00
afbbbcb4d1 remove debug 2023-04-19 14:28:23 +10:00
820c3aec9d remove debug permission 2023-04-19 14:27:31 +10:00
eafbcd8389 cleanup 2023-04-19 14:26:37 +10:00
f0459b3f6e cleanup 2023-04-19 14:26:27 +10:00
ff93265890 show banners and dates 2023-04-19 13:40:38 +10:00
320e282dc8 added banner colors 2023-04-19 13:40:29 +10:00
d23c911c78 fix ul margin 2023-04-19 13:13:51 +10:00
51df812a6c add display_name support 2023-04-19 09:40:35 +10:00
a96aba57f7 add php test debugging 2023-04-19 09:40:20 +10:00
36c71da4bb lots o updates 2023-04-18 21:47:44 +10:00
b53fca9648 removed dataset 2023-04-18 17:04:24 +10:00
9fafb8bd2a removed 2023-04-18 17:03:33 +10:00
41c7ba35a0 table width 100% 2023-04-18 16:59:57 +10:00
4cc5702da7 updated text 2023-04-18 15:47:17 +10:00
65f626f15e added cod 2023-04-18 15:47:09 +10:00
2abf6f67af added cod 2023-04-18 15:47:04 +10:00
72cde997ab added italic, updated small 2023-04-18 15:46:54 +10:00
8b27cb4690 removed small, added li 2023-04-18 15:46:47 +10:00
fb0cec0850 fix error not applying to border 2023-04-18 15:29:25 +10:00
a9a0bfdad0 fix small div 2023-04-18 15:26:47 +10:00
00a752173d added new formcard 2023-04-18 15:24:41 +10:00
24caa9a4f4 added space-between 2023-04-18 15:24:28 +10:00
a1075e000a fix styling 2023-04-18 15:11:52 +10:00
c416902280 cleanup 2023-04-18 15:04:06 +10:00
a29d707183 toolbar should be 100% 2023-04-18 15:04:00 +10:00
69d08a85ac input should be 100% 2023-04-18 15:03:51 +10:00
475ea08517 changes! 2023-04-18 13:52:36 +10:00
b4c97c20d6 inner container items 2023-04-18 13:52:28 +10:00
f7da2c8185 override default container center 2023-04-18 13:52:19 +10:00
a1a630fc02 align container center default 2023-04-18 13:52:10 +10:00
22ef117493 missing important 2023-04-18 13:51:58 +10:00
04b80d5ff8 updated darkmode 2023-04-18 13:35:06 +10:00
b764979c3b added accent-2 dark 2023-04-18 13:34:57 +10:00
a78c0491ef added accent-2 2023-04-18 13:32:25 +10:00
6082beb964 updated 2023-04-18 13:32:16 +10:00
9d9a5fd9d2 added narrow option 2023-04-18 13:01:56 +10:00
4332f389a1 change to use body page instead of data-set 2023-04-18 13:01:45 +10:00
a26b60e726 added accent colors 2023-04-18 12:48:40 +10:00
465d76cd08 added click to hide 2023-04-18 12:48:28 +10:00
e0300148cf cleanup 2023-04-18 12:08:02 +10:00
4442c6c625 cleanup styling 2023-04-18 12:07:58 +10:00
289eb86d97 cleanup 2023-04-18 12:07:51 +10:00
59724777e9 update header sizes 2023-04-18 12:07:46 +10:00
99e0b297b2 added change emitter 2023-04-18 11:29:38 +10:00
7036747042 use center option 2023-04-18 10:44:02 +10:00
b9cd3e3f9f added transitions 2023-04-18 10:43:54 +10:00
c8e90b6887 default is start, added center option 2023-04-18 10:43:25 +10:00
56973b62f6 added extra items 2023-04-18 10:43:15 +10:00
990a13e777 fixes 2023-04-18 10:21:55 +10:00
cd37623746 cleanup 2023-04-18 10:21:45 +10:00
193620e4e4 reduce font weight 2023-04-18 09:55:34 +10:00
78d85e2440 added clear option 2023-04-18 09:55:25 +10:00
9fa9689db9 fix padding on icon only buttons 2023-04-18 09:55:16 +10:00
81fc33183c changed dropdown to chevron 2023-04-18 09:20:21 +10:00
2600011736 fix dropdown clicks and overflow 2023-04-18 09:11:25 +10:00
e5c297eb7c hide easydatatable 2023-04-18 09:11:15 +10:00
a3766aca6c apply margin-top to all h3 2023-04-18 08:29:20 +10:00
857689dc22 remove obsolete loader 2023-04-18 08:29:08 +10:00
2ed5917e96 css disabled 2023-04-18 08:29:00 +10:00
84380bf333 #app as flex 2023-04-18 08:28:53 +10:00
e7d517f264 use new table 2023-04-17 22:57:40 +10:00
40a9cc424e cleanup 2023-04-17 22:57:35 +10:00
b725bc2b5b change search button to icon 2023-04-17 22:57:28 +10:00
50306c319e added 2023-04-17 22:57:18 +10:00
c1e86c6897 added back links 2023-04-17 22:57:07 +10:00
eb02142afc bug fixes 2023-04-17 22:56:49 +10:00
5f0526eef7 cleanup 2023-04-17 19:56:39 +10:00
cbdc55df8f fix scrollbar padding 2023-04-17 19:56:33 +10:00
e0022b15c5 remove obsolete code 2023-04-17 19:56:25 +10:00
983edc53d1 update workshop route name 2023-04-17 19:38:41 +10:00
2af1dcd24e update router namespace 2023-04-17 19:38:28 +10:00
2814a5f044 fix responsive 2023-04-17 19:34:42 +10:00
802fd87850 change button to primary type 2023-04-17 19:34:34 +10:00
50a6a39632 dark mode always on home page 2023-04-17 19:28:49 +10:00
49d0d3b35a updated page 2023-04-17 16:11:57 +10:00
8017f017f2 bug fixes 2023-04-17 16:11:51 +10:00
864798be7c updated h3 2023-04-17 16:11:45 +10:00
e20ef40e02 remove input group 2023-04-17 16:01:04 +10:00
955f9021f7 updated the new input group slots 2023-04-17 15:58:37 +10:00
e006090be2 removed 2023-04-17 15:58:27 +10:00
1c6bc56e08 added prepend and append slots 2023-04-17 15:58:21 +10:00
aa2da29b4c remove input group 2023-04-17 15:19:39 +10:00
9e47d28660 bug fix 2023-04-17 15:19:33 +10:00
a5383c87c7 cleanup 2023-04-17 15:07:53 +10:00
152a637e31 update button font color 2023-04-17 15:07:45 +10:00
5d947000ca fix validator and font weight on smaller 2023-04-17 15:07:35 +10:00
bf4f378108 added cta button 2023-04-17 14:58:08 +10:00
7f03228efa added sizes to button 2023-04-17 14:57:59 +10:00
7e6fd1859e added offset option 2023-04-17 14:30:41 +10:00
979c77c1b9 bring back model function and cleanup 2023-04-17 14:26:42 +10:00
15c9603902 support new conductor features 2023-04-17 14:11:42 +10:00
20dd8bcb3a apply includes if no fields are set 2023-04-17 14:11:33 +10:00
bec4b03a17 return a blank string when name attribute 2023-04-17 13:54:37 +10:00
2686a162e7 cleanup and fields support includes fields 2023-04-17 13:54:17 +10:00
7d9c982cf5 bug fixes and updates 2023-04-17 07:16:31 +10:00
d1c09ce74e added 2023-04-13 07:39:30 +10:00
fe5f429039 dependency udates 2023-04-12 18:53:28 +10:00
8937571214 fix background colors 2023-04-12 14:08:33 +10:00
f9591951cb fix footer sheme 2023-04-12 14:08:19 +10:00
956d2a25f2 fix navbar variables 2023-04-12 14:08:10 +10:00
365bec10a6 added support for scheme 2023-04-12 13:45:14 +10:00
c69c11b0fe added base-darker 2023-04-12 13:45:08 +10:00
40b8414f8a update css 2023-04-12 13:39:08 +10:00
06cb735b68 update component 2023-04-12 13:39:03 +10:00
985f32e06e update page 2023-04-12 13:38:57 +10:00
36469b20b3 use variables 2023-04-12 13:38:28 +10:00
2173e4c6b8 update footer 2023-04-12 13:38:19 +10:00
d7a35e651e remove breadcrumb and bg reference 2023-04-12 13:38:08 +10:00
4238c977f3 added dark/light logo 2023-04-12 10:07:39 +10:00
74e9a3204f added dark/light d-none 2023-04-12 10:06:54 +10:00
7bf94ced84 added css variables 2023-04-12 09:53:41 +10:00
1b3a40c22a support css scheme 2023-04-12 09:53:28 +10:00
28bef07e37 update color 2023-04-12 09:53:05 +10:00
3b7cb57e7a fix hover and spacing css 2023-04-12 08:56:42 +10:00
3f069e6d22 removed depreciated progressbar 2023-04-12 08:49:29 +10:00
12e7269591 removed depreciated carousel 2023-04-12 08:49:20 +10:00
0127cf0a6b added fontaine 2023-04-12 08:44:54 +10:00
fd1522a2ca fix event test to specifically set status 2023-04-11 17:10:53 +10:00
c79ec065d3 update structure 2023-04-11 14:09:10 +10:00
19fe484049 fix factory 2023-04-11 14:09:03 +10:00
db3d831bc0 remove whitespace 2023-04-11 14:08:53 +10:00
d27e707044 add permission default value 2023-04-11 14:08:41 +10:00
c142440068 cleanup 2023-04-11 13:19:48 +10:00
df6456f5d2 fix error changing defaults after rename 2023-04-11 13:15:24 +10:00
1578a2b8d1 fix bad table name in drop 2023-04-11 13:14:57 +10:00
4a43c152d5 remove unused constraints 2023-04-11 13:14:50 +10:00
0d1ee37272 remove page transitions 2023-04-10 21:23:15 +10:00
5c0b97cd1e h1 align left 2023-04-10 21:23:08 +10:00
511e8d6074 update post view 2023-04-10 21:18:31 +10:00
826e4a7de2 remove breadcrumbs 2023-04-10 21:18:24 +10:00
1ac66b4ece update default background color 2023-04-10 21:18:16 +10:00
8f58de9f4e remove carousel 2023-04-10 20:52:13 +10:00
611d997df9 remove padding 2023-04-10 20:52:07 +10:00
3f66e3f1f1 remove page loader 2023-04-10 20:51:59 +10:00
6154fa5dcc added new element 2023-04-10 20:46:31 +10:00
dd0914cd89 started removal of rounded borders 2023-04-10 20:46:25 +10:00
b8000d9a64 white hamburger 2023-04-10 19:51:13 +10:00
d94bd66c54 white stem 2023-04-10 19:51:05 +10:00
2ebd2018db updated navbar design 2023-04-10 19:25:54 +10:00
04b41e16e1 added components 2023-04-10 18:03:02 +10:00
7ad73f3c84 bug fixes and support new media 2023-04-10 14:49:53 +10:00
359698d54f added apiAttachmentResource 2023-04-10 14:49:27 +10:00
26ea658f9c updated types 2023-04-10 14:49:13 +10:00
a13be0530f added media variants helper 2023-04-10 14:49:07 +10:00
b018b11c57 fix docs 2023-04-10 14:48:55 +10:00
aac023351a remove logging 2023-04-10 14:48:42 +10:00
fd2fbea03f S3 jobs 2023-04-10 14:47:53 +10:00
f3bbdec77c rewrote to support S3 2023-04-10 14:47:38 +10:00
b54ace0272 added respondAccepted 2023-04-10 14:47:09 +10:00
55bc78d9cb return fulfilled hero and user 2023-04-10 14:47:00 +10:00
fabe027d54 changed default permission from null to '' 2023-04-10 14:46:48 +10:00
b4f4450573 return fulfilled hero 2023-04-10 14:46:21 +10:00
990cc66600 support null models 2023-04-10 14:45:58 +10:00
aa76147144 added public/private aws and CF 2023-04-10 14:45:46 +10:00
ee46af08ca update media table 2023-04-10 14:44:23 +10:00
c33de944ef dependencies update 2023-04-10 14:44:08 +10:00
79e5103b08 updated config 2023-04-06 21:20:54 +10:00
4797b213ee added clamav config 2023-04-06 21:18:54 +10:00
c232042af5 use static function in Media modalk 2023-04-06 21:17:38 +10:00
252448f4a9 added uniqueFileName rule 2023-04-06 21:14:57 +10:00
ec4febe5e9 added additional rows for media table 2023-04-06 21:12:12 +10:00
35ca0d90f7 added the route macro apiAttachmentResource 2023-04-06 17:28:07 +10:00
eae3d4689b add the storage macro public 2023-04-06 17:27:29 +10:00
67c9d4084c added sunspikes/clamav-validator 2023-04-06 17:26:10 +10:00
fb52428219 update dependencies 2023-04-06 17:25:31 +10:00
23e620e168 reduce to XLarge 2023-04-06 08:52:43 +10:00
324054b3db fix button text justification 2023-04-06 08:36:40 +10:00
d9dcbeef7b preview uses thumb size 2023-04-05 19:20:04 +10:00
9b31d52d7e renamed header to Files 2023-04-05 19:18:47 +10:00
260d2d28ad support relational links 2023-04-05 15:56:58 +10:00
dd74bdda6a explicit ask for small images 2023-04-05 15:53:21 +10:00
7486390da5 show file to large error 2023-04-05 14:53:35 +10:00
410 changed files with 57088 additions and 20148 deletions

View File

@@ -38,11 +38,24 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
AWS_PUBLIC_ACCESS_KEY_ID=
AWS_PUBLIC_SECRET_ACCESS_KEY=
AWS_PUBLIC_DEFAULT_REGION="us-west-002"
AWS_PUBLIC_BUCKET=
AWS_PUBLIC_USE_PATH_STYLE_ENDPOINT=false
AWS_PUBLIC_ENDPOINT=
AWS_PUBLIC_URL=
AWS_PRIVATE_ACCESS_KEY_ID=
AWS_PRIVATE_SECRET_ACCESS_KEY=
AWS_PRIVATE_DEFAULT_REGION="us-west-002"
AWS_PRIVATE_BUCKET=
AWS_PRIVATE_USE_PATH_STYLE_ENDPOINT=false
AWS_PRIVATE_ENDPOINT=
AWS_PRIVATE_URL=
CLOUDFLARE_ZONE_ID=
CLOUDFLARE_API_KEY=
PUSHER_APP_ID=
PUSHER_APP_KEY=

15
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"

View File

@@ -11,7 +11,7 @@ jobs:
steps:
- uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
php-version: "8.2"
- uses: actions/checkout@v3
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"

15
.gitignore vendored
View File

@@ -26,7 +26,7 @@ storage/*.key
Homestead.yaml
Homestead.json
/.vagrant
.phpunit.result.cache
/.phpunit.cache
### macOS ###
# General
@@ -237,11 +237,22 @@ dist/
### This Project ###
/public/uploads
/public/build
/public/tinymce
*.key
### TinyMCE ###
/public/tinymce
!/public/tinymce/skins/ui/stemmech/
### Synk ###
.dccache
### TempCodeRunner ###
tempCodeRunnerFile.*
### PHPUnit ###
.phpunit.result.cache
.gitignore
### Codesniffer ###
phpcs.phar
phpcbf.phar

14
.ls-lint.yml Normal file
View File

@@ -0,0 +1,14 @@
ls:
resources/js/store:
.ts: pascalcase
"*":
.js: camelcase
.ts: camelcase
.vue: pascalcase
.dir: snakecase
.type.ts: camelcase
ignore:
- node_modules
- vendor
- public/build
- public/tinymce

View File

@@ -1,4 +1,5 @@
{
"bracketSameLine": true,
"tabWidth": 4
"tabWidth": 4,
"htmlWhitespaceSensitivity": "css"
}

View File

@@ -2,8 +2,7 @@
"editor.formatOnType": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
// "source.organizeImports": true // <-- when enabled, breaks tinymce required import order
"source.fixAll.eslint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[vue]": {
@@ -15,5 +14,6 @@
"[php]": {
// "editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
"editor.defaultFormatter": "wongjn.php-sniffer"
}
},
"cSpell.words": ["TIMESTAMPDIFF"]
}

23355
_ide_helper.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Conductors;
use Illuminate\Database\Eloquent\Model;
class AnalyticsConductor extends Conductor
{
/**
* The Model Class
* @var string
*/
protected $class = \App\Models\AnalyticsSession::class;
/**
* The default includes to include in a request.
*
* @var array
*/
protected $includes = ['requests.type','requests.path'];
/**
* Return if the current model is visible.
*
* @param Model $model The model.
* @return boolean Allow model to be visible.
*/
public static function viewable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/analytics') === true);
}
/**
* Return if the current model is creatable.
*
* @return boolean Allow creating model.
*/
public static function creatable(): bool
{
return true;
}
/**
* Return if the current model is updatable.
*
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/analytics') === true);
}
/**
* Return if the current model is destroyable.
*
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/analytics') === true);
}
}

View File

@@ -0,0 +1,181 @@
<?php
namespace App\Conductors;
use App\Models\Media;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\InvalidCastException;
use Illuminate\Database\Eloquent\MissingAttributeException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use LogicException;
class ArticleConductor extends Conductor
{
/**
* The Model Class
* @var string
*/
protected $class = \App\Models\Article::class;
/**
* The default sorting field
* @var string
*/
protected $sort = '-publish_at';
/**
* The included fields
*
* @var string[]
*/
protected $includes = ['attachments', 'user', 'gallery'];
/**
* Run a scope query on the collection before anything else.
*
* @param Builder $builder The builder in use.
* @return void
*/
public function scope(Builder $builder): void
{
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/articles') === false) {
$builder
->where('publish_at', '<=', now());
}
}
/**
* Return if the current model is visible.
*
* @param Model $model The model.
* @return boolean Allow model to be visible.
*/
public static function viewable(Model $model): bool
{
if (Carbon::parse($model->publish_at)->isFuture() === true) {
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/articles') === false) {
return false;
}
}
return true;
}
/**
* Return if the current model is creatable.
*
* @return boolean Allow creating model.
*/
public static function creatable(): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/articles') === true);
}
/**
* Return if the current model is updatable.
*
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/articles') === true);
}
/**
* Return if the current model is destroyable.
*
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/articles') === true);
}
/**
* Transform the final model data
*
* @param array $data The model data to transform.
* @return array The transformed model.
*/
public function transformFinal(array $data): array
{
unset($data['user_id']);
return $data;
}
/**
* Include Attachments Field.
*
* @param Model $model Them model.
* @return mixed The model result.
*/
public function includeAttachments(Model $model)
{
return $model->getAttachments()->map(function ($attachment) {
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
});
}
/**
* Include Gallery Field.
*
* @param Model $model Them model.
* @return mixed The model result.
*/
public function includeGallery(Model $model)
{
return $model->getGallery()->map(function ($item) {
return MediaConductor::includeModel(request(), 'gallery', $item->media);
});
}
/**
* Include User Field.
*
* @param Model $model Them model.
* @return mixed The model result.
*/
public function includeUser(Model $model)
{
$cacheKey = "user:{$model['user_id']}";
$user = Cache::remember($cacheKey, now()->addDays(28), function () use ($model) {
return User::find($model['user_id']);
});
return UserConductor::includeModel(request(), 'user', $user);
}
/**
* Transform the Hero field.
*
* @param mixed $value The current value.
* @return array|null The new value.
*/
public function transformHero(mixed $value): array|null
{
$cacheKey = "media:{$value}";
$media = Cache::remember($cacheKey, now()->addDays(28), function () use ($value) {
return Media::find($value);
});
return MediaConductor::includeModel(request(), 'hero', $media);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,10 +2,12 @@
namespace App\Conductors;
use App\Models\Media;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\InvalidCastException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class EventConductor extends Conductor
{
@@ -13,13 +15,19 @@ class EventConductor extends Conductor
* The Model Class
* @var string
*/
protected $class = '\App\Models\Event';
protected $class = \App\Models\Event::class;
/**
* The default sorting field
* @var string
*/
protected $sort = 'start_at';
protected $sort = '-start_at';
/**
* The included fields
* @var string[]
*/
protected $includes = ['attachments'];
/**
@@ -28,8 +36,9 @@ class EventConductor extends Conductor
* @param Builder $builder The builder in use.
* @return void
*/
public function scope(Builder $builder)
public function scope(Builder $builder): void
{
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/events') === false) {
$builder
@@ -44,9 +53,10 @@ class EventConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow model to be visible.
*/
public static function viewable(Model $model)
public static function viewable(Model $model): bool
{
if (strtolower($model->status) === 'draft' || Carbon::parse($model->publish_at)->isFuture() === true) {
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/events') === false) {
return false;
@@ -61,8 +71,9 @@ class EventConductor extends Conductor
*
* @return boolean Allow creating model.
*/
public static function creatable()
public static function creatable(): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/events') === true);
}
@@ -73,8 +84,9 @@ class EventConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model)
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/events') === true);
}
@@ -85,26 +97,44 @@ class EventConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model)
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/events') === true);
}
/**
* Transform the model
* Include Attachments Field.
*
* @param Model $model The model to transform.
* @return array The transformed model.
* @throws InvalidCastException Cannot cast item to model.
* @param Model $model Them model.
* @return mixed The model result.
*/
public function transform(Model $model)
public function includeAttachments(Model $model)
{
$result = $model->toArray();
$result['attachments'] = $model->attachments()->get()->map(function ($attachment) {
return MediaConductor::model(request(), $attachment->media);
/** @var \App\Models\User */
$user = auth()->user();
return $model->getAttachments()->map(function ($attachment) use ($user) {
if ($attachment->private === false || ($user !== null && $user->hasPermission('admin/events') === true)) {
return MediaConductor::includeModel(request(), 'attachments', $attachment->media);
}
});
}
/**
* Transform the Hero field.
*
* @param mixed $value The current value.
* @return array|null The new value.
*/
public function transformHero(mixed $value): array|null
{
$cacheKey = "media:{$value}";
$media = Cache::remember($cacheKey, now()->addDays(28), function () use ($value) {
return Media::find($value);
});
return $result;
return MediaConductor::includeModel(request(), 'hero', $media);
}
}

View File

@@ -2,8 +2,11 @@
namespace App\Conductors;
use App\Models\MediaJob;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class MediaConductor extends Conductor
{
@@ -11,7 +14,7 @@ class MediaConductor extends Conductor
* The Model Class
* @var string
*/
protected $class = '\App\Models\Media';
protected $class = \App\Models\Media::class;
/**
* The default sorting field
@@ -19,6 +22,22 @@ class MediaConductor extends Conductor
*/
protected $sort = 'created_at';
/**
* The included fields
*
* @var string[]
*/
protected $includes = ['user', 'jobs'];
/**
* The default filters to use in a request.
*
* @var array
*/
// protected $defaultFilters = [
// 'status' => 'OK'
// ];
/**
* Return an array of model fields visible to the current user.
@@ -26,13 +45,14 @@ class MediaConductor extends Conductor
* @param Model $model The model in question.
* @return array The array of field names.
*/
public function fields(Model $model)
public function fields(Model $model): array
{
$fields = parent::fields($model);
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/media') === false) {
$fields = arrayRemoveItem($fields, 'permission');
$fields = arrayRemoveItem($fields, ['security_data', 'storage']);
}
return $fields;
@@ -44,13 +64,21 @@ class MediaConductor extends Conductor
* @param Builder $builder The builder in use.
* @return void
*/
public function scope(Builder $builder)
public function scope(Builder $builder): void
{
$user = auth()->user();
if ($user === null) {
$builder->whereNull('permission');
$builder->where('security_type', '')
->orWhere('security_type', 'password');
} else {
$builder->whereNull('permission')->orWhereIn('permission', $user->permissions);
$builder->where(function ($query) use ($user) {
$query->where('security_type', '')
->orWhere('security_type', 'password')
->orWhere(function ($subquery) use ($user) {
$subquery->where('security_type', 'permission')
->whereIn('security_data', $user->permissions);
});
});
}
}
@@ -60,13 +88,16 @@ class MediaConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow model to be visible.
*/
public static function viewable(Model $model)
public static function viewable(Model $model): bool
{
if ($model->permission !== null) {
if (strcasecmp('permission', $model->security_type) === 0) {
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission($model->permission) === false) {
if ($user === null || $user->hasPermission($model->security_data) === false) {
return false;
}
} elseif ($model->security_type !== '' && strcasecmp('password', $model->security_type) !== 0) {
return false;
}
return true;
@@ -77,7 +108,7 @@ class MediaConductor extends Conductor
*
* @return boolean Allow creating model.
*/
public static function creatable()
public static function creatable(): bool
{
$user = auth()->user();
return ($user !== null);
@@ -89,10 +120,12 @@ class MediaConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model)
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && (strcasecmp($model->user_id, $user->id) === 0 || $user->hasPermission('admin/media') === true));
return ($user !== null && (strcasecmp($model->user_id, $user->id) === 0 ||
$user->hasPermission('admin/media') === true));
}
/**
@@ -101,9 +134,51 @@ class MediaConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model)
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && ($model->user_id === $user->id || $user->hasPermission('admin/media') === true));
}
/**
* Transform the final model data
*
* @param array $data The model data to transform.
* @return array The transformed model.
*/
public function transformFinal(array $data): array
{
unset($data['user_id']);
return $data;
}
/**
* Include User Field.
*
* @param Model $model Them model.
* @return mixed The model result.
*/
public function includeUser(Model $model)
{
$user = Cache::remember("user:{$model['user_id']}", now()->addDays(28), function () use ($model) {
return User::find($model['user_id']);
});
return UserConductor::includeModel(request(), 'user', $user);
}
/**
* Include job models in Media
*
* @param Model $model The reference model.
* @return mixed
*/
public function includeJobs(Model $model)
{
$jobs = $model->jobs()
->select(['id','created_at','updated_at','user_id','status','status_text','progress'])
->orderBy('created_at', 'desc')->get();
return $jobs;
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace App\Conductors;
use App\Models\MediaJob;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class MediaJobConductor extends Conductor
{
/**
* The Model Class
* @var string
*/
protected $class = \App\Models\MediaJob::class;
/**
* The default sorting field
* @var string
*/
protected $sort = 'created_at';
/**
* The included fields
*
* @var string[]
*/
protected $includes = ['user'];
/**
* Return if the current model is creatable.
*
* @return boolean Allow creating model.
*/
public static function creatable(): bool
{
return false;
}
/**
* Return if the current model is updatable.
*
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model): bool
{
return false;
}
/**
* Return if the current model is destroyable.
*
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model): bool
{
return false;
}
/**
* Transform the final model data
*
* @param array $data The model data to transform.
* @return array The transformed model.
*/
public function transformFinal(array $data): array
{
unset($data['user_id']);
return $data;
}
}

View File

@@ -1,109 +0,0 @@
<?php
namespace App\Conductors;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
class PostConductor extends Conductor
{
/**
* The Model Class
* @var string
*/
protected $class = '\App\Models\Post';
/**
* The default sorting field
* @var string
*/
protected $sort = '-publish_at';
/**
* Run a scope query on the collection before anything else.
*
* @param Builder $builder The builder in use.
* @return void
*/
public function scope(Builder $builder)
{
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/posts') === false) {
$builder
->where('publish_at', '<=', now());
}
}
/**
* Return if the current model is visible.
*
* @param Model $model The model.
* @return boolean Allow model to be visible.
*/
public static function viewable(Model $model)
{
if (Carbon::parse($model->publish_at)->isFuture() === true) {
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/posts') === false) {
return false;
}
}
return true;
}
/**
* Return if the current model is creatable.
*
* @return boolean Allow creating model.
*/
public static function creatable()
{
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/posts') === true);
}
/**
* Return if the current model is updatable.
*
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model)
{
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/posts') === true);
}
/**
* Return if the current model is destroyable.
*
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model)
{
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/posts') === true);
}
/**
* Transform the model
*
* @param Model $model The model to transform.
* @return array The transformed model.
* @throws InvalidCastException Cannot cast item to model.
*/
public function transform(Model $model)
{
$result = $model->toArray();
$result['attachments'] = $model->attachments()->get()->map(function ($attachment) {
return MediaConductor::model(request(), $attachment->media);
});
return $result;
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace App\Conductors;
use Illuminate\Database\Eloquent\Model;
class ShortlinkConductor extends Conductor
{
/**
* The Model Class
* @var string
*/
protected $class = \App\Models\Shortlink::class;
/**
* The default sorting field
* @var string
*/
protected $sort = 'created_at';
/**
* Return if the current model is creatable.
*
* @return boolean Allow creating model.
*/
public static function creatable(): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
}
/**
* Return if the current model is updatable.
*
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
}
/**
* Return if the current model is destroyable.
*
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/shortlinks') === true);
}
}

View File

@@ -10,7 +10,7 @@ class SubscriptionConductor extends Conductor
* The Model Class
* @var string
*/
protected $class = '\App\Models\Subscription';
protected $class = \App\Models\Subscription::class;
/**
@@ -19,10 +19,14 @@ class SubscriptionConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model)
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
return ($user !== null && (
(strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) ||
$user->hasPermission('admin/subscriptions') === true
));
}
/**
@@ -31,9 +35,11 @@ class SubscriptionConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model)
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 && $user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
return ($user !== null && ((strcasecmp($model->email, $user->email) === 0 &&
$user->email_verified_at !== null) || $user->hasPermission('admin/subscriptions') === true));
}
}

View File

@@ -10,7 +10,7 @@ class UserConductor extends Conductor
* The Model Class
* @var string
*/
protected $class = '\App\Models\User';
protected $class = \App\Models\User::class;
/**
@@ -19,11 +19,12 @@ class UserConductor extends Conductor
* @param Model $model The model.
* @return string[] The fields visible.
*/
public function fields(Model $model)
public function fields(Model $model): array
{
/** @var \App\Models\User */
$user = auth()->user();
if ($user === null || $user->hasPermission('admin/users') === false) {
return ['id', 'username'];
return ['id', 'display_name'];
}
return parent::fields($model);
@@ -35,16 +36,24 @@ class UserConductor extends Conductor
* @param Model $model The model to transform.
* @return array The transformed model.
*/
public function transform(Model $model)
public function transform(Model $model): array
{
/** @var \App\Models\User */
$user = auth()->user();
$data = $model->toArray();
$limit = $this->fields($model);
if ($user === null || ($user->hasPermission('admin/users') === false && strcasecmp($user->id, $model->id) !== 0)) {
$fields = ['id', 'username'];
$data = arrayLimitKeys($data, $fields);
if (
$user === null || (
$user->hasPermission('admin/users') === false && strcasecmp($user->id, $model->id) !== 0
)
) {
$limit = ['id', 'display_name'];
} else {
$data['permissions'] = $user->permissions;
}
$data = arrayLimitKeys($data, $limit);
return $data;
}
@@ -54,8 +63,9 @@ class UserConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow updating model.
*/
public static function updatable(Model $model)
public static function updatable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
if ($user !== null) {
return ($user->hasPermission('admin/users') === true || strcasecmp($user->id, $model->id) === 0);
@@ -70,8 +80,9 @@ class UserConductor extends Conductor
* @param Model $model The model.
* @return boolean Allow deleting model.
*/
public static function destroyable(Model $model)
public static function destroyable(Model $model): bool
{
/** @var \App\Models\User */
$user = auth()->user();
return ($user !== null && $user->hasPermission('admin/users') === true);
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class CleanupTempFiles extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:cleanup-temp-files';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete temporary files that are older that 1 day';
/**
* Execute the console command.
*
* @return void
*/
public function handle(): void
{
$keepTime = (1 * 24 * 60 * 60); // 1 Day
$currentTimeStamp = time();
$deletedFileCount = 0;
foreach (glob(storage_path('app/tmp/*')) as $filename) {
$fileModifiedTimeStamp = filemtime($filename);
if (($currentTimeStamp - $fileModifiedTimeStamp) > $keepTime) {
unlink($filename);
$deletedFileCount++;
}
}
$this->comment('Deleted ' . $deletedFileCount . ' files');
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Console\Commands;
use App\Models\MediaJob;
use Illuminate\Console\Command;
class RemoveStaleMediaJobs extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:remove-stale-media-jobs';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Remove media_jobs that have not been modified for 48 hours';
/**
* Execute the console command.
*
* @return void
*/
public function handle(): void
{
$threshold = now()->subHours(48);
$staleJobs = MediaJob::where('updated_at', '<=', $threshold)->get();
foreach ($staleJobs as $job) {
$job->delete();
}
$this->info(count($staleJobs) . ' stale media_jobs removed.');
}
}

View File

@@ -13,9 +13,11 @@ class Kernel extends ConsoleKernel
* @param \Illuminate\Console\Scheduling\Schedule $schedule The schedule.
* @return void
*/
protected function schedule(Schedule $schedule)
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')->hourly();
$schedule->command('app:cleanup-temp-files')->everyThirtyMinutes();
$schedule->command('app:remove-stale-media-jobs')->everyThirtyMinutes();
}
/**
@@ -23,7 +25,7 @@ class Kernel extends ConsoleKernel
*
* @return void
*/
protected function commands()
protected function commands(): void
{
$this->load(__DIR__ . '/Commands');

View File

@@ -58,11 +58,13 @@ class Enum
/**
* Returns a message from the enum subclass
*
* @param integer $messageIndex The message index to retrieve.
* @param string $defaultMessage Message to use if index does not exist.
* @return string
*/
public static function getMessage(int $messageIndex, string $defaultMessage = 'Unknown'): string
{
if(array_key_exists($messageIndex, self::$messages) === true) {
if (array_key_exists($messageIndex, self::$messages) === true) {
return self::$messages[$messageIndex];
}

View File

@@ -2,34 +2,18 @@
namespace App\Exceptions;
use App\Enum\HttpResponseCodes;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
use PDOException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
class Handler extends ExceptionHandler
{
/**
* A list of exception types with their corresponding custom log levels.
*
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
*/
protected $levels = [
//
];
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<\Throwable>>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed to the session on validation exceptions.
*
@@ -47,7 +31,7 @@ class Handler extends ExceptionHandler
*
* @return void
*/
public function register()
public function register(): void
{
// $this->renderable(function (HttpException $e, $request) {
// if ($request->is('api/*')) {
@@ -79,7 +63,36 @@ class Handler extends ExceptionHandler
});
$this->reportable(function (Throwable $e) {
//
if ($this->shouldReport($e) === true) {
if (App::runningUnitTests() === false) {
$this->sendEmail($e);
}
}
});
}
/**
* Send email
*
* @param Throwable $exception Throwable object.
* @return void
*/
public function sendEmail(Throwable $exception)
{
try {
$e = FlattenException::createFromThrowable($exception);
$handler = new HtmlErrorRenderer(true);
$css = $handler->getStylesheet();
$content = $handler->getBody($e);
Mail::send('emails.exception', compact('css', 'content'), function ($message) {
$message
->to('webmaster@stemmechanics.com.au')
->subject('Exception Generated')
;
});
} catch (Throwable $ex) {
Log::error($ex);
}
}
}

View File

@@ -11,7 +11,7 @@ class SubscriptionFilter extends FilterAbstract
*
* @var mixed
*/
protected $class = '\App\Models\Subscription';
protected $class = \App\Models\Subscription::class;
/**

View File

@@ -38,3 +38,41 @@ function arrayLimitKeys(array $arr, array $keys): array
{
return array_intersect_key($arr, array_flip($keys));
}
/**
* Return an array value or default value if it does not exist
*
* @param string $key The key value to return if exists.
* @param array $arr The array to check.
* @param mixed $value The value to return if key does not exist.
* @return mixed
*/
function arrayDefaultValue(string $key, array $arr, mixed $value): mixed
{
if (array_key_exists($key, $arr) === true) {
return $arr[$key];
}
return $value;
}
/**
* Return if an item exists in an array, case insensitive
*
* @param string $val The value to check.
* @param array $arr The array to check.
* @return boolean
*/
function existsInArray(string $val, array $arr): bool
{
$exists = false;
foreach ($arr as $el) {
if (strcasecmp($val, $el) === 0) {
$exists = true;
break;
}
}
return $exists;
}

92
app/Helpers/Temp.php Normal file
View File

@@ -0,0 +1,92 @@
<?php
/* Temp File Helper Functions */
/**
* Generate a temporary file path.
*
* @param string $extension The file extension to use.
* @param string $part The file part number.
* @return string The filtered array.
*/
function generateTempFilePath(string $extension = '', string $part = ''): string
{
$temporaryDir = storage_path('app/tmp');
if (is_dir($temporaryDir) === false) {
mkdir($temporaryDir, 0777, true);
}
return $temporaryDir . DIRECTORY_SEPARATOR . uniqid('upload_', true) . ($extension !== '' ? ".{$extension}" : '') .
($part !== '' ? ".part-{$part}" : '');
}
/**
* Get Temp file information
*
* @param string $filePath The temp file name.
* @return array The temp file name details.
*/
function tempFileInfo(string $filePath): array
{
$part = '';
// Extract the part if it's present
if (preg_match('/\.part-(\d+)$/', $filePath, $matches) !== false) {
$part = $matches[1];
$filePath = substr($filePath, 0, -strlen($matches[0]));
}
$info = pathinfo($filePath);
$directory = $info['dirname'];
$name = $info['filename'];
$extension = '';
// If there's an extension, separate it
if (isset($info['extension']) === true) {
$extension = $info['extension'];
}
return [
'dirname' => $directory,
'basename' => $name . ($extension !== '' ? ".{$extension}" : ''),
'filename' => $name,
'extension' => $extension,
'part' => $part,
];
}
/**
* Check a temporary file exists.
*
* @param string $dir The file parent directory.
* @param string $name The file name.
* @param string $extension The file extension to use.
* @param string $part The file part number.
* @return boolean If the file exists.
*/
function tempFileExists(string $dir, string $name, string $extension = '', string $part = ''): bool
{
$filename = constructTempFileName($dir, $name, $extension, $part);
$exists = file_exists($filename);
return $exists;
}
/**
* Construct the temp file name based on the information
*
* @param string $dir The file parent directory.
* @param string $name The file name.
* @param string $extension The file extension to use.
* @param string $part The file part number.
* @return string The file path.
*/
function constructTempFileName(string $dir, string $name, string $extension = '', string $part = ''): string
{
$filename = $dir . DIRECTORY_SEPARATOR . $name . ($extension !== '' ? ".{$extension}" : '') .
($part !== "" ? ".part-{$part}" : '');
return $filename;
}

27
app/Helpers/TypeValue.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
/* Type Value Helper Functions */
/**
* Is value true
*
* @param mixed $value Value to check.
* @return boolean
*/
function isTrue(mixed $value): bool
{
if (is_bool($value) === true && $value === true) {
return true;
}
if (is_numeric($value) === true && intval($value) === 1) {
return true;
}
if (is_string($value) === true && in_array(strtolower($value), ['true', '1'], true) === true) {
return true;
}
return false;
}

View File

@@ -0,0 +1,121 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\AnalyticsConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\AnalyticsRequest;
use App\Models\AnalyticsItemRequest;
use App\Models\AnalyticsSession;
use Illuminate\Http\Request;
class AnalyticsController extends ApiController
{
/**
* AnalyticsController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->only([
'index',
'update',
'delete'
]);
}
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if ($request->user() !== null && $request->user()?->hasPermission('admin/analytics') === true) {
$request->rename([
'type' => 'requests.type',
'path' => 'requests.path'
]);
list($collection, $total) = AnalyticsConductor::request($request);
return $this->respondAsResource(
$collection,
['resourceName' => 'session',
'isCollection' => true,
'appendData' => ['total' => $total]
]
);
}//end if
return $this->respondForbidden();
}
/**
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\AnalyticsSession $session The analytics session.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, AnalyticsSession $session)
{
if ($request->user() !== null && $request->user()?->hasPermission('admin/analytics') === true) {
$session->load(['requests' => function ($query) {
$query->select('session_id', 'type', 'path', 'created_at');
}
]);
foreach ($session->requests as $requestItem) {
$requestItem->makeHidden('session_id');
}
return $this->respondAsResource(
$session,
['resourceName' => 'session']
);
}
return $this->respondForbidden();
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\AnalyticsRequest $request The user request.
* @return \Illuminate\Http\Response
*/
public function store(AnalyticsRequest $request)
{
if (AnalyticsConductor::creatable() === true) {
$analytics = null;
$user = $request->user();
$data = [
'type' => $request->input('type'),
'path' => $request->input('path', ''),
'useragent' => $request->userAgent(),
'ip' => $request->ip()
];
if (
$user !== null &&
$user->hasPermission('admin/analytics') === true &&
$request->has('session') === true
) {
$data['session_id'] = $request->input('session_id');
$analytics = AnalyticsItemRequest::create($data);
} else {
$analytics = AnalyticsItemRequest::create($data);
}
return $this->respondAsResource(
AnalyticsConductor::model($request, $analytics),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
);
} else {
return $this->respondForbidden();
}//end if
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api;
use Illuminate\Http\JsonResponse;
use App\Enum\HttpResponseCodes;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Model;
@@ -23,10 +24,13 @@ class ApiController extends Controller
* @param array $data Response data.
* @param integer $respondCode Response status code.
* @param array $headers Response headers.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondJson(array $data, int $respondCode = HttpResponseCodes::HTTP_OK, array $headers = [])
{
public function respondJson(
array $data,
int $respondCode = HttpResponseCodes::HTTP_OK,
array $headers = []
): JsonResponse {
return response()->json($data, $respondCode, $headers);
}
@@ -34,10 +38,11 @@ class ApiController extends Controller
* Return forbidden message
*
* @param string $message Response message.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondForbidden(string $message = 'You do not have permission to access the resource.')
{
public function respondForbidden(
string $message = 'You do not have permission to access the resource.'
): JsonResponse {
return response()->json(['message' => $message], HttpResponseCodes::HTTP_FORBIDDEN);
}
@@ -45,9 +50,9 @@ class ApiController extends Controller
* Return forbidden message
*
* @param string $message Response message.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondNotFound(string $message = 'The resource was not found.')
public function respondNotFound(string $message = 'The resource was not found.'): JsonResponse
{
return response()->json(['message' => $message], HttpResponseCodes::HTTP_NOT_FOUND);
}
@@ -56,40 +61,74 @@ class ApiController extends Controller
* Return too large message
*
* @param string $message Response message.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondTooLarge(string $message = 'The request entity is too large.')
public function respondTooLarge(string $message = 'The request entity is too large.'): JsonResponse
{
return response()->json(['message' => $message], HttpResponseCodes::HTTP_REQUEST_ENTITY_TOO_LARGE);
}
/**
* Return no content
* @return \Illuminate\Http\JsonResponse
* Return no content.
*
* @return JsonResponse
*/
public function respondNoContent()
public function respondNoContent(): JsonResponse
{
return response()->json([], HttpResponseCodes::HTTP_NO_CONTENT);
}
/**
* Return created
* @return \Illuminate\Http\JsonResponse
* Return no content
*
* @return JsonResponse
*/
public function respondCreated()
public function respondNotImplemented(): JsonResponse
{
return response()->json([], HttpResponseCodes::HTTP_NOT_IMPLEMENTED);
}
/**
* Return created.
*
* @return JsonResponse
*/
public function respondCreated(): JsonResponse
{
return response()->json([], HttpResponseCodes::HTTP_CREATED);
}
/**
* Return accepted.
*
* @return JsonResponse
*/
public function respondAccepted(): JsonResponse
{
return response()->json([], HttpResponseCodes::HTTP_ACCEPTED);
}
/**
* Return server error.
*
* @return JsonResponse
*/
public function respondServerError(): JsonResponse
{
return response()->json([], HttpResponseCodes::HTTP_INTERNAL_SERVER_ERROR);
}
/**
* Return single error message
*
* @param string $message Error message.
* @param integer $responseCode Resource code.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondError(string $message, int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY)
{
public function respondError(
string $message,
int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY
): JsonResponse {
return response()->json([
'message' => $message
], $responseCode);
@@ -100,10 +139,12 @@ class ApiController extends Controller
*
* @param array $errors Error messages.
* @param integer $responseCode Resource code.
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function respondWithErrors(array $errors, int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY)
{
public function respondWithErrors(
array $errors,
int $responseCode = HttpResponseCodes::HTTP_UNPROCESSABLE_ENTITY
): JsonResponse {
$keys = array_keys($errors);
$error = $errors[$keys[0]];
@@ -123,26 +164,36 @@ class ApiController extends Controller
*
* @param array|Model|Collection $data Resource data.
* @param array $options Respond options.
* @return \Illuminate\Http\JsonResponse
* @param callable|null $validationFn Optional validation function to check the data before responding.
* @return JsonResponse
*/
protected function respondAsResource(
mixed $data,
array $options = [],
) {
$isCollection = $options['isCollection'] ?? false;
$appendData = $options['appendData'] ?? null;
$resourceName = $options['resourceName'] ?? null;
$respondCode = $options['respondCode'] ?? HttpResponseCodes::HTTP_OK;
$validationFn = null
): JsonResponse {
$isCollection = ($options['isCollection'] ?? false);
$appendData = ($options['appendData'] ?? null);
$resourceName = ($options['resourceName'] ?? '');
$transformResourceName = ($options['transformResourceName'] ?? true);
$respondCode = ($options['respondCode'] ?? HttpResponseCodes::HTTP_OK);
if ($data === null || ($data instanceof Collection && $data->count() === 0)) {
return $this->respondNotFound();
$validationData = [];
if (array_key_exists('appendData', $options) === true) {
$validationData = $options['appendData'];
}
if(is_null($resourceName) === true || empty($resourceName) === true) {
if ($validationFn === null || $validationFn($validationData) === true) {
return $this->respondNotFound();
}
}
if (empty($resourceName) === true) {
$resourceName = $this->resourceName;
}
if(is_null($resourceName) === true || empty($resourceName) === true) {
if (empty($resourceName) === true) {
$resourceName = get_class($this);
$resourceName = substr($resourceName, (strrpos($resourceName, '\\') + 1));
$resourceName = substr($resourceName, 0, strpos($resourceName, 'Controller'));
@@ -155,15 +206,14 @@ class ApiController extends Controller
} elseif (is_array($data) === true) {
$dataArray = $data;
} elseif ($data instanceof Model) {
$is_multiple = false;
$dataArray = $data->toArray();
}
$resource = [];
if ($isCollection === true) {
$resource = [Str::plural($resourceName) => $dataArray];
$resource = [$transformResourceName === true ? Str::plural($resourceName) : $resourceName => $dataArray];
} else {
$resource = [Str::singular($resourceName) => $dataArray];
$resource = [$transformResourceName === true ? Str::singular($resourceName) : $resourceName => $dataArray];
}
if ($appendData !== null) {
@@ -172,4 +222,22 @@ class ApiController extends Controller
return response()->json($resource, $respondCode);
}
/**
* Get the Controller Model Class name.
*
* @return string
*/
public function getModelClass(): string
{
$controllerClass = static::class;
$modelName = 'App\\Models\\' . Str::replaceLast('Controller', '', Str::afterLast($controllerClass, '\\'));
if (class_exists($modelName) === false) {
return $modelName;
}
return $modelName;
}
}

View File

@@ -0,0 +1,139 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\MediaConductor;
use App\Conductors\ArticleConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\ArticleRequest;
use App\Models\Media;
use App\Models\Article;
use App\Traits\HasAttachments;
use App\Traits\HasGallery;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ArticleController extends ApiController
{
use HasAttachments;
use HasGallery;
/**
* ApplicationController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->only([
'store',
'update',
'delete'
]);
}
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
list($collection, $total) = ArticleConductor::request($request);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]
]
);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\Article $article The article model.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Article $article)
{
if (ArticleConductor::viewable($article) === true) {
return $this->respondAsResource(ArticleConductor::model($request, $article));
}
return $this->respondForbidden();
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\ArticleRequest $request The user request.
* @return \Illuminate\Http\Response
*/
public function store(ArticleRequest $request)
{
if (ArticleConductor::creatable() === true) {
$article = Article::create($request->except(['attachments', 'gallery']));
if ($request->has('attachments') === true) {
$article->addAttachments($request->get('attachments'));
}
if ($request->has('gallery') === true) {
$article->galleryAddMany($request->get('gallery'));
}
return $this->respondAsResource(
ArticleConductor::model($request, $article),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
);
} else {
return $this->respondForbidden();
}//end if
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\ArticleRequest $request The article update request.
* @param \App\Models\Article $article The specified article.
* @return \Illuminate\Http\Response
*/
public function update(ArticleRequest $request, Article $article)
{
if (ArticleConductor::updatable($article) === true) {
if ($request->has('attachments') === true) {
$article->deleteAttachments();
$article->addAttachments($request->get('attachments'));
}
if ($request->has('gallery') === true) {
$article->gallery()->delete();
$article->galleryAddMany($request->get('gallery'));
}
$article->update($request->except(['attachments', 'gallery']));
return $this->respondAsResource(ArticleConductor::model($request, $article));
}
return $this->respondForbidden();
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Article $article The specified article.
* @return \Illuminate\Http\Response
*/
public function destroy(Article $article)
{
if (ArticleConductor::destroyable($article) === true) {
$article->delete();
return $this->respondNoContent();
} else {
return $this->respondForbidden();
}
}
}

View File

@@ -1,84 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\Attachment;
use Illuminate\Http\Request;
class AttachmentController extends ApiController
{
/**
* ApplicationController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->except(['store', 'destroyByEmail']);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param \App\Models\Attachment $attachment
* @return \Illuminate\Http\Response
*/
public function show(Attachment $attachment)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Attachment $attachment
* @return \Illuminate\Http\Response
*/
public function edit(Attachment $attachment)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Attachment $attachment
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Attachment $attachment)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Attachment $attachment
* @return \Illuminate\Http\Response
*/
public function destroy(Attachment $attachment)
{
//
}
}

View File

@@ -33,7 +33,7 @@ class AuthController extends ApiController
* @param Request $request Current request data.
* @return JsonResponse
*/
public function me(Request $request)
public function me(Request $request): JsonResponse
{
$user = $request->user()->makeVisible(['permissions']);
return $this->respondAsResource($user);
@@ -47,18 +47,22 @@ class AuthController extends ApiController
*/
public function login(AuthLoginRequest $request)
{
$user = User::where('username', '=', $request->input('username'))->first();
$user = User::where('email', '=', $request->input('email'))->first();
if ($user !== null && Hash::check($request->input('password'), $user->password) === true) {
if (
$user !== null &&
strlen($user->password) > 0 &&
Hash::check($request->input('password'), $user->password) === true
) {
if ($user->email_verified_at === null) {
return $this->respondWithErrors([
'username' => 'Email address has not been verified.'
'email' => 'Email address has not been verified.'
]);
}
if ($user->disabled === true) {
return $this->respondWithErrors([
'username' => 'Account has been disabled.'
'email' => 'Account has been disabled.'
]);
}
@@ -78,8 +82,8 @@ class AuthController extends ApiController
}//end if
return $this->respondWithErrors([
'username' => 'Invalid username or password',
'password' => 'Invalid username or password',
'email' => 'Invalid email or password',
'password' => 'Invalid email or password',
]);
}
@@ -89,7 +93,7 @@ class AuthController extends ApiController
* @param Request $request Current request data.
* @return JsonResponse
*/
public function logout(Request $request)
public function logout(Request $request): JsonResponse
{
$user = $request->user();

View File

@@ -6,9 +6,14 @@ use App\Enum\HttpResponseCodes;
use App\Models\Event;
use App\Conductors\EventConductor;
use App\Conductors\MediaConductor;
use App\Conductors\UserConductor;
use App\Http\Requests\EventRequest;
use App\Models\Media;
use App\Models\User;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class EventController extends ApiController
{
@@ -18,7 +23,7 @@ class EventController extends ApiController
public function __construct()
{
$this->middleware('auth:sanctum')
->only(['store','update','destroy']);
->only(['store','update','destroy', 'userAdd', 'userUpdate', 'userDelete']);
}
/**
@@ -64,7 +69,12 @@ class EventController extends ApiController
public function store(EventRequest $request)
{
if (EventConductor::creatable() === true) {
$event = Event::create($request->all());
$event = Event::create($request->except(['attachments']));
if ($request->has('attachments') === true) {
$event->addAttachments($request->get('attachments'));
}
return $this->respondAsResource(
EventConductor::model($request, $event),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
@@ -84,7 +94,12 @@ class EventController extends ApiController
public function update(EventRequest $request, Event $event)
{
if (EventConductor::updatable($event) === true) {
$event->update($request->all());
if ($request->has('attachments') === true) {
$event->deleteAttachments();
$event->addAttachments($request->get('attachments'));
}
$event->update($request->except(['attachments']));
return $this->respondAsResource(EventConductor::model($request, $event));
}
@@ -108,127 +123,108 @@ class EventController extends ApiController
}
/**
* Get a list of attachments related to this model.
*
* @param Request $request The user request.
* @param Post $post The post model.
* @return JsonResponse Returns the post attachments.
* @throws InvalidFormatException
* @throws BindingResolutionException
* @throws InvalidCastException
*/
public function getAttachments(Request $request, Event $event)
{
if (EventConductor::viewable($event) === true) {
$medium = $event->attachments->map(function ($attachment) {
return $attachment->media;
});
return $this->respondAsResource(MediaConductor::collection($request, $medium), ['isCollection' => true, 'resourceName' => 'attachment']);
}
return $this->respondForbidden();
}
/**
* Store an attachment related to this model.
*
* @param Request $request The user request.
* @param Post $post The post model.
* @return JsonResponse The response.
* @throws BindingResolutionException
* @throws MassAssignmentException
*/
public function storeAttachment(Request $request, Event $event)
{
if (EventConductor::updatable($event) === true) {
if ($request->has("medium") && Media::find($request->medium)) {
$event->attachments()->create(['media_id' => $request->medium]);
return $this->respondCreated();
}
return $this->respondWithErrors(['media' => 'The media ID was not found']);
}
return $this->respondForbidden();
}
/**
* Update/replace attachments related to this model.
*
* @param Request $request The user request.
* @param Post $post The related model.
* List users of Event
* @param Request $request The HTTP request.
* @param Event $event Event model.
* @return JsonResponse
* @throws BindingResolutionException
* @throws MassAssignmentException
*/
public function updateAttachments(Request $request, Event $event)
public function userList(Request $request, Event $event): JsonResponse
{
if (EventConductor::updatable($event) === true) {
$mediaIds = $request->attachments;
if (is_array($mediaIds) === false) {
$mediaIds = explode(',', $request->attachments);
$authUser = $request->user();
$eventUsers = $event->users;
if ($authUser !== null) {
$isAdmin = $authUser->hasPermission('admin/events');
$isEventUser = $eventUsers->contains($authUser->id);
if ($isAdmin === true || $isEventUser === true) {
if ($isAdmin === false) {
$eventUsers = $eventUsers->filter(function ($user) use ($authUser) {
return $user->id === $authUser->id;
});
}
$mediaIds = array_map('trim', $mediaIds); // trim each media ID
$attachments = $event->attachments;
// Delete attachments that are not in $mediaIds
foreach ($attachments as $attachment) {
if (!in_array($attachment->media_id, $mediaIds)) {
$attachment->delete();
}
return $this->respondAsResource(
UserConductor::collection($request, $eventUsers),
[
'isCollection' => true,
'resourceName' => 'users'
]
);
}
// Create new attachments for media IDs that are not already in $post->attachments()
foreach ($mediaIds as $mediaId) {
$found = false;
foreach ($attachments as $attachment) {
if ($attachment->media_id == $mediaId) {
$found = true;
break;
}
}
if (!$found) {
$event->attachments()->create(['media_id' => $mediaId]);
}
}
return $this->respondNoContent();
return $this->respondNotFound();
}//end if
return $this->respondForbidden();
}
/**
* Delete a specific related attachment.
* @param Request $request The user request.
* @param Post $post The model.
* @param Media $medium The attachment medium.
* Add user to Event
* @param Request $request The HTTP request.
* @param Event $event Event model.
* @return JsonResponse
* @throws BindingResolutionException
*/
public function deleteAttachment(Request $request, Event $event, Media $medium)
public function userAdd(Request $request, Event $event): JsonResponse
{
if (EventConductor::updatable($event) === true) {
$attachments = $event->attachments;
$deleted = false;
$authUser = $request->user();
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
if ($request->has("users") === true) {
$eventUsers = $event->users()->pluck('user_id')->toArray(); // Get the current users in the event
$requestedUsers = $request->input("users"); // Get the requested users
foreach ($attachments as $attachment) {
if ($attachment->media_id === $medium->id) {
$attachment->delete();
$deleted = true;
break;
$usersToAdd = array_diff($requestedUsers, $eventUsers); // Users to add
$usersToRemove = array_diff($eventUsers, $requestedUsers); // Users to remove
// Add missing users
foreach ($usersToAdd as $userToAdd) {
if (User::find($userToAdd) !== null) {
$event->users()->attach($userToAdd);
}
}
if ($deleted) {
// Attachment was deleted successfully
// Remove extra users
foreach ($usersToRemove as $userToRemove) {
$event->users()->detach($userToRemove);
}
return $this->respondNoContent();
}//end if
return $this->respondWithErrors(['users' => 'The user list was not found']);
}//end if
return $this->respondForbidden();
}
/**
* Update user
* @param Request $request The HTTP request.
* @param Event $event Event model.
* @return void
*/
public function userUpdate(Request $request, Event $event): void
{
// only admin/events permitted
}
/**
* Delete user from event
*
* @param Request $request The HTTP request.
* @param Event $event Event model.
* @param User $user User model.
* @return JsonResponse
*/
public function userDelete(Request $request, Event $event, User $user): JsonResponse
{
$authUser = $request->user();
if ($authUser !== null && $authUser->hasPermission('admin/events') === true) {
$eventUsers = $event->users;
if ($eventUsers->find($user->id) !== null) {
$eventUsers->detach($user->id);
return $this->respondNoContent();
} else {
// Attachment with matching media ID was not found
return $this->respondNotFound();
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers\Api;
use App\Enum\HttpResponseCodes;
use App\Models\Media;
use Illuminate\Http\Request;
class InfoController extends ApiController
{
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$info = [
"version" => "1.0.0",
"max_upload_size" => Media::getMaxUploadSize()
];
return $this->respondJson($info);
}
}

View File

@@ -45,7 +45,12 @@ class LogController extends ApiController
$before = $request->get('before');
if ($before !== null) {
$before = preg_split("/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/", $before, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
$before = preg_split(
"/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/",
$before,
-1,
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
);
if (count($before) !== 6) {
$before = null;
}
@@ -53,7 +58,12 @@ class LogController extends ApiController
$after = $request->get('after');
if ($after !== null) {
$after = preg_split("/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/", $after, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
$after = preg_split(
"/([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/",
$after,
-1,
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
);
if (count($after) !== 6) {
$after = null;
}
@@ -77,30 +87,59 @@ class LogController extends ApiController
$logContent = file_get_contents($logFile['path']);
}
$logArray = preg_split("/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: (?:(?!\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: )[\s\S])*)/", $logContent, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
$logArray = preg_split(
// phpcs:ignore Generic.Files.LineLength.TooLong
"/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: (?:(?!\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}: )[\s\S])*)/",
$logContent,
-1,
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
);
$logContent = '';
$logLineCount = 0;
$logLineSkip = false;
foreach (array_reverse($logArray) as $logLine) {
$lineDate = preg_split("/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}): /", $logLine, -1, (PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
$lineDate = preg_split(
"/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}): /",
$logLine,
-1,
(PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY)
);
if (count($lineDate) >= 6) {
$logLineSkip = false;
// Is line before
if ($before !== null && ($lineDate[0] > $before[0] || $lineDate[1] > $before[1] || $lineDate[2] > $before[2] || $lineDate[3] > $before[3] || $lineDate[4] > $before[4] || $lineDate[5] > $before[5])) {
if (
$before !== null && (
$lineDate[0] > $before[0] ||
$lineDate[1] > $before[1] ||
$lineDate[2] > $before[2] ||
$lineDate[3] > $before[3] ||
$lineDate[4] > $before[4] ||
$lineDate[5] > $before[5]
)
) {
$logLineSkip = true;
continue;
}
// Is line after
if ($after !== null && ($after[0] > $lineDate[0] || $after[1] > $lineDate[1] || $after[2] > $lineDate[2] || $after[3] > $lineDate[3] || $after[4] > $lineDate[4] || $after[5] > $lineDate[5])) {
if (
$after !== null && (
$after[0] > $lineDate[0] ||
$after[1] > $lineDate[1] ||
$after[2] > $lineDate[2] ||
$after[3] > $lineDate[3] ||
$after[4] > $lineDate[4] ||
$after[5] > $lineDate[5]
)
) {
$logLineSkip = true;
continue;
}
$logLineCount += 1;
}
}//end if
if ($logLineCount > $lines) {
break;

View File

@@ -3,11 +3,18 @@
namespace App\Http\Controllers\Api;
use App\Conductors\MediaConductor;
use App\Conductors\MediaJobConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\MediaRequest;
use App\Models\Media;
use App\Models\MediaJob;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\PersonalAccessToken;
class MediaController extends ApiController
@@ -34,7 +41,11 @@ class MediaController extends ApiController
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]]
'appendData' => ['total' => $total]
],
function ($options) {
return $options['total'] === 0;
}
);
}
@@ -62,53 +73,18 @@ class MediaController extends ApiController
*/
public function store(MediaRequest $request)
{
if (MediaConductor::creatable() === true) {
// allowed to create a media item
if (MediaConductor::creatable() === false) {
return $this->respondForbidden();
}
// check for file
$file = $request->file('file');
if ($file === null) {
return $this->respondWithErrors(['file' => 'The browser did not upload the file correctly to the server.']);
}
if ($file->isValid() !== true) {
switch ($file->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
return $this->respondTooLarge();
case UPLOAD_ERR_PARTIAL:
return $this->respondWithErrors(['file' => 'The file upload was interrupted.']);
default:
return $this->respondWithErrors(['file' => 'An error occurred uploading the file to the server.']);
}
}
if ($file->getSize() > Media::maxUploadSize()) {
return $this->respondTooLarge();
}
$title = $file->getClientOriginalName();
$mime = $file->getMimeType();
$fileInfo = Media::store($file, empty($request->input('permission')));
if ($fileInfo === null) {
return $this->respondWithErrors(
['file' => 'The file could not be stored on the server'],
HttpResponseCodes::HTTP_INTERNAL_SERVER_ERROR
);
}
$request->merge([
'title' => $title,
'mime' => $mime,
'name' => $fileInfo['name'],
'size' => filesize($fileInfo['path'])
]);
$media = $request->user()->media()->create($request->all());
return $this->respondAsResource(
MediaConductor::model($request, $media),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
);
}//end if
return $this->respondForbidden();
return $this->storeOrUpdate($request, null);
}
/**
@@ -120,39 +96,202 @@ class MediaController extends ApiController
*/
public function update(MediaRequest $request, Media $medium)
{
if (MediaConductor::updatable($medium) === true) {
$file = $request->file('file');
if ($file !== null) {
if ($file->getSize() > Media::maxUploadSize()) {
return $this->respondTooLarge();
// allowed to update a media item
if (MediaConductor::updatable($medium) === false) {
return $this->respondForbidden();
}
$oldPath = $medium->path();
$fileInfo = Media::store($file, empty($request->input('permission')));
if ($fileInfo === null) {
return $this->storeOrUpdate($request, $medium);
}
/**
* Store a new media resource
*
* @param \App\Http\Requests\MediaRequest $request The uploaded media.
* @param \App\Models\Media|null $medium The specified media.
* @return \Illuminate\Http\Response
*/
public function storeOrUpdate(MediaRequest $request, Media|null $medium)
{
$file = $request->file('file');
if ($file !== null) {
// validate file object
if ($file->isValid() !== true) {
switch ($file->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
return $this->respondTooLarge();
case UPLOAD_ERR_PARTIAL:
return $this->respondWithErrors([$file => 'The file upload was interrupted.']);
default:
return $this->respondWithErrors(
['file' => 'The file could not be stored on the server'],
HttpResponseCodes::HTTP_INTERNAL_SERVER_ERROR
[$file => 'An error occurred uploading the file to the server.']
);
}
}
if ($file->getSize() > Media::getMaxUploadSize()) {
return $this->respondTooLarge();
}
}
// create/get media job
$mediaJob = null;
$data = [];
if ($request->missing('job_id') === true) {
/** @var \App\Models\User */
$user = auth()->user();
$mediaJob = new MediaJob();
$mediaJob->user_id = $user->id;
if ($medium !== null) {
$mediaJob->media_id = $medium->id;
}
if ($request->has('title') === true || $file !== null) {
$data['title'] = $request->get('title', '');
}
if ($request->has('name') === true || $file !== null) {
$data['name'] = (
$request->has('chunk') === true ? $request->get('name', '') : $file->getClientOriginalName()
);
}
if (file_exists($oldPath) === true) {
unlink($oldPath);
if ($file !== null) {
$data['size'] = $request->has('chunk') === true ? intval($request->get('size', 0)) : $file->getSize();
$data['mime_type'] = (
$request->has('chunk') === true ? $request->get('mime_type', '') : $file->getMimeType()
);
}
$request->merge([
'title' => $file->getClientOriginalName(),
'mime' => $file->getMimeType(),
'name' => $fileInfo['name'],
'size' => filesize($fileInfo['path'])
]);
if ($request->has('storage') === true || $file !== null) {
$data['storage'] = $request->get('storage', '');
}
if ($request->has('security_type') === true || $file !== null) {
$data['security']['type'] = $request->get('security_type', '');
$data['security']['data'] = $request->get('security_data', '');
if ($data['security']['type'] === '') {
$data['security']['data'] = '';
}
if ($medium === null || strcasecmp($data['security']['type'], $medium->security_type) !== 0) {
if ($request->has('storage') === false) {
$mime_type = $request->get('mime_type', $medium === null ? '' : $medium->mime_type);
$data['storage'] = Media::recommendedStorage($mime_type, $data['security']['type']);
}
}
}
if (
array_key_exists('storage', $data) === true && (
array_key_exists('security', $data) === true &&
array_key_exists('type', $data['security']) === true
) &&
array_key_exists('mime_type', $data) === true &&
$data['mime_type'] !== ""
) {
$error = Media::verifyStorage($data['mime_type'], $data['security']['type'], $data['storage']);
// Log::error($data['mime_type'] . ' - ' . $data['security']['type'] . ' - ' . $data['storage']);
switch ($error) {
case Media::STORAGE_VALID:
break;
case Media::STORAGE_MIME_MISSING:
return $this->respondWithErrors(['mime_type' => 'The file type is required.']);
case Media::STORAGE_NOT_FOUND:
return $this->respondWithErrors(['storage' => 'Storage was not found.']);
case Media::STORAGE_INVALID_SECURITY:
return $this->respondWithErrors(
['storage' => 'Storage invalid for this security requirement.']
);
default:
return $this->respondWithErrors(['storage' => 'Storage verification error occurred.']);
}
}
if ($request->has('transform') === true) {
$transform = [];
foreach (explode(',', $request->get('transform', '')) as $value) {
if (is_string($value) === true) {
if (preg_match('/^rotate-(-?\d+)$/', $value, $matches) !== false) {
$transform['rotate'] = $matches[1];
} elseif (preg_match('/^flip-([vh]|vh|hv)$/', $value, $matches) !== false) {
$transform['flip'] = $matches[1];
} elseif (preg_match('/^crop-(\d+)-(\d+)$/', $value, $matches) !== false) {
$transform['crop'] = ['width' => $matches[1], 'height' => $matches[2]];
} elseif (preg_match('/^crop-(\d+)-(\d+)-(\d+)-(\d+)$/', $value, $matches) !== false) {
$transform['crop'] = [
'width' => $matches[1],
'height' => $matches[2],
'x' => $matches[3],
'y' => $matches[4]
];
}
}
}
if (count($transform) > 0) {
$data['transform'] = $transform;
}
}//end if
$medium->update($request->all());
return $this->respondAsResource(MediaConductor::model($request, $medium));
$mediaJob->setStatusWaiting();
} else {
$mediaJob = MediaJob::find($request->get('job_id'));
if ($mediaJob === null || $mediaJob->exists() === false) {
$this->respondNotFound();
}
$data = json_decode($mediaJob->data, true);
if ($data === null) {
Log::error(`{$mediaJob->id} contains no data`);
return $this->respondServerError();
}
if (array_key_exists('name', $data) === false) {
Log::error(`{$mediaJob->id} data does not contain the name key`);
return $this->respondServerError();
}
}//end if
return $this->respondForbidden();
if ($mediaJob === null) {
Log::error(`media job does not exist`);
return $this->respondServerError();
}
// save uploaded file
if ($file !== null) {
if ($data['name'] === '') {
Log::error(`filename does not exist`);
return $this->respondServerError();
}
$temporaryFilePath = generateTempFilePath(
pathinfo($data['name'], PATHINFO_EXTENSION),
$request->get('chunk', '')
);
copy($file->path(), $temporaryFilePath);
if ($request->has('chunk') === true) {
$data['chunks'][$request->get('chunk', '1')] = $temporaryFilePath;
$data['chunk_count'] = $request->get('chunk_count', 1);
} else {
$data['file'] = $temporaryFilePath;
}
}
$mediaJob->data = json_encode($data, true);
$mediaJob->save();
$mediaJob->process();
return $this->respondAsResource(
MediaJobConductor::model($request, $mediaJob),
['resourceName' => 'media_job', 'respondCode' => HttpResponseCodes::HTTP_ACCEPTED]
);
}
/**
@@ -164,10 +303,6 @@ class MediaController extends ApiController
public function destroy(Media $medium)
{
if (MediaConductor::destroyable($medium) === true) {
if (file_exists($medium->path()) === true) {
unlink($medium->path());
}
$medium->delete();
return $this->respondNoContent();
}
@@ -179,33 +314,27 @@ class MediaController extends ApiController
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\Media $medium Specified media.
* @param \App\Models\Media $media Specified media.
* @return \Illuminate\Http\Response
*/
public function download(Request $request, Media $medium)
public function download(Request $request, Media $media): Response
{
$respondJson = in_array('application/json', explode(',', $request->header('Accept', 'application/json')));
$headers = [];
$path = $medium->path();
/* File exists */
if (file_exists($path) === false) {
if ($respondJson === false) {
return redirect('/not-found');
} else {
/* Check file exists */
if (Storage::disk($media->storage)->exists($media->name) === false) {
return $this->respondNotFound();
}
}
$updated_at = Carbon::parse(filemtime($path));
$updated_at = Carbon::parse(Storage::disk($media->storage)->lastModified($media->name));
$headerPragma = 'no-cache';
$headerCacheControl = 'max-age=0, must-revalidate';
$headerExpires = $updated_at->toRfc2822String();
if (empty($medium->permission) === true) {
if ($request->user() === null && $request->has('token') === true) {
/* construct user if can */
$user = $request->user();
if ($user === null && $request->has('token') === true) {
$accessToken = PersonalAccessToken::findToken(urldecode($request->input('token')));
if (
@@ -215,16 +344,29 @@ class MediaController extends ApiController
$user = $accessToken->tokenable;
}
}
if ($request->user() === null || $user->hasPermission($medium->permission) === false) {
if ($respondJson === false) {
return redirect('/login?redirect=' . $request->path());
} else {
return $this->respondForbidden();
}
}
} else {
if ($media->security_type === '') {
/* no security */
$headerPragma = 'public';
$headerExpires = $updated_at->addMonth()->toRfc2822String();
} elseif (strcasecmp('password', $media->security_type) === 0) {
/* password */
if (
($user === null || $user->hasPermission('admin/media') === false) &&
($request->has('password') === false || $request->get('password') !== $media->security_data)
) {
return $this->respondForbidden();
}
} elseif (strcasecmp('permission', $media->security_type) === 0) {
/* permission */
if (
$user === null || (
$user->hasPermission('admin/media') === false &&
$user->hasPermission($media->security_data) === false
)
) {
return $this->respondForbidden();
}
}//end if
// deepcode ignore InsecureHash: Browsers expect Etag to be a md5 hash
@@ -233,7 +375,7 @@ class MediaController extends ApiController
$headers = [
'Cache-Control' => $headerCacheControl,
'Content-Disposition' => sprintf('inline; filename="%s"', basename($path)),
'Content-Disposition' => sprintf('inline; filename="%s"', basename($media->name)),
'Etag' => $headerEtag,
'Expires' => $headerExpires,
'Last-Modified' => $headerLastModified,
@@ -252,6 +394,50 @@ class MediaController extends ApiController
return response()->make('', 304, $headers);
}
return response()->file($path, $headers);
$headers['Content-Type'] = Storage::disk($media->storage)->mimeType($media->name);
$headers['Content-Length'] = Storage::disk($media->storage)->size($media->name);
$headers['Content-Disposition'] = 'attachment; filename="' . basename($media->name) . '"';
$stream = Storage::disk($media->storage)->readStream($media->name);
return response()->stream(
function () use ($stream) {
while (ob_get_level() > 0) {
ob_end_flush();
}
fpassthru($stream);
},
200,
$headers
);
}
/**
* Validate a File item in a request is valid
*
* @param UploadedFile $file The file to validate.
* @param string $errorKey The error key to use.
* @return JsonResponse|null
*/
private function validateFileObject(UploadedFile $file, string $errorKey = 'file'): JsonResponse|null
{
if ($file->isValid() !== true) {
switch ($file->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
return $this->respondTooLarge();
case UPLOAD_ERR_PARTIAL:
return $this->respondWithErrors([$errorKey => 'The file upload was interrupted.']);
default:
return $this->respondWithErrors(
[$errorKey => 'An error occurred uploading the file to the server.']
);
}
}
if ($file->getSize() > Media::getMaxUploadSize()) {
return $this->respondTooLarge();
}
return null;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\MediaJobConductor;
use App\Http\Controllers\Api\ApiController;
use App\Models\MediaJob;
use Illuminate\Http\Request;
class MediaJobController extends ApiController
{
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
list($collection, $total) = MediaJobConductor::request($request);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total],
'resourceName' => 'media_job'
],
function ($options) {
return $options['total'] === 0;
}
);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\MediaJob $mediaJob The request media job.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, MediaJob $mediaJob)
{
if (MediaJobConductor::viewable($mediaJob) === true) {
return $this->respondAsResource(
MediaJobConductor::model($request, $mediaJob),
['resourceName' => 'media_job']
);
}
return $this->respondForbidden();
}
}

View File

@@ -32,7 +32,7 @@ class OCRController extends ApiController
$data = ['ocr' => []];
$filters = $request->get('filters', ['tesseract']);
if(is_array($filters) === false) {
if (is_array($filters) === false) {
$filters = explode(',', $filters);
}
@@ -52,9 +52,12 @@ class OCRController extends ApiController
// We need progress updates to break the connection mid-way
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128); // more progress info
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function(
$downloadSize, $downloaded, $uploadSize, $uploaded
) use($maxDownloadSize) {
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function (
$downloadSize,
$downloaded,
$uploadSize,
$uploaded
) use ($maxDownloadSize) {
return ($downloaded > $maxDownloadSize) ? 1 : 0;
});
@@ -62,9 +65,9 @@ class OCRController extends ApiController
$curlError = curl_errno($ch);
$curlSize = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
if($curlError !== 0) {
if ($curlError !== 0) {
$error = 'File size is larger then allowed';
if($curlError !== CurlErrorCodes::CURLE_ABORTED_BY_CALLBACK) {
if ($curlError !== CurlErrorCodes::CURLE_ABORTED_BY_CALLBACK) {
$error = CurlErrorCodes::getMessage($curlError);
}
@@ -77,8 +80,8 @@ class OCRController extends ApiController
// tesseract (overall)
$ocr = null;
foreach($filters as $filterItem) {
if(str_starts_with($filterItem, 'tesseract') === true) {
foreach ($filters as $filterItem) {
if (str_starts_with($filterItem, 'tesseract') === true) {
$ocr = new TesseractOCR();
$ocr->image($urlDownloadFilePath);
if ($tesseractOEM !== null) {
@@ -95,11 +98,13 @@ class OCRController extends ApiController
}
// Image Filter Function
$tesseractImageFilterFunc = function($filter, $options = null) use($curlResult, $curlSize, $ocr) {
$tesseractImageFilterFunc = function ($filter, $options = null) use ($curlResult, $curlSize, $ocr) {
$result = '';
$img = imagecreatefromstring($curlResult);
if ($img !== false && (($options !== null && imagefilter($img, $filter, $options) === true) || ($options === null && imagefilter($img, $filter) === true))) {
if (
$img !== false && (($options !== null && imagefilter($img, $filter, $options) === true) ||
($options === null && imagefilter($img, $filter) === true))
) {
ob_start();
imagepng($img);
$imgData = ob_get_contents();
@@ -116,7 +121,7 @@ class OCRController extends ApiController
};
// Image Scale Function
$tesseractImageScaleFunc = function($scaleFunc) use ($curlResult, $ocr) {
$tesseractImageScaleFunc = function ($scaleFunc) use ($curlResult, $ocr) {
$result = '';
$srcImage = imagecreatefromstring($curlResult);
$srcWidth = imagesx($srcImage);
@@ -143,7 +148,7 @@ class OCRController extends ApiController
};
// filter: tesseract
if(in_array('tesseract', $filters) === true) {
if (in_array('tesseract', $filters) === true) {
$data['ocr']['tesseract'] = $ocr->run(500);
}
@@ -154,14 +159,14 @@ class OCRController extends ApiController
// filter: tesseract.double_scale
if (in_array('tesseract.double_scale', $filters) === true) {
$data['ocr']['tesseract.double_scale'] = $tesseractImageScaleFunc(function($size) {
$data['ocr']['tesseract.double_scale'] = $tesseractImageScaleFunc(function ($size) {
return $size * 2;
});
}
// filter: tesseract.half_scale
if (in_array('tesseract.half_scale', $filters) === true) {
$data['ocr']['tesseract.half_scale'] = $tesseractImageScaleFunc(function($size) {
$data['ocr']['tesseract.half_scale'] = $tesseractImageScaleFunc(function ($size) {
return $size / 2;
});
}
@@ -187,12 +192,12 @@ class OCRController extends ApiController
}
// filter: keras
if(in_array('keras', $filters) === true) {
if (in_array('keras', $filters) === true) {
$cmd = '/usr/bin/python3 ' . base_path() . '/scripts/keras_oc.py ' . urlencode($url);
$command = escapeshellcmd($cmd);
$output = shell_exec($cmd);
if ($output !== null && strlen($output) > 0) {
$output = substr($output, strpos($output, '----------START----------') + 25);
$output = substr($output, (strpos($output, '----------START----------') + 25));
} else {
$output = '';
}

View File

@@ -1,246 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\MediaConductor;
use App\Conductors\PostConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\PostRequest;
use App\Models\Media;
use App\Models\Post;
use Illuminate\Http\JsonResponse;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\InvalidCastException;
use Illuminate\Database\Eloquent\MassAssignmentException;
use Illuminate\Http\Request;
class PostController extends ApiController
{
/**
* ApplicationController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->only([
'store',
'update',
'delete'
]);
}
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
list($collection, $total) = PostConductor::request($request);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]]
);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\Post $post The post model.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Post $post)
{
if (PostConductor::viewable($post) === true) {
return $this->respondAsResource(PostConductor::model($request, $post));
}
return $this->respondForbidden();
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\PostRequest $request The user request.
* @return \Illuminate\Http\Response
*/
public function store(PostRequest $request)
{
if (PostConductor::creatable() === true) {
$post = Post::create($request->all());
return $this->respondAsResource(
PostConductor::model($request, $post),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
);
} else {
return $this->respondForbidden();
}
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\PostRequest $request The post update request.
* @param \App\Models\Post $post The specified post.
* @return \Illuminate\Http\Response
*/
public function update(PostRequest $request, Post $post)
{
if (PostConductor::updatable($post) === true) {
$post->update($request->all());
return $this->respondAsResource(PostConductor::model($request, $post));
}
return $this->respondForbidden();
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Post $post The specified post.
* @return \Illuminate\Http\Response
*/
public function destroy(Post $post)
{
if (PostConductor::destroyable($post) === true) {
$post->delete();
return $this->respondNoContent();
} else {
return $this->respondForbidden();
}
}
/**
* Get a list of attachments related to this model.
*
* @param Request $request The user request.
* @param Post $post The post model.
* @return JsonResponse Returns the post attachments.
* @throws InvalidFormatException
* @throws BindingResolutionException
* @throws InvalidCastException
*/
public function getAttachments(Request $request, Post $post)
{
if (PostConductor::viewable($post) === true) {
$medium = $post->attachments->map(function ($attachment) {
return $attachment->media;
});
return $this->respondAsResource(MediaConductor::collection($request, $medium), ['isCollection' => true, 'resourceName' => 'attachment']);
}
return $this->respondForbidden();
}
/**
* Store an attachment related to this model.
*
* @param Request $request The user request.
* @param Post $post The post model.
* @return JsonResponse The response.
* @throws BindingResolutionException
* @throws MassAssignmentException
*/
public function storeAttachment(Request $request, Post $post)
{
if (PostConductor::updatable($post) === true) {
if($request->has("medium") && Media::find($request->medium)) {
$post->attachments()->create(['media_id' => $request->medium]);
return $this->respondCreated();
}
return $this->respondWithErrors(['media' => 'The media ID was not found']);
}
return $this->respondForbidden();
}
/**
* Update/replace attachments related to this model.
*
* @param Request $request The user request.
* @param Post $post The related model.
* @return JsonResponse
* @throws BindingResolutionException
* @throws MassAssignmentException
*/
public function updateAttachments(Request $request, Post $post)
{
if (PostConductor::updatable($post) === true) {
$mediaIds = $request->attachments;
if(is_array($mediaIds) === false) {
$mediaIds = explode(',', $request->attachments);
}
$mediaIds = array_map('trim', $mediaIds); // trim each media ID
$attachments = $post->attachments;
// Delete attachments that are not in $mediaIds
foreach ($attachments as $attachment) {
if (!in_array($attachment->media_id, $mediaIds)) {
$attachment->delete();
}
}
// Create new attachments for media IDs that are not already in $post->attachments()
foreach ($mediaIds as $mediaId) {
$found = false;
foreach ($attachments as $attachment) {
if ($attachment->media_id == $mediaId) {
$found = true;
break;
}
}
if (!$found) {
$post->attachments()->create(['media_id' => $mediaId]);
}
}
return $this->respondNoContent();
}
return $this->respondForbidden();
}
/**
* Delete a specific related attachment.
* @param Request $request The user request.
* @param Post $post The model.
* @param Media $medium The attachment medium.
* @return JsonResponse
* @throws BindingResolutionException
*/
public function deleteAttachment(Request $request, Post $post, Media $medium)
{
if (PostConductor::updatable($post) === true) {
$attachments = $post->attachments;
$deleted = false;
foreach ($attachments as $attachment) {
if ($attachment->media_id === $medium->id) {
$attachment->delete();
$deleted = true;
break;
}
}
if ($deleted) {
// Attachment was deleted successfully
return $this->respondNoContent();
} else {
// Attachment with matching media ID was not found
return $this->respondNotFound();
}
}
return $this->respondForbidden();
}
}

View File

@@ -0,0 +1,111 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\ShortlinkConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\ShortlinkRequest;
use App\Models\Shortlink;
use Illuminate\Http\Request;
class ShortlinkController extends ApiController
{
/**
* ApplicationController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->only(['store','update','destroy']);
}
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
list($collection, $total) = ShortlinkConductor::request($request);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]
],
function ($options) {
return $options['total'] === 0;
}
);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\Shortlink $shortlink The request shortlink.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Shortlink $shortlink)
{
if (ShortlinkConductor::viewable($shortlink) === true) {
return $this->respondAsResource(ShortlinkConductor::model($request, $shortlink));
}
return $this->respondForbidden();
}
/**
* Store a new media resource
*
* @param \App\Http\Requests\ShortlinkRequest $request The shortlink.
* @return \Illuminate\Http\Response
*/
public function store(ShortlinkRequest $request)
{
if (ShortlinkConductor::creatable() === true) {
$shortlink = Shortlink::create($request->all());
return $this->respondAsResource(
ShortlinkConductor::model($request, $shortlink),
['respondCode' => HttpResponseCodes::HTTP_ACCEPTED]
);
}//end if
return $this->respondForbidden();
}
/**
* Update the media resource in storage.
*
* @param \App\Http\Requests\ShortlinkRequest $request The update request.
* @param \App\Models\Shortlink $shortlink The specified shortlink.
* @return \Illuminate\Http\Response
*/
public function update(ShortlinkRequest $request, Shortlink $shortlink)
{
if (ShortlinkConductor::updatable($shortlink) === true) {
$shortlink->update($request->all());
return $this->respondAsResource(ShortlinkConductor::model($request, $shortlink));
}//end if
return $this->respondForbidden();
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Shortlink $shortlink Specified shortlink.
* @return \Illuminate\Http\Response
*/
public function destroy(Shortlink $shortlink)
{
if (ShortlinkConductor::destroyable($shortlink) === true) {
$shortlink->delete();
return $this->respondNoContent();
}
return $this->respondForbidden();
}
}

View File

@@ -1,145 +0,0 @@
<?php
namespace App\Http\Controllers\Api;
use App\Conductors\SubscriptionConductor;
use App\Enum\HttpResponseCodes;
use App\Models\Subscription;
use App\Http\Requests\SubscriptionRequest;
use App\Jobs\SendEmailJob;
use App\Mail\SubscriptionConfirm;
use App\Mail\SubscriptionUnsubscribed;
use Illuminate\Http\Request;
class SubscriptionController extends ApiController
{
/**
* ApplicationController constructor.
*/
public function __construct()
{
$this->middleware('auth:sanctum')
->except(['store', 'destroyByEmail']);
}
/**
* Display a listing of subscribers.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
list($collection, $total) = SubscriptionConductor::request($request);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]]
);
}
/**
* Display the specified user.
*
* @param \Illuminate\Http\Request $request The endpoint request.
* @param \App\Models\Subscription $subscription The subscription model.
* @return \Illuminate\Http\Response
*/
public function show(Request $request, Subscription $subscription)
{
if (SubscriptionConductor::viewable($subscription) === true) {
return $this->respondAsResource(SubscriptionConductor::model($request, $subscription));
}
return $this->respondForbidden();
}
/**
* Store a subscriber email in the database.
*
* @param \App\Http\Requests\SubscriptionRequest $request The subscriber update request.
* @return \Illuminate\Http\Response
*/
public function store(SubscriptionRequest $request)
{
if (SubscriptionConductor::creatable() === true) {
Subscription::create($request->all());
dispatch((new SendEmailJob($request->email, new SubscriptionConfirm($request->email))))->onQueue('mail');
return $this->respondCreated();
} else {
return $this->respondForbidden();
}
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\SubscriptionRequest $request The subscription update request.
* @param \App\Models\Subscription $subscription The specified subscription.
* @return \Illuminate\Http\Response
*/
public function update(SubscriptionRequest $request, Subscription $subscription)
{
// if (EventConductor::updatable($event) === true) {
// $event->update($request->all());
// return $this->respondAsResource(EventConductor::model($request, $event));
// }
// return $this->respondForbidden();
// $input = [];
// $updatable = ['username', 'first_name', 'last_name', 'email', 'phone', 'password'];
// if ($request->user()->hasPermission('admin/user') === true) {
// $updatable = array_merge($updatable, ['email_verified_at']);
// } elseif ($request->user()->is($user) !== true) {
// return $this->respondForbidden();
// }
// $input = $request->only($updatable);
// if (array_key_exists('password', $input) === true) {
// $input['password'] = Hash::make($request->input('password'));
// }
// $user->update($input);
// return $this->respondAsResource((new UserFilter($request))->filter($user));
}
/**
* Remove the user from the database.
*
* @param Subscription $subscription The specified subscription.
* @return \Illuminate\Http\Response
*/
public function destroy(Subscription $subscription)
{
if (SubscriptionConductor::destroyable($subscription) === true) {
$subscription->delete();
return $this->respondNoContent();
} else {
return $this->respondForbidden();
}
}
/**
* Remove the user from the database.
*
* @param SubscriptionRequest $request The specified subscription.
* @return \Illuminate\Http\Response
*/
public function destroyByEmail(SubscriptionRequest $request)
{
$subscription = Subscription::where('email', $request->email)->first();
if ($subscription !== null) {
$subscription->delete();
dispatch((new SendEmailJob($request->email, new SubscriptionUnsubscribed($request->email))))->onQueue('mail');
}
return $this->respondNoContent();
}
}

View File

@@ -2,10 +2,10 @@
namespace App\Http\Controllers\Api;
use App\Conductors\EventConductor;
use App\Enum\HttpResponseCodes;
use App\Http\Requests\UserRequest;
use App\Http\Requests\UserForgotPasswordRequest;
use App\Http\Requests\UserForgotUsernameRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Requests\UserResendVerifyEmailRequest;
use App\Http\Requests\UserResetPasswordRequest;
@@ -14,7 +14,6 @@ use App\Jobs\SendEmailJob;
use App\Mail\ChangedEmail;
use App\Mail\ChangedPassword;
use App\Mail\ChangeEmailVerify;
use App\Mail\ForgotUsername;
use App\Mail\ForgotPassword;
use App\Mail\EmailVerify;
use App\Models\User;
@@ -22,6 +21,8 @@ use App\Models\UserCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Conductors\UserConductor;
use Illuminate\Http\JsonResponse;
use Illuminate\Contracts\Container\BindingResolutionException;
class UserController extends ApiController
{
@@ -37,10 +38,10 @@ class UserController extends ApiController
'register',
'exists',
'forgotPassword',
'forgotUsername',
'resetPassword',
'verifyEmail',
'resendVerifyEmailCode'
'resendVerifyEmailCode',
'eventList',
]);
}
@@ -57,7 +58,8 @@ class UserController extends ApiController
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]]
'appendData' => ['total' => $total]
]
);
}
@@ -71,7 +73,10 @@ class UserController extends ApiController
{
if (UserConductor::creatable() === true) {
$user = User::create($request->all());
return $this->respondAsResource(UserConductor::model($request, $user), ['respondCode' => HttpResponseCodes::HTTP_CREATED]);
return $this->respondAsResource(
UserConductor::model($request, $user),
['respondCode' => HttpResponseCodes::HTTP_CREATED]
);
} else {
return $this->respondForbidden();
}
@@ -104,7 +109,7 @@ class UserController extends ApiController
{
if (UserConductor::updatable($user) === true) {
$input = [];
$updatable = ['username', 'first_name', 'last_name', 'email', 'phone', 'password'];
$updatable = ['first_name', 'last_name', 'email', 'phone', 'password', 'display_name'];
if ($request->user()->hasPermission('admin/user') === true) {
$updatable = array_merge($updatable, ['email_verified_at']);
@@ -143,20 +148,33 @@ class UserController extends ApiController
* Register a new user
*
* @param \App\Http\Requests\UserRegisterRequest $request The register user request.
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function register(UserRegisterRequest $request)
public function register(UserRegisterRequest $request): JsonResponse
{
try {
$user = User::create([
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name'),
'username' => $request->input('username'),
'email' => $request->input('email'),
'phone' => $request->input('phone'),
'password' => Hash::make($request->input('password'))
$userData = $request->only([
'first_name',
'last_name',
'email',
'phone',
'password',
'display_name',
]);
$userData['password'] = Hash::make($userData['password']);
$user = User::where('email', $request->input('email'))
->whereNull('password')
->first();
if ($user === null) {
$user = User::create($userData);
} else {
unset($userData['email']);
$user->update($userData);
}//end if
$code = $user->codes()->create([
'action' => 'verify-email',
]);
@@ -173,26 +191,6 @@ class UserController extends ApiController
}//end try
}
/**
* Sends an email with all the usernames registered at that address
*
* @param \App\Http\Requests\UserForgotUsernameRequest $request The forgot username request.
* @return \Illuminate\Http\Response
*/
public function forgotUsername(UserForgotUsernameRequest $request)
{
$users = User::where('email', $request->input('email'))->whereNotNull('email_verified_at')->get();
if ($users->count() > 0) {
dispatch((new SendEmailJob(
$users->first()->email,
new ForgotUsername($users->pluck('username')->toArray())
)))->onQueue('mail');
return $this->respondNoContent();
}
return $this->respondJson(['message' => 'Username send to the email address if registered']);
}
/**
* Generates a new reset password code
*
@@ -201,7 +199,7 @@ class UserController extends ApiController
*/
public function forgotPassword(UserForgotPasswordRequest $request)
{
$user = User::where('username', $request->input('username'))->first();
$user = User::where('email', $request->input('email'))->first();
if ($user !== null) {
$user->codes()->where('action', 'reset-password')->delete();
$code = $user->codes()->create([
@@ -291,13 +289,13 @@ class UserController extends ApiController
* Resend a new verify email
*
* @param \App\Http\Requests\UserResendVerifyEmailRequest $request The resend verify email request.
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function resendVerifyEmail(UserResendVerifyEmailRequest $request)
public function resendVerifyEmail(UserResendVerifyEmailRequest $request): JsonResponse
{
UserCode::clearExpired();
$user = User::where('username', $request->input('username'))->first();
$user = User::where('email', $request->input('email'))->first();
if ($user !== null) {
$code = $user->codes()->where('action', 'verify-email')->first();
$code->regenerate();
@@ -322,7 +320,7 @@ class UserController extends ApiController
*/
public function resendVerifyEmailCode(UserResendVerifyEmailRequest $request)
{
$user = User::where('username', $request->input('username'))->first();
$user = User::where('email', $request->input('email'))->first();
if ($user !== null) {
$user->codes()->where('action', 'verify-email')->delete();
@@ -339,4 +337,33 @@ class UserController extends ApiController
return $this->respondNotFound();
}
/**
* Return a JSON event list of a user.
*
* @param Request $request The http request.
* @param User $user The specified user.
* @return JsonResponse
*/
public function eventList(Request $request, User $user): JsonResponse
{
if (
$request->user() !== null && (
$request->user() === $user || $request->user()->hasPermission('admin/events') === true
)
) {
$collection = $user->events;
$total = $collection->count();
$collection = EventConductor::collection($request, $collection);
return $this->respondAsResource(
$collection,
['isCollection' => true,
'appendData' => ['total' => $total]
]
);
} else {
return $this->respondForbidden();
}
}
}

View File

@@ -3,13 +3,11 @@
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests;
use DispatchesJobs;
use ValidatesRequests;
}

View File

@@ -40,28 +40,30 @@ class Kernel extends HttpKernel
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
// \App\Http\Middleware\ForceJsonResponse::class,
\App\Http\Middleware\UnmangleRequest::class,
'useSanctumGuard',
\App\Http\Middleware\LogRequest::class,
],
];
/**
* The application's route middleware.
* The application's middleware aliases.
*
* These middleware may be assigned to groups or used individually.
* Aliases may be used to conveniently assign middleware to routes and groups.
*
* @var array<string, class-string|string>
*/
protected $routeMiddleware = [
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'unmangle' => \App\Http\Middleware\UnmangleRequest::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,

View File

@@ -10,12 +10,14 @@ class Authenticate extends Middleware
* Get the path the user should be redirected to when they are not authenticated.
*
* @param mixed $request Request.
* @return string|null
* @return ?string
*/
protected function redirectTo(mixed $request)
protected function redirectTo(mixed $request): ?string
{
if ($request->expectsJson() === false) {
return route('login');
}
return null;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Response;
use Closure;
use Illuminate\Http\Request;
@@ -10,11 +11,9 @@ class ForceJsonResponse
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, Closure $next): Response
{
$request->headers->set('Accept', 'application/json');
return $next($request);

View File

@@ -2,30 +2,29 @@
namespace App\Http\Middleware;
use App\Models\AnalyticsItemRequest;
use Symfony\Component\HttpFoundation\Response;
use Closure;
use Illuminate\Http\Request;
use App\Models\Analytics;
class LogRequest
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
* @param Illuminate\Http\Request $request HTTP Request.
* @param \Closure $next Closure.
* @return Symfony\Component\HttpFoundation\Response
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, Closure $next): Response
{
// Make it an after middleware
$response = $next($request);
try {
Analytics::create([
'type' => 'pageview',
'attribute' => $request->path(),
'useragent' => $request->userAgent(),
'ip' => $request->ip(),
AnalyticsItemRequest::create([
'type' => 'apirequest',
'path' => $request->path(),
]);
return $response;

View File

@@ -2,6 +2,7 @@
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Response;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
@@ -13,11 +14,11 @@ class RedirectIfAuthenticated
* Handle an incoming request.
*
* @param Request $request Request.
* @param Closure(Request): (Response|RedirectResponse) $next Next.
* @param \Closure $next Closure.
* @param string|null ...$guards Guards.
* @return Response|RedirectResponse
* @return Response
*/
public function handle(Request $request, Closure $next, ...$guards)
public function handle(Request $request, Closure $next, string ...$guards): Response
{
$guards = empty($guards) === true ? [null] : $guards;

View File

@@ -11,7 +11,7 @@ class TrustHosts extends Middleware
*
* @return array<int, string|null>
*/
public function hosts()
public function hosts(): array
{
return [
$this->allSubdomainsOfApplicationUrl(),

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Response;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class UnmangleRequest
{
/**
* Handle an incoming request.
*
* @param Request $request Request.
* @param \Closure $next Next.
* @param string|null ...$guards Guards.
* @return Response response.
*/
public function handle(Request $request, Closure $next, string ...$guards): Response
{
if (isset($_SERVER['QUERY_STRING']) === true) {
$params = $request->all();
$string = $_SERVER['QUERY_STRING'];
$parts = explode('&', $string);
foreach ($parts as $part) {
$key = $part;
$splitPos = strpos($key, '=');
if ($splitPos !== false) {
$key = urldecode(substr($key, 0, $splitPos));
}
$replace_key = str_replace('.', '_', $key);
if (strpos($key, '.') !== false && array_key_exists($replace_key, $params) === true) {
$params[$key] = $params[$replace_key];
unset($params[$replace_key]);
}
}
$request->replace($params);
}//end if
return $next($request);
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Middleware;
use Symfony\Component\HttpFoundation\Response;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -11,11 +12,11 @@ class UseSanctumGuard
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
* @param Request $request Request object.
* @param \Closure $next Closure object.
* @return Response
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, Closure $next): Response
{
Auth::shouldUse('sanctum');
return $next($request);

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Validation\Rule;
class AnalyticsRequest extends BaseRequest
{
/**
* Get the validation rules that apply to POST requests.
*
* @return array<string, mixed>
*/
public function postRules(): array
{
return [
'type' => 'required|string',
];
}
/**
* Get the validation rules that apply to PUT request.
*
* @return array<string, mixed>
*/
public function putRules(): array
{
return [
'type' => 'string',
'useragent' => 'string',
'ip' => 'ipv4|ipv6',
'session' => 'number',
];
}
}

View File

@@ -4,17 +4,17 @@ namespace App\Http\Requests;
use Illuminate\Validation\Rule;
class PostRequest extends BaseRequest
class ArticleRequest extends BaseRequest
{
/**
* Get the validation rules that apply to POST requests.
*
* @return array<string, mixed>
*/
public function postRules()
public function postRules(): array
{
return [
'slug' => 'required|string|min:6|unique:posts',
'slug' => 'required|string|min:6|unique:articles',
'title' => 'required|string|min:6|max:255',
'publish_at' => 'required|date',
'user_id' => 'required|uuid|exists:users,id',
@@ -28,13 +28,13 @@ class PostRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function putRules()
public function putRules(): array
{
return [
'slug' => [
'string',
'min:6',
Rule::unique('posts')->ignoreModel($this->post),
Rule::unique('articles')->ignoreModel($this->article),
],
'title' => 'string|min:6|max:255',
'publish_at' => 'date',

View File

@@ -11,10 +11,10 @@ class AuthLoginRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'username' => 'required|string|min:6|max:255',
'email' => 'required|string|min:6|max:255',
'password' => 'required|string|min:6',
];
}

View File

@@ -12,11 +12,15 @@ class BaseRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
if (request()->isMethod('post') === true && method_exists($this, 'postAuthorize') === true) {
return $this->postAuthorize();
} elseif ((request()->isMethod('put') === true || request()->isMethod('patch') === true) && method_exists($this, 'putAuthorize') === true) {
} elseif (
(
request()->isMethod('put') === true || request()->isMethod('patch') === true
) && method_exists($this, 'putAuthorize') === true
) {
return $this->putAuthorize();
} elseif (request()->isMethod('delete') === true && method_exists($this, 'destroyAuthorize') === true) {
return $this->deleteAuthorize();
@@ -30,7 +34,7 @@ class BaseRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
$rules = [];
@@ -40,7 +44,11 @@ class BaseRequest extends FormRequest
if (method_exists($this, 'postRules') === true && request()->isMethod('post') === true) {
$rules = $this->mergeRules($rules, $this->postRules());
} elseif (method_exists($this, 'putRules') === true && (request()->isMethod('put') === true || request()->isMethod('patch') === true)) {
} elseif (
method_exists($this, 'putRules') === true && (
request()->isMethod('put') === true || request()->isMethod('patch') === true
)
) {
$rules = $this->mergeRules($rules, $this->putRules());
} elseif (method_exists($this, 'destroyRules') === true && request()->isMethod('delete') === true) {
$rules = $this->mergeRules($rules, $this->destroyRules());
@@ -56,7 +64,7 @@ class BaseRequest extends FormRequest
* @param array $collection2 The second collection of rules to merge.
* @return array
*/
private function mergeRules(array $collection1, array $collection2)
private function mergeRules(array $collection1, array $collection2): array
{
$rules = [];

View File

@@ -12,13 +12,13 @@ class ContactSendRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'name' => 'required|max:255',
'email' => 'required|email|max:255',
'content' => 'required|max:2000',
'captcha_token' => [new Recaptcha()],
// 'captcha_token' => [new Recaptcha()],
];
}
}

View File

@@ -11,7 +11,7 @@ class EventRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function baseRules()
public function baseRules(): array
{
return [
'title' => 'min:6',
@@ -23,7 +23,7 @@ class EventRequest extends BaseRequest
'end_at' => 'date|after:start_date',
'publish_at' => 'date|nullable',
'status' => [
Rule::in(['draft', 'soon', 'open', 'closed', 'cancelled']),
Rule::in(['draft', 'soon', 'open', 'closed', 'cancelled', 'scheduled', 'full']),
],
'registration_type' => [
Rule::in(['none', 'email', 'link', 'message']),
@@ -34,6 +34,7 @@ class EventRequest extends BaseRequest
Rule::when(strcasecmp('message', $this->attributes->get('registration_type')) == 0, 'required|message'),
],
'hero' => 'uuid|exists:media,id',
'location_url' => 'sometimes|string|max:255',
];
}
@@ -42,7 +43,7 @@ class EventRequest extends BaseRequest
*
* @return array<string, mixed>
*/
protected function postRules()
protected function postRules(): array
{
return [
'title' => 'required',

View File

@@ -2,7 +2,32 @@
namespace App\Http\Requests;
use Illuminate\Validation\Rule;
class MediaRequest extends BaseRequest
{
/* empty */
/**
* POST request rules
*
* @return array
*/
public function postRules(): array
{
return [
'job_id' => [
Rule::requiredIf(function () {
return request()->has('chunk') && request('chunk') != 1;
}),
'string',
],
'name' => [
Rule::requiredIf(function () {
return request()->has('chunk') && request('chunk') == 1;
}),
'string',
],
'chunk' => 'required_with:chunk_count|integer|min:1|max:999|lte:chunk_count',
'chunk_count' => 'required_with:chunk|integer|min:1',
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Http\Requests;
use Illuminate\Validation\Rule;
class ShortlinkRequest extends BaseRequest
{
/**
* Apply the additional POST base rules to this request
*
* @return array<string, mixed>
*/
public function postRules(): array
{
return [
'code' => 'required|string|max:255|min:2|unique:shortlinks',
'url' => 'required|string|max:255|min:2',
];
}
/**
* Get the validation rules that apply to PUT request.
*
* @return array<string, mixed>
*/
public function putRules(): array
{
$shortlink = $this->route('shortlink');
return [
'code' => ['required', 'string', 'max:255', 'min:2', Rule::unique('shortlinks')->ignore($shortlink->id)],
'url' => 'required|string|max:255|min:2',
];
}
}

View File

@@ -11,11 +11,11 @@ class SubscriptionRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function postRules()
public function postRules(): array
{
return [
'email' => 'required|email|unique:subscriptions',
'captcha_token' => [new Recaptcha()],
// 'captcha_token' => [new Recaptcha()],
];
}
@@ -24,11 +24,11 @@ class SubscriptionRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function destroyRules()
public function destroyRules(): array
{
return [
'email' => 'required|email',
'captcha_token' => [new Recaptcha()],
// 'captcha_token' => [new Recaptcha()],
];
}
@@ -37,7 +37,7 @@ class SubscriptionRequest extends BaseRequest
*
* @return array
*/
public function messages()
public function messages(): array
{
return [
'email.unique' => 'This email address has already subscribed',

View File

@@ -12,11 +12,11 @@ class UserForgotPasswordRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'username' => 'required|exists:users,username',
'captcha_token' => [new Recaptcha()],
'email' => 'required|exists:users,email',
// 'captcha_token' => [new Recaptcha()],
];
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Http\Requests;
use App\Rules\Recaptcha;
use Illuminate\Foundation\Http\FormRequest;
class UserForgotUsernameRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array<string, mixed>
*/
public function rules()
{
return [
'email' => 'required|email|max:255',
'captcha_token' => [new Recaptcha()],
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Requests;
use App\Rules\Uniqueish;
use Illuminate\Foundation\Http\FormRequest;
class UserRegisterRequest extends FormRequest
@@ -11,13 +12,11 @@ class UserRegisterRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255',
'username' => 'required|string|min:4|max:255|unique:users',
'display_name' => ['required','string','max:255', new Uniqueish('users')],
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
];
}

View File

@@ -2,7 +2,11 @@
namespace App\Http\Requests;
use App\Rules\RequiredIfAny;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\RequiredIf;
use App\Rules\Uniqueish;
use Illuminate\Support\Arr;
class UserRequest extends BaseRequest
{
@@ -11,13 +15,25 @@ class UserRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function postRules()
public function postRules(): array
{
$user = auth()->user();
$isAdminUser = $user->hasPermission('admin/users');
return [
'username' => 'required|string|max:255|min:4|unique:users',
'first_name' => 'required|string|max:255|min:2',
'last_name' => 'required|string|max:255|min:2',
'email' => 'required|string|email|max:255',
'first_name' => (
$isAdminUser === true ? 'required_with:last_name,display_name,phone' : 'required'
) . '|string|max:255|min:2',
'last_name' => (
$isAdminUser === true ? 'required_with:first_name,display_name,phone' : 'required'
) . '|string|max:255|min:2',
'display_name' => [
$isAdminUser === true ? 'required_with:first_name,last_name,phone' : 'required',
'string',
'max:255',
new Uniqueish('users')
],
'email' => 'required|string|email|max:255|unique:users',
'phone' => ['string', 'regex:/^(\+|00)?[0-9][0-9 \-\(\)\.]{7,32}$/'],
'email_verified_at' => 'date'
];
@@ -28,27 +44,68 @@ class UserRequest extends BaseRequest
*
* @return array<string, mixed>
*/
public function putRules()
public function putRules(): array
{
$user = $this->route('user');
$user = auth()->user();
$ruleUser = $this->route('user');
$isAdminUser = $user->hasPermission('admin/users');
$requiredIfFieldsPresent = function (array $fields) use ($ruleUser): RequiredIf {
return new RequiredIf(function () use ($fields, $ruleUser) {
$input = $this->all();
$values = Arr::only($input, $fields);
foreach ($values as $key => $value) {
if ($value !== null && $value !== '') {
return true;
}
}
$fields = array_diff($fields, array_keys($values));
foreach ($fields as $field) {
if ($ruleUser->$field !== '') {
return true;
}
}
return false;
});
};
return [
'username' => [
'first_name' => [
'sometimes',
$isAdminUser === true ? $requiredIfFieldsPresent(['last_name', 'display_name', 'phone']) : 'required',
'string',
'between:2,255',
],
'last_name' => [
'sometimes',
$isAdminUser === true ? $requiredIfFieldsPresent(['first_name', 'last_name', 'phone']) : 'required',
'string',
'between:2,255',
],
'display_name' => [
'sometimes',
$isAdminUser === true ? $requiredIfFieldsPresent(['first_name', 'display_name', 'phone']) : 'required',
'string',
'between:2,255',
(new Uniqueish('users', 'display_name'))->ignore($ruleUser->id)
],
'email' => [
'string',
'email',
'max:255',
'min:4',
Rule::unique('users')->ignore($user->id)->when(
$this->username !== $user->username,
Rule::unique('users')->ignore($ruleUser->id)->when(
$this->email !== $ruleUser->email,
function ($query) {
return $query->where('username', $this->username);
return $query->where('email', $this->email);
}
),
],
'first_name' => 'string|max:255|min:2',
'last_name' => 'string|max:255|min:2',
'email' => 'string|email|max:255',
'phone' => ['nullable','regex:/^(\+|00)?[0-9][0-9 \-\(\)\.]{7,32}$/'],
'password' => 'string|min:8'
'phone' => ['nullable', 'regex:/^(\+|00)?[0-9][0-9 \-\(\)\.]{7,32}$/'],
'password' => "nullable|string|min:8"
];
}
}

View File

@@ -12,11 +12,11 @@ class UserResendVerifyEmailRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'username' => 'required|exists:users,username',
'captcha_token' => [new Recaptcha()],
'email' => 'required|exists:users,email',
// 'captcha_token' => [new Recaptcha()],
];
}
}

View File

@@ -12,12 +12,12 @@ class UserResetPasswordRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'code' => 'required|digits:6',
'password' => 'required|string|min:8',
'captcha_token' => [new Recaptcha()],
// 'captcha_token' => [new Recaptcha()],
];
}
}

View File

@@ -12,11 +12,11 @@ class UserVerifyEmailRequest extends FormRequest
*
* @return array<string, mixed>
*/
public function rules()
public function rules(): array
{
return [
'code' => 'required|digits:6',
'captcha_token' => [new Recaptcha()],
// 'captcha_token' => [new Recaptcha()],
];
}
}

393
app/Jobs/MediaWorkerJob.php Normal file
View File

@@ -0,0 +1,393 @@
<?php
namespace App\Jobs;
use App\Models\Media;
use App\Models\MediaJob;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use FFMpeg;
use FFMpeg\Coordinate\Dimension;
use FFMpeg\FFProbe;
use FFMpeg\Format\VideoInterface;
use Intervention\Image\Facades\Image;
/** @property on $format */
class MediaWorkerJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/**
* MediaJob item
*
* @var MediaJob
*/
protected $mediaJob;
/**
* Create a new job instance.
*
* @param MediaJob $mediaJob The mediaJob model.
* @return void
*/
public function __construct(MediaJob $mediaJob)
{
$this->mediaJob = $mediaJob;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(): void
{
$media = $this->mediaJob->media()->first();
$newMedia = false;
$data = json_decode($this->mediaJob->data, true);
try {
// FILE
if (array_key_exists('file', $data) === true) {
if (file_exists($data['file']) === false) {
$this->throwMediaJobFailure('temporary upload file no longer exists');
}
// convert HEIC files to JPG
$fileExtension = File::extension($data['file']);
if ($fileExtension === 'heic') {
$this->mediaJob->setStatusProcessing(0, 0, 'converting image');
// Get the path without the file name
$uploadedFileDirectory = dirname($data['file']);
// Convert the HEIC file to JPG
$jpgFileName = pathinfo($data['file'], PATHINFO_FILENAME) . '.jpg';
$jpgFilePath = $uploadedFileDirectory . '/' . $jpgFileName;
if (file_exists($jpgFilePath) === true) {
$this->throwMediaJobFailure('file already exists on server');
}
Image::make($data['file'])->save($jpgFilePath);
// Update the uploaded file path and file name
unlink($data['file']);
$data['file'] = $jpgFileName;
}//end if
// get security
$security = [];
if ($media === null) {
if (array_key_exists('security', $data) === true) {
$security = $data['security'];
}
} else {
$security['type'] = $media->security_type;
$security['data'] = $media->security_data;
}
// get storage
$storage = '';
if ($media === null) {
if (array_key_exists('storage', $data) === true) {
$storage = $data['storage'];
}
} else {
$storage = $media->storage;
}
if ($storage === '') {
if (count($security) === 0 || $security['type'] === '') {
if (strpos($data['mime_type'], 'image/') === 0) {
$storage = 'local';
} else {
$storage = 'cdn';
}
} else {
$storage = 'private';
}
}
// Check if file already exists
$exists = Storage::disk($storage)->exists($data['name']);
if ($exists === true) {
if (array_key_exists('noreplace', $data) === true && isTrue($data['noreplace']) === true) {
$this->throwMediaJobFailure('file already exists on server');
}
}
if ($exists === true) {
$pathInfo = pathinfo($data['name']);
$basename = $pathInfo['filename'];
$extension = $pathInfo['extension'];
$index = 0;
do {
$index++;
$data['name'] = $basename . '-' . $index . '.' . $extension;
} while (Storage::disk($storage)->exists($data['name']) === true);
}
if ($media === null) {
$newMedia = true;
$media = new Media([
'user_id' => $this->mediaJob->user_id,
'title' => $data['title'],
'name' => $data['name'],
'mime_type' => $data['mime_type'],
'size' => $data['size'],
'security_type' => $data['security']['type'],
'security_data' => $data['security']['data'],
'storage' => $storage,
]);
}//end if
$media->setStagingFile($data['file']);
} else {
if ($media === null) {
$this->throwMediaJobFailure('The media item no longer exists');
}
}//end if
if (array_key_exists('transform', $data) === true) {
$media->createStagingFile();
// Modifications
if (strpos($media->mime_type, 'image/') === 0) {
$modified = false;
$image = Image::make($media->getStagingFilePath());
// ROTATE
if (array_key_exists("rotate", $data['transform']) === true) {
$rotate = intval($data['transform']['rotate']);
if ($rotate !== 0) {
$this->mediaJob->setStatusProcessing(0, 0, 'rotating image');
$image = $image->rotate($rotate);
$modified = true;
}
}
// FLIP-H/V
if (array_key_exists('flip', $data['transform']) === true) {
if (stripos($data['transform']['flip'], 'h') !== false) {
$this->mediaJob->setStatusProcessing(0, 0, 'flipping image');
$image = $image->flip('h');
$modified = true;
}
if (stripos($data['transform']['flip'], 'v') !== false) {
$this->mediaJob->setStatusProcessing(0, 0, 'flipping image');
$image = $image->flip('v');
$modified = true;
}
}
// CROP
if (array_key_exists("crop", $data['transform']) === true) {
$cropData = $data['transform']['crop'];
$width = intval(arrayDefaultValue("width", $cropData, $image->getWidth()));
$height = intval(arrayDefaultValue("height", $cropData, $image->getHeight()));
$x = intval(arrayDefaultValue("x", $cropData, 0));
$y = intval(arrayDefaultValue("y", $cropData, 0));
$this->mediaJob->setStatusProcessing(0, 0, 'cropping image');
$image = $image->crop($width, $height, $x, $y);
$modified = true;
}//end if
if ($modified === true) {
$image->save();
}
} elseif (strpos($data['mime_type'], 'video/') === 0) {
$stagingFilePath = $media->getStagingFilePath();
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open($stagingFilePath);
$format = $this->detectVideoFormat($stagingFilePath);
$modified = false;
if ($format === null) {
$this->mediaJob->setStatusFailed('Unsupported video format');
return;
}
/** @var FFMpeg\Media\Video::filters */
$filters = $video->filters();
// ROTATE
if (array_key_exists("rotate", $data['transform']) === true) {
$rotate = intval($data['transform']['rotate']);
$rotate = (($rotate % 360 + 360) % 360); // remove excess rotations
$rotate = intval(round($rotate / 90) * 90); // round to nearest 90%
if ($rotate > 0) {
$this->mediaJob->setStatusProcessing(0, 0, 'rotating video');
if ($rotate === 90) {
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_270);
$modified = true;
} elseif ($rotate === 180) {
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_180);
$modified = true;
} elseif ($rotate === 270) {
$filters->rotate(FFMpeg\Filters\Video\RotateFilter::ROTATE_90);
$modified = true;
}
}
}
// FLIP-H/V
if (array_key_exists('flip', $data['transform']) === true) {
if (stripos($data['transform']['flip'], 'h') !== false) {
$this->mediaJob->setStatusProcessing(0, 0, 'flipping video');
$filters->hflip()->synchronize();
$modified = true;
}
if (stripos($data['transform']['flip'], 'v') !== false) {
$this->mediaJob->setStatusProcessing(0, 0, 'flipping video');
$filters->vflip()->synchronize();
$modified = true;
}
}
// CROP
if (array_key_exists("crop", $data['transform']) === true) {
$cropData = $data['transform']['crop'];
$videoStream = $video->getStreams()->videos()->first();
$width = intval(arrayDefaultValue("width", $cropData, $videoStream->get('width')));
$height = intval(arrayDefaultValue("height", $cropData, $videoStream->get('height')));
$x = intval(arrayDefaultValue("x", $cropData, 0));
$y = intval(arrayDefaultValue("y", $cropData, 0));
$cropDimension = new Dimension($width, $height);
$this->mediaJob->setStatusProcessing(0, 0, 'cropping video');
$filters->crop($cropDimension, $x, $y)->synchronize();
$modified = true;
}//end if
$tempFilePath = generateTempFilePath(pathinfo($stagingFilePath, PATHINFO_EXTENSION));
if (method_exists($format, 'on') === true) {
$mediaJob = $this->mediaJob;
$format->on('progress', function ($video, $format, $percentage) use ($mediaJob) {
$mediaJob->setStatusProcessing($percentage, 100, 'transcoded');
});
}
if ($modified === true) {
$video->save($format, $tempFilePath);
$media->changeStagingFile($tempFilePath);
}
}//end if
}//end if
// Update attributes
if (array_key_exists('title', $data) === true) {
$media->title = $data['title'];
}
// Relocate file (if requested)
if (array_key_exists('security', $data) === true && array_key_exists('type', $data['security']) === true) {
$media->security_type = $data['security']['type'];
$media->security_data = $data['security']['data'];
}
if (array_key_exists('storage', $data) === true) {
if ($media->storage !== $data['storage']) {
$media->createStagingFile();
Storage::disk($media->storage)->delete($media->name);
$media->storage = $data['storage'];
}
}
// Finish media object
if ($media->hasStagingFile() === true) {
$this->mediaJob->setStatusProcessing(0, 0, 'transferring to cdn');
$media->deleteFile();
$media->saveStagingFile(true);
}
$media->save();
$this->mediaJob->media_id = $media->id;
$this->mediaJob->setStatusComplete();
} catch (\Exception $e) {
if ($this->mediaJob->status !== 'failed') {
$this->mediaJob->setStatusFailed('Unexpected server error occurred');
}
if ($media !== null) {
$media->deleteStagingFile();
if ($newMedia === true) {
$media->delete();
}
}
Log::error($e->getMessage() . "\n" . $e->getFile() . " - " . $e->getLine() . "\n" . $e->getTraceAsString());
$this->fail($e);
}//end try
}
/**
* Detects the format of a video using FFProbe
*
* @param string $videoPath The video file path.
* @return VideoInterface | null
*/
public function detectVideoFormat(string $videoPath): VideoInterface | null
{
$ffprobe = FFProbe::create();
$videoStream = $ffprobe
->streams($videoPath) // Provide the path to the video file
->videos() // Filter video streams
->first();
$codecName = $videoStream->get('codec_name');
$codecToFormatClass = [
'h264' => 'FFMpeg\Format\Video\X264',
'wmv2' => 'FFMpeg\Format\Video\WMV',
'vp9' => 'FFMpeg\Format\Video\WebM',
'theora' => 'FFMpeg\Format\Video\Ogg',
'mpeg4' => 'FFMpeg\Format\Video\Mpeg4',
// Add more mappings as needed
];
if (isset($codecToFormatClass[$codecName]) === false) {
Log::info("Unsupported codec: $codecName");
return null;
}
$formatClassName = $codecToFormatClass[$codecName];
if (class_exists($formatClassName) === false) {
Log::info("Format class does not exist: $formatClassName");
return null;
}
return new $formatClassName();
}
/**
* Set failure status of MediaJob and throw exception.
*
* @param string $error The failure message.
* @return void
*/
private function throwMediaJobFailure(string $error): void
{
$this->mediaJob->setStatusFailed($error);
throw new \Exception($error);
}
}

View File

@@ -50,7 +50,7 @@ class SendEmailJob implements ShouldQueue
*
* @return void
*/
public function handle()
public function handle(): void
{
Mail::to($this->to)->send($this->mailable);
}

View File

@@ -55,9 +55,9 @@ class ChangeEmailVerify extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '👋🏻 Lets change your email!',
@@ -67,9 +67,9 @@ class ChangeEmailVerify extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.change_email_verify',

View File

@@ -55,9 +55,9 @@ class ChangedEmail extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '👍 Your email has been changed!',
@@ -67,9 +67,9 @@ class ChangedEmail extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.changed_email',

View File

@@ -37,9 +37,9 @@ class ChangedPassword extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '👍 Your password has been changed!',
@@ -49,9 +49,9 @@ class ChangedPassword extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.changed_password',

View File

@@ -54,9 +54,9 @@ class Contact extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: config('contact.contact_subject'),
@@ -66,9 +66,9 @@ class Contact extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.contact',

View File

@@ -46,9 +46,9 @@ class EmailVerify extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '👋🏻 Welcome to STEMMechanics!',
@@ -58,9 +58,9 @@ class EmailVerify extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.email_verify',

View File

@@ -9,52 +9,51 @@ use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class ForgotUsername extends Mailable
class ExceptionMail extends Mailable
{
use Queueable;
use SerializesModels;
/**
* The list of usernames
*
* @var string[]
*/
public $usernames;
/**
* Create a new message instance.
*
* @param array $usernames The usernames.
* @return void
*/
public function __construct(array $usernames)
public function __construct()
{
$this->usernames = $usernames;
//
}
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '🤦 Forgot your username?',
subject: 'Exception Mail',
);
}
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.forgot_username',
text: 'emails.user.forgot_username_plain',
view: 'view.name',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

View File

@@ -46,9 +46,9 @@ class ForgotPassword extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '🤦 Forgot your password?',
@@ -58,9 +58,9 @@ class ForgotPassword extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.forgot_password',

View File

@@ -37,9 +37,9 @@ class SubscriptionConfirm extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: '🗞️ You\'re on the mailing list!',
@@ -49,9 +49,9 @@ class SubscriptionConfirm extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.subscription_confirm',

View File

@@ -37,9 +37,9 @@ class SubscriptionUnsubscribed extends Mailable
/**
* Get the message envelope.
*
* @return \Illuminate\Mail\Mailables\Envelope
* @return Illuminate\Mail\Mailables\Envelope
*/
public function envelope()
public function envelope(): Envelope
{
return new Envelope(
subject: 'You have been unsubscribed',
@@ -49,9 +49,9 @@ class SubscriptionUnsubscribed extends Mailable
/**
* Get the message content definition.
*
* @return \Illuminate\Mail\Mailables\Content
* @return Illuminate\Mail\Mailables\Content
*/
public function content()
public function content(): Content
{
return new Content(
view: 'emails.user.subscription_unsubscribed',

View File

@@ -1,18 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Analytics extends Model
{
use HasFactory;
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = [];
}

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AnalyticsItemRequest extends Model
{
use HasFactory;
/**
* The table name
*
* @var string
*/
protected $table = 'analytics_requests';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'type',
'path'
];
/**
* Model Boot.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::creating(function (AnalyticsItemRequest $analytics) {
if (isset($analytics->session_id) !== true) {
$request = request();
if ($request !== null) {
$session = AnalyticsSession::where('ip', $request->ip())
->where('useragent', $request->userAgent())
->where('ended_at', '>=', now()->subMinutes(30))
->first();
if ($session === null) {
$session = AnalyticsSession::create([
'ip' => $request->ip(),
'useragent' => $request->userAgent(),
'ended_at' => now()
]);
} else {
$session->update(['ended_at' => now()]);
}
$analytics->session_id = $session->id;
}
}//end if
});
}
/**
* Return the Analytics Session model.
*
* @return BelongsTo
*/
public function session(): BelongsTo
{
return $this->belongsTo(AnalyticsSession::class, 'id', 'session_id');
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class AnalyticsSession extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'ip',
'useragent',
'ended_at'
];
/**
* Set the "useragent" attribute.
*
* @param mixed $value
* @return void
*/
public function setUseragentAttribute($value)
{
$this->attributes['useragent'] = $value !== null ? $value : '';
}
/**
* Returns the related requests for this session.
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function requests(): HasMany {
return $this->hasMany(AnalyticsItemRequest::class, 'session_id', 'id');
}
}

View File

@@ -2,14 +2,19 @@
namespace App\Models;
use App\Traits\HasAttachments;
use App\Traits\HasGallery;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Post extends Model
class Article extends Model
{
use HasFactory;
use Uuids;
use HasGallery;
use HasAttachments;
/**
* The attributes that are mass assignable.
@@ -27,20 +32,12 @@ class Post extends Model
/**
* Get the post user
* Get the article user
*
* @return BelongsTo
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* Get all of the post's attachments.
*/
public function attachments()
{
return $this->morphMany('App\Models\Attachment', 'attachable');
}
}

View File

@@ -4,6 +4,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Cache;
class Attachment extends Model
{
@@ -16,22 +18,69 @@ class Attachment extends Model
*/
protected $fillable = [
'media_id',
'private',
];
/**
* The default attributes.
*
* @var string[]
*/
protected $attributes = [
'private' => false,
];
/**
* Get attachments attachable
*/
public function attachable()
{
return $this->morphTo();
}
/**
* Get the media for this attachment.
*
* @return BelongsTo
*/
public function media()
public function media(): BelongsTo
{
return $this->belongsTo(Media::class);
}
/**
* Get associated Media object.
*
* @return null|Media
*/
public function getMediaAttribute(): ?Media
{
$mediaId = '0';
$media = null;
if (Cache::has("attachment:{$this->id}:media") === true) {
$mediaId = Cache::get("attachment:{$this->id}:media");
} else {
$media = $this->media()->first();
if ($media === null) {
return null;
}
$mediaId = $media->id;
Cache::put("attachment:{$this->id}:media", $mediaId, now()->addDays(28));
}
return Cache::remember("media:{$mediaId}", now()->addDays(28), function () use ($media) {
if ($media !== null) {
return $media;
}
return $this->media()->first();
});
}
/**
* Set the media for this item.
*
* @param Media $media The media model.
* @return void
*/
public function setMediaAttribute(Media $media): void
{
$this->media()->associate($media)->save();
Cache::put("attachment:{$this->id}:media", $media->id, now()->addDays(28));
}
}

View File

@@ -2,12 +2,16 @@
namespace App\Models;
use App\Traits\HasAttachments;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
class Event extends Model
{
use HasAttachments;
use HasFactory;
use Uuids;
@@ -19,6 +23,7 @@ class Event extends Model
protected $fillable = [
'title',
'location',
'location_url',
'address',
'start_at',
'end_at',
@@ -30,14 +35,17 @@ class Event extends Model
'content',
'price',
'ages',
'open_at',
];
/**
* Get all of the post's attachments.
* Get all the associated users.
*
* @return BelongsToMany
*/
public function attachments()
public function users(): BelongsToMany
{
return $this->morphMany('App\Models\Attachment', 'attachable');
return $this->belongsToMany(User::class, 'event_user', 'event_id', 'user_id');
}
}

45
app/Models/EventUsers.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
namespace App\Models;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class EventUser extends Model
{
use HasFactory;
use Uuids;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'event_id',
'user_id',
];
/**
* Get the event for this attachment.
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function event(): BelongsTo
{
return $this->belongsTo(Event::class);
}
/**
* Get the user for this attachment.
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

107
app/Models/Gallery.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
namespace App\Models;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Cache;
class Gallery extends Model
{
use HasFactory;
use Uuids;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'media_id',
];
/**
* Boot the model.
*
* @return void
*/
protected static function boot(): void
{
parent::boot();
$clearCache = function ($gallery) {
Cache::forget("gallery:{$gallery->id}:media");
};
static::saving($clearCache);
static::deleting($clearCache);
}
/**
* Get gallery addendum model.
*
* @return Illuminate\Database\Eloquent\Relations\MorphTo Addenum model.
*/
public function addendum(): MorphTo
{
return $this->morphTo();
}
/**
* Get the media for this item.
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo The media model.
*/
public function media(): BelongsTo
{
return $this->belongsTo(Media::class);
}
/**
* Get the media for this item.
*
* @return null|Media The media model.
*/
public function getMediaAttribute(): ?Media
{
$mediaId = '0';
$media = null;
if (Cache::has("gallery:{$this->id}:media") === true) {
$mediaId = Cache::get("gallery:{$this->id}:media");
} else {
$media = $this->media()->first();
if ($media === null) {
return null;
}
$mediaId = $media->id;
Cache::put("gallery:{$this->id}:media", $mediaId, now()->addDays(28));
}
return Cache::remember("media:{$mediaId}", now()->addDays(28), function () use ($media) {
if ($media !== null) {
return $media;
}
return $this->media()->first();
});
}
/**
* Set the media for this item.
*
* @param Media $media The media model.
* @return void
*/
public function setMediaAttribute(Media $media): void
{
$this->media()->associate($media)->save();
Cache::put("gallery:{$this->id}:media", $media->id, now()->addDays(28));
}
}

File diff suppressed because it is too large Load Diff

239
app/Models/MediaJob.php Normal file
View File

@@ -0,0 +1,239 @@
<?php
namespace App\Models;
use App\Jobs\MediaWorkerJob;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class MediaJob extends Model
{
use HasFactory;
use Uuids;
/**
* The default attributes.
*
* @var string[]
*/
protected $attributes = [
'user_id' => null,
'media_id' => null,
'status' => '',
'status_text' => '',
'progress' => 0,
'progress_max' => 0,
'data' => '',
];
/**
* Set MediaJob status to failed.
*
* @param string $statusText The failed reason.
* @return void
*/
public function setStatusFailed(string $statusText = ''): void
{
$this->setStatus('failed', $statusText, 0);
}
/**
* Set MediaJob status to queued.
*
* @return void
*/
public function setStatusQueued(): void
{
$this->setStatus('queued', '', 0);
}
/**
* Set MediaJob status to waiting.
*
* @return void
*/
public function setStatusWaiting(): void
{
$this->setStatus('waiting', '', 0);
}
/**
* Set MediaJob status to processing.
*
* @param integer $progress The processing progress value.
* @param integer $progressMax The processing progress maximum value.
* @param string $statusText The processing status text.
* @return void
*/
public function setStatusProcessing(int $progress = 0, int $progressMax = 0, string $statusText = ''): void
{
if ($statusText === '') {
$statusText = $this->status_text;
}
$this->setStatus('processing', $statusText, $progress, $progressMax);
}
/**
* Set MediaJob status to complete.
*
* @return void
*/
public function setStatusComplete(): void
{
$this->setStatus('complete');
}
/**
* Set MediaJon status to invalid.
*
* @param string $text The status text.
* @return void
*/
public function setStatusInvalid(string $text = ''): void
{
$this->setStatus('invalid', $text);
}
/**
* Set MediaJob status details.
*
* @param string $status The status string.
* @param string $text The status text.
* @param integer $progress The status progress value.
* @param integer $progress_max The status progress maximum value.
* @return void
*/
protected function setStatus(string $status, string $text = '', int $progress = 0, int $progress_max = 0): void
{
$this->status = $status;
$this->status_text = $text;
$this->progress = $progress;
$this->progress_max = $progress_max;
$this->save();
}
/**
* Process the MediaJob.
*
* @return void
*/
public function process(): void
{
$data = json_decode($this->data, true);
if ($data !== null) {
if (array_key_exists('chunks', $data) === true) {
if (array_key_exists('chunk_count', $data) === false) {
$this->setStatusInvalid('chunk_count is missing');
return;
}
if (array_key_exists('name', $data) === false) {
$this->setStatusInvalid('name is missing');
return;
}
$numChunks = count($data['chunks']);
$maxChunks = intval($data['chunk_count']);
if ($numChunks >= $maxChunks) {
// merge file and dispatch
$this->setStatusProcessing(0, $maxChunks, 'combining chunks');
$newFile = generateTempFilePath(pathinfo($data['name'], PATHINFO_EXTENSION));
$failed = false;
for ($index = 1; $index <= $maxChunks; $index++) {
if (array_key_exists($index, $data['chunks']) === false) {
$failed = `{$index} chunk is missing`;
} else {
$tempFileName = $data['chunks'][$index];
if ($failed === false) {
$chunkContents = file_get_contents($tempFileName);
if ($chunkContents === false) {
$failed = `{$index} chunk is empty`;
} else {
file_put_contents($newFile, $chunkContents, FILE_APPEND);
}
}
unlink($tempFileName);
$this->setStatusProcessing($index, $maxChunks);
}
}
unset($data['chunks']);
$this->data = json_encode($data);
if ($failed !== false) {
$this->setStatusInvalid($failed);
} else {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $newFile);
finfo_close($finfo);
$data['file'] = $newFile;
$data['size'] = filesize($newFile);
$data['mime_type'] = $mime;
if (
array_key_exists('storage', $data) === true &&
array_key_exists('security_type', $data) === true &&
array_key_exists('mime_type', $data) === true &&
$data['mime_type'] !== ""
) {
$error = Media::verifyStorage($data['mime_type'], $data['security_type'], $data['storage']);
switch ($error) {
case Media::STORAGE_VALID:
break;
case Media::STORAGE_MIME_MISSING:
$this->setStatusInvalid('The file type cannot be determined.');
return;
case Media::STORAGE_NOT_FOUND:
$this->setStatusInvalid('Storage was not found.');
return;
case Media::STORAGE_INVALID_SECURITY:
$this->setStatusInvalid('Storage invalid for security value.');
return;
default:
$this->setStatusInvalid('Storage verification error occurred.');
return;
}
}
$this->data = json_encode($data);
$this->setStatusQueued();
MediaWorkerJob::dispatch($this)->onQueue('media');
}//end if
}//end if
} else {
$this->setStatusQueued();
MediaWorkerJob::dispatch($this)->onQueue('media');
}//end if
}//end if
}
/**
* Return the job owner
*
* @return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* Return the media item
*
* @return BelongsTo
*/
public function media(): BelongsTo
{
return $this->belongsTo(Media::class);
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Models;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Permission extends Model
{
@@ -25,9 +26,9 @@ class Permission extends Model
/**
* Get the User associated with this model
*
* @return BelongsTo
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}

37
app/Models/Shortlink.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use App\Enum\HttpResponseCodes;
use App\Jobs\OptimizeMediaJob;
use App\Traits\Uuids;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\StreamedResponse;
class Shortlink extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'code',
'url',
];
}

View File

@@ -5,9 +5,13 @@ namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Cache;
use Laravel\Sanctum\HasApiTokens;
use OwenIt\Auditing\Contracts\Auditable;
@@ -25,12 +29,12 @@ class User extends Authenticatable implements Auditable
* @var array<int, string>
*/
protected $fillable = [
'username',
'first_name',
'last_name',
'email',
'phone',
'password',
'display_name',
];
/**
@@ -66,18 +70,42 @@ class User extends Authenticatable implements Auditable
'permissions'
];
// public function getPermissionsAttribute() {
// return $this->permissions()->pluck('permission')->toArray();
// }
/**
* The default attributes.
*
* @var string[]
*/
protected $attributes = [
'phone' => '',
];
/**
* Get the list of files of the user
* Boot the model.
*
* @return HasMany
* @return void
*/
public function permissions()
protected static function boot(): void
{
parent::boot();
$clearCache = function ($user) {
Cache::forget(
"user:{$user->id}",
"user:{$user->id}:permissions"
);
};
static::saving($clearCache);
static::deleting($clearCache);
}
/**
* Get the list of permissions of the user
*
* @return Illuminate\Database\Eloquent\Relations\HasMany
*/
public function permissions(): HasMany
{
return $this->hasMany(Permission::class);
}
@@ -87,9 +115,29 @@ class User extends Authenticatable implements Auditable
*
* @return array
*/
public function getPermissionsAttribute()
public function getPermissionsAttribute(): array
{
$cacheKey = "user:{$this->id}:permissions";
return Cache::remember($cacheKey, now()->addDays(28), function () {
return $this->permissions()->pluck('permission')->toArray();
});
}
/**
* Set the permission attribute
*
* @param array $newPermissions The new permissions to set to the user.
* @return void
*/
public function setPermissionsAttribute(array $newPermissions): void
{
$existingPermissions = $this->permissions->pluck('permission')->toArray();
$this->revokePermission(array_diff($this->permissions, $newPermissions));
$this->givePermission(array_diff($newPermissions, $this->permissions));
$cacheKey = "user:{$this->id}:permissions";
Cache::delete($cacheKey);
}
/**
@@ -98,33 +146,31 @@ class User extends Authenticatable implements Auditable
* @param string $permission Permission to test.
* @return boolean
*/
public function hasPermission(string $permission)
public function hasPermission(string $permission): bool
{
return ($this->permissions()->where('permission', $permission)->first() !== null);
return in_array($permission, $this->permissions);
}
/**
* Give permissions to the user
*
* @param string|array $permissions The permission(s) to give.
* @return Collection
* @return Illuminate\Database\Eloquent\Collection
*/
public function givePermission($permissions)
public function givePermission($permissions): Collection
{
if (!is_array($permissions)) {
if (is_array($permissions) === false) {
$permissions = [$permissions];
}
$permissions = collect($permissions)->map(function ($permission) {
$newPermissions = array_map(function ($permission) {
return ['permission' => $permission];
});
}, array_diff($permissions, $this->permissions));
$existingPermissions = $this->permissions()->whereIn('permission', $permissions->pluck('permission'))->get();
$newPermissions = $permissions->reject(function ($permission) use ($existingPermissions) {
return $existingPermissions->contains('permission', $permission['permission']);
});
$cacheKey = "user:{$this->id}:permissions";
Cache::forget($cacheKey);
return $this->permissions()->createMany($newPermissions->toArray());
return $this->permissions()->createMany($newPermissions);
}
@@ -132,14 +178,17 @@ class User extends Authenticatable implements Auditable
* Revoke permissions from the user
*
* @param string|array $permissions The permission(s) to revoke.
* @return int
* @return integer
*/
public function revokePermission($permissions)
public function revokePermission($permissions): int
{
if (!is_array($permissions)) {
if (is_array($permissions) === false) {
$permissions = [$permissions];
}
$cacheKey = "user:{$this->id}:permissions";
Cache::forget($cacheKey);
return $this->permissions()
->whereIn('permission', $permissions)
->delete();
@@ -150,7 +199,7 @@ class User extends Authenticatable implements Auditable
*
* @return HasMany
*/
public function media()
public function media(): HasMany
{
return $this->hasMany(Media::class);
}
@@ -160,9 +209,9 @@ class User extends Authenticatable implements Auditable
*
* @return HasMany
*/
public function posts()
public function articles(): HasMany
{
return $this->hasMany(Post::class);
return $this->hasMany(Article::class);
}
/**
@@ -170,7 +219,7 @@ class User extends Authenticatable implements Auditable
*
* @return HasMany
*/
public function codes()
public function codes(): HasMany
{
return $this->hasMany(UserCode::class);
}
@@ -180,8 +229,18 @@ class User extends Authenticatable implements Auditable
*
* @return HasMany
*/
public function logins()
public function logins(): HasMany
{
return $this->hasMany(UserLogins::class);
}
/**
* Get the events associated with the user.
*
* @return BelongsToMany
*/
public function events(): BelongsToMany
{
return $this->belongsToMany(Event::class, 'event_user', 'user_id', 'event_id');
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserCode extends Model
{
@@ -26,7 +27,7 @@ class UserCode extends Model
*
* @return void
*/
protected static function boot()
protected static function boot(): void
{
parent::boot();
static::creating(function ($model) {
@@ -49,7 +50,7 @@ class UserCode extends Model
*
* @return void
*/
public function regenerate()
public function regenerate(): void
{
while (true) {
$code = random_int(100000, 999999);
@@ -65,7 +66,7 @@ class UserCode extends Model
*
* @return void
*/
public static function clearExpired()
public static function clearExpired(): void
{
UserCode::where('updated_at', '<=', now()->subDays(5))->delete();
}
@@ -73,9 +74,9 @@ class UserCode extends Model
/**
* Get associated user
*
* @return BelongsTo
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}

View File

@@ -5,6 +5,7 @@ namespace App\Models;
use App\Traits\Uuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserLogins extends Model
{
@@ -29,9 +30,9 @@ class UserLogins extends Model
/**
* Get the file user
*
* @return BelongsTo
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}

View File

@@ -2,10 +2,9 @@
namespace App\Providers;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
use Exception;
use Illuminate\Support\Facades\DB;
use PDOException;
use Illuminate\Support\Facades\Storage;
class AppServiceProvider extends ServiceProvider
{
@@ -14,7 +13,7 @@ class AppServiceProvider extends ServiceProvider
*
* @return void
*/
public function register()
public function register(): void
{
//
}
@@ -24,8 +23,31 @@ class AppServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
//
Request::macro('rename', function ($param, $newParam = null) {
if (is_array($param) === false) {
if ($newParam === null) {
return;
}
$param = [$param => $newParam];
}
$paramArray = $this->all();
foreach ($param as $oldParam => $newParam) {
if (isset($paramArray[$oldParam]) === true) {
$paramArray[$newParam] = $paramArray[$oldParam];
unset($paramArray[$oldParam]);
}
}
$this->replace($paramArray);
});
Storage::macro('public', function ($diskName) {
$public = config("filesystems.disks.{$diskName}.public", false);
return $public;
});
}
}

View File

@@ -22,10 +22,8 @@ class AuthServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->registerPolicies();
//
}
}

View File

@@ -12,7 +12,7 @@ class BroadcastServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
Broadcast::routes();

View File

@@ -29,24 +29,9 @@ class EventServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
Queue::after(function (JobProcessed $event) {
// Log::info($event->connectionName);
// Log::info('ID: ' . $event->job->getJobId());
// Log::info('Attempts: ' . $event->job->attempts());
// Log::info('Name: ' . $event->job->getName());
// Log::info('ResolveNAme: ' . $event->job->resolveName());
// Log::info('Queue: ' . $event->job->getQueue());
// Log::info('Body: ' . $event->job->getRawBody());
// Log::info(print_r($event->job->payload(), true));
// $payload = $event->job->payload();
// $data = unserialize($payload['data']['command']);
// Log::info('MAIL: ' . $data->to);
// Log::info('MAIL: ' . get_class($data->mailable));
});
//
}
/**
@@ -54,7 +39,7 @@ class EventServiceProvider extends ServiceProvider
*
* @return boolean
*/
public function shouldDiscoverEvents()
public function shouldDiscoverEvents(): bool
{
return false;
}

View File

@@ -7,6 +7,7 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvi
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
class RouteServiceProvider extends ServiceProvider
{
@@ -25,9 +26,32 @@ class RouteServiceProvider extends ServiceProvider
*
* @return void
*/
public function boot()
public function boot(): void
{
$this->configureRateLimiting();
// RateLimiter::for('api', function (Request $request) {
// return Limit::perMinute(60)->by($request->user()?->id !== null ?: $request->ip());
// });
$rateLimitEnabled = true;
/** @var \App\Models\User */
$user = auth()->user();
if (app()->environment('testing') === true) {
$rateLimitEnabled = false;
} elseif ($user !== null && $user->hasPermission('admin/ratelimit') === true) {
// Admin users with the "admin/ratelimit" permission are not rate limited
$rateLimitEnabled = false;
}
if ($rateLimitEnabled === true) {
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(800)->by(isset($request->user()->id) === true ?: $request->ip());
});
} else {
RateLimiter::for('api', function () {
return Limit::none();
});
}
$this->routes(function () {
Route::middleware('api')
@@ -37,37 +61,30 @@ class RouteServiceProvider extends ServiceProvider
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
// RateLimiter::for('api', function (Request $request) {
// return Limit::perMinute(60)->by($request->user()?->id !== null ?: $request->ip());
// });
Route::macro('apiAddendumResource', function ($addendum, $uri, $controller) {
$singularUri = Str::singular($uri);
$signularAddendum = Str::singular((strtolower($addendum)));
$pluralAddendum = Str::plural($signularAddendum);
$rateLimitEnabled = true;
$user = auth()->user();
Route::get("{$uri}/{{$singularUri}}/{$pluralAddendum}", [$controller, "{$signularAddendum}Index"])
->name("{$singularUri}.{$signularAddendum}.index");
if (app()->environment('testing')) {
$rateLimitEnabled = false;
} elseif ($user !== null && $user->hasPermission('admin/ratelimit') === true) {
// Admin users with the "admin/ratelimit" permission are not rate limited
$rateLimitEnabled = false;
}
Route::post("{$uri}/{{$singularUri}}/{$pluralAddendum}", [$controller, "{$signularAddendum}Store"])
->name("{$singularUri}.{$signularAddendum}.store");
if ($rateLimitEnabled === true) {
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(180)->by($request->user()?->id ?: $request->ip());
Route::match(
['put', 'patch'],
"{$uri}/{{$singularUri}}/{$pluralAddendum}",
[$controller, "{$signularAddendum}Update"]
)
->name("{$singularUri}.{$signularAddendum}.update");
Route::delete(
"{$uri}/{{$singularUri}}/{$pluralAddendum}/{medium}",
[$controller,"{$signularAddendum}Delete"]
)
->name("{$singularUri}.{$signularAddendum}.destroy");
});
} else {
RateLimiter::for('api', function () {
return Limit::none();
});
}
}
}

View File

@@ -24,7 +24,7 @@ class Recaptcha implements Rule
* @param mixed $value Attribute value.
* @return boolean
*/
public function passes(mixed $attribute, mixed $value)
public function passes(mixed $attribute, mixed $value): bool
{
$endpoint = config('services.google_recaptcha');
@@ -45,7 +45,7 @@ class Recaptcha implements Rule
*
* @return string
*/
public function message()
public function message(): string
{
return 'Captcha failed. Refresh the page and try again';
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Rules;
use App\Models\Media;
use Illuminate\Contracts\Validation\Rule;
class UniqueFileName implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param mixed $attribute Attribute name.
* @param mixed $value Attribute value.
* @return boolean
*/
public function passes(mixed $attribute, mixed $value): bool
{
return (Media::fileExists($value) === false);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message(): string
{
return 'The file name already exists.';
}
}

Some files were not shown because too many files have changed in this diff Show More