Open danielfowler opened 5 years ago
is that validate line right? no quotes around it? I would expect all those :
on one line would cause a problem.
Profiler is not built on Workshop, it is completely separate.
I added quotation marks, I'll keep you updated as I see new assets come in.
Asset validation still doesn't work.
It works on initial user registration using {{ user:register_form files="true" }}
. But it fails when trying to update the picture with {{ profiler:edit_form files="true" }}
.
In my users.yaml
.
profile_picture:
container: users
restrict: true
max_files: 1
type: assets
display: Profilbild
folder: /
validate: required|mimes:jpg,jpeg,png|max:3000
I tried validate: "required|mimes:jpg,jpeg,png|max:3000"
(with quotes) as well. This didn't work either.
I'm on Statamic v2.11.19 and Profiler v2.1.4.
Actually it looks like the fix from https://github.com/edalzell/statamic-profiler/commit/d15d94026efabc603c9800de89eaf5b4005ecb1c is not present in v2.1.4.
It looks like the fix was still present in Tag: 2.1.2
. It's missing from Tag: 2.1.3
upwards.
I've noticed that use Statamic\CP\Publish\ValidationBuilder
in ProfilerController.php
is missing from Tag: 2.1.3
upwards as well. Not sure if that's another hiccup or meant to be. I'd be carefully checking everything.
I've encountered another bug #24 which is possibly related to this as well.
This only occurs when you set it required but don't include a file
@aerni question for you, IF they already have a photo attached (because it works during user registration) and they only want to change, say, their last name, and NOT their photo, then how do you want it to work?
Right now I assume that if there is no photo in the request, then they do not want to update it so I remove the validation rules. This seems reasonable to me, does this not work for you?
If not, can you please how you'd like it to work?
Yes, that's exactly how I'd expect it to work. I think this goes along with what I was trying to explain in issue #24.
Let me explain a bit more. All the fields from the user.yaml
are present in the user registration from. The validation should work accordingly. All the required fields have to be filled.
Now when the user edits his profile, I ONLY want to validate the fields present in the user edit form. I DON'T want to get an error of ANY required field that is NOT present in the form.
I have a form to edit the user account. This form only includes fields to edit username
and password
. I can successfully send the form and don't have to include all the other required fields from the user.yaml
, as those fields were already published during registration. This is the expected behavior.
Now I have another form to edit the user profile with his profile_picture
, name
, email
etc. This is where the validation for the privacy_terms
checkbox fails. But it ONLY fails when the profile_picture
validation fails. It DOESN'T fail when any other field is successfully changed or the validation of any other field fails.
I hope this makes sense. I can also give you access to the project repo if that helps you track it down.
This is my user.yaml
:
sections:
main:
display: Main
fields:
profile_picture:
container: users
restrict: true
max_files: 1
type: assets
display: Profilbild
folder: /
validate: required|image|mimes:jpg,jpeg,png|max:3000
username:
type: text
display: Benutzername
validate: required|string|alpha_dash|max:30
width: 33
name:
type: text
display: Name
validate: 'required|string|max:255|regex:/^[\p{Latin}\s\-]+$/u'
width: 33
email:
type: text
display: E-Mail
validate: required|string|email|max:255
width: 33
zip:
type: text
display: PLZ
validate: required|string|integer|digits:4
width: 33
city:
type: text
display: Ort
validate: 'required|string|max:255|regex:/^[\p{Latin}\s\-\d]+$/u'
width: 33
cantons:
max_items: 1
type: taxonomy
display: Kanton
taxonomy: cantons
mode: tags
create: false
validate: required|string|alpha_dash
width: 33
services:
type: taxonomy
display: Services
taxonomy: services
mode: tags
create: false
validate: required|array
width: 50
radius:
max_items: 1
type: taxonomy
display: Umkreis
taxonomy: radius
mode: tags
create: false
validate: required|string|alpha_dash
width: 50
privacy_terms:
type: checkboxes
options:
accepted: Akzeptiert
display: Datenschutz und Bedingungen
validate: 'required|string|regex:/^accepted$/'
roles:
type: user_roles
taxonomies: false
hide: true
title: User
Now when the user edits his profile, I ONLY want to validate the fields present in the user edit form. I DON'T want to get an error of ANY required field that is NOT present in the form.
Ya that's not going to happen, use hidden fields for that. Too hard to figure out when someone wants to REMOVE some data vs keep if the data isn't there in both cases.
also for your file checking it should be ext:jpg...
not mime
, that doesn't seem to work in Statamic.
True. I didn‘t consider the use case of a user wanting to delete some data.
I experimented with the file check using both ext
and mime
. What I found is that the assets fieldtype in the CP can only validate with ext
, and the registration form on the frontend only with mime
.
The CP doesn‘t work with mime
because Statamic doesn‘t actually validate the picture but the array. There‘s a thread on the Statamic forum about this.
I didn‘t find why the file input on the fronend doesn‘t work with ext
though.
it works for me w/ ext
in my testing. Regardless, that's not a Profiler
issue.
What works with ext
for you? Registration or Profiler or both?
For me, ext
doesn't work on registration, which is why I switched to this validation which works great using the registration form: validate: required|image|mimes:jpg,jpeg,png|max:3000
. It only fails in the CP, because the assets fieldtype doesn't like mimes
. But in my case, I just ignore this, because validating the registration is more important than CP input.
When editing the user with Profiler, the validation of mimes
fails. Profiler works fine with ext
. So it's exactly the opposite of the registration form. Also, Profiler doesn't like the max
validation.
In short, this validation works fine on registration: validate: required|image|mimes:jpg,jpeg,png|max:3000
This validation works with Profiler: validate: required|ext:jpg,jpeg,png
Let me know if you'd like access to my repo for a real test case.
I call the built in validators and have nothing to with the actual validation. No clue why one works on registration vs profiler.
I wonder if the form tags do something special?
I'll leave this open and take a look.
Did you have a chance to look at this yet?
It's a really odd issue. Why would Profiler's asset validation fail different to the registration form …
Especially weird is the behaviour I explained earlier:
I have some checkboxes
and radio buttons
on the frontend which should validate according to the settings in user.yaml
. The fields are services
, radius
and privacy_terms
. They validate as expected in the registration form. But NOT in Profiler's edit form.
Profiler DOESN'T throw any validation errors for those fields. BUT it throws validation errors for those fields WHEN the assets validation fails. And ONLY when the assets validation fails.
All the other validations work as expected.
That's why I suspect something funky with Profiler's asset validation. But maybe that's a Statamic core issue? No idea …
This is my user.yaml
:
sections:
main:
display: Main
fields:
profile_picture:
container: users
restrict: true
max_files: 1
type: assets
display: Profilbild
folder: /
validate: required|image|mimes:jpg,jpeg,png|max:3000
username:
type: text
display: Benutzername
validate: required|string|alpha_dash|max:30
width: 33
name:
type: text
display: Name
validate: 'required|string|max:255|regex:/^[\p{Latin}\s\-]+$/u'
width: 33
email:
type: text
display: E-Mail
validate: required|string|email|max:255
width: 33
zip:
type: text
display: PLZ
validate: required|string|integer|digits:4
width: 33
city:
type: text
display: Ort
validate: 'required|string|max:255|regex:/^[\p{Latin}\s\-\d]+$/u'
width: 33
cantons:
max_items: 1
type: taxonomy
display: Kanton
taxonomy: cantons
mode: tags
create: false
validate: required|string|alpha_dash
width: 33
services:
type: taxonomy
display: Services
taxonomy: services
mode: tags
create: false
validate: required|array
width: 50
radius:
max_items: 1
type: taxonomy
display: Umkreis
taxonomy: radius
mode: tags
create: false
validate: required|string|alpha_dash
width: 50
privacy_terms:
type: checkboxes
options:
accepted: Akzeptiert
display: Datenschutz und Bedingungen
validate: 'required|string|regex:/^accepted$/'
roles:
type: user_roles
taxonomies: false
hide: true
title: User
Can I see your form as well @aerni? I wouldn't expect that privacy_terms
validation to work as it's an array of data and you're checking it for string
etc. Same w/ radius
actually, it's an array and you're checking for string
And your user registration template please @aerni.
Can I see your form as well @aerni? I wouldn't expect that
privacy_terms
validation to work as it's an array of data and you're checking it forstring
etc. Same w/radius
actually, it's an array and you're checking forstring
Yeah I know, it's odd but it works. At least on registration. Because it's saved as a string when there's only one option available.
Please find all the data below. I'm happy to give you access to the project, as it may be easier to track it down. Or do a remote pair to show you the error. It's easier to grasp when you see it in action than reading through this. At least for me. 😅
In my countless tests with the profile_picture
validation, I found that the following validation works with the {{ user:register_form }}
. BUT NOT with the {{ profiler:edit_form }}
nor in the CP
:
validate: required|image|mimes:jpg,jpeg,png|max:3000
This validation works with the {{ profiler:edit_form }}
and in the CP
. BUT NOT with the {{ user:register_form }}
:
validate: required|ext:jpg,jpeg,png
It looks like the {{ profiler:edit_form }}
and the CP
behave the same way and expect the same validation.
Could it be that the {{ user:register_form }}
uses a different validator than the CP
uses? And that {{ profiler:edit_form }}
is making use of the CP
validator and thus not validating the same as the {{ user:register_form }}
?
This form works perfectly as expected, respecting all the validation rules set in the user.yaml
.
{{ user:register_form redirect="/success?register=true" files="true" attr="x-data:{ submitting: false }|@submit:submitting = true" }}
<div>
{{ if errors }}
<div class="p-4 mb-6 rounded-md bg-red-100">
<p class="rfs-text-sm font-medium text-red-600">
{{ errors }}
{{ value }}<br>
{{ /errors }}
</p>
</div>
{{ /if }}
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Account</h3>
<p class="mt-1 rfs-text-sm leading-5 text-gray-500">Lege Benutzername und Passwort fest.</p>
</div>
<div class="mt-6 grid grid-cols-1 row-gap-6 col-gap-4 sm:grid-cols-6">
<div class="sm:col-span-6">
<label for="username" class="block rfs-text-sm font-medium leading-5 text-gray-700">Benutzername</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="username" type="text" name="username" value="{{ old:username }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-3">
<label for="password" class="block rfs-text-sm font-medium leading-5 text-gray-700">Passwort</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="password" type="password" name="password" value="{{ old:password }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-3">
<label for="password_confirmation" class="block rfs-text-sm font-medium leading-5 text-gray-700">Passwort wiederholen</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="password_confirmation" type="password" name="password_confirmation" value="{{ old:password_confirmation }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
</div>
</div>
<div class="mt-8 border-t border-gray-200 pt-8">
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Persönliche Informationen</h3>
<p class="mt-1 rfs-text-sm leading-5 text-gray-500">Diese Informationen werden öffentlich in deinem Profil angezeigt.</p>
</div>
<div class="mt-6 grid grid-cols-1 row-gap-6 col-gap-4 sm:grid-cols-6">
<div x-data="profilePicture()" class="sm:col-span-6">
<label for="profile_picture" class="rfs-text-sm leading-5 font-medium text-gray-700 select-none">Profilbild</label>
<div class="mt-2 flex items-center">
<div @click="$refs.input.click()" class="h-12 w-12 flex-shrink-0 rounded-full overflow-hidden bg-gray-200 cursor-pointer">
<div class="aspect-ratio-square relative">
<div class="absolute inset-0 w-full h-full flex justify-center items-center">
{{ theme:output src="svg/user-solid.svg" }}
</div>
{{ if profile_picture }}
{{ asset:profile_picture }}
{{ if is_image }}
<img
x-ref="preview"
src="{{ glide:url preset="user_thumbnail" }}"
alt="{{ name }}"
class="absolute inset-0 w-full h-full object-cover"
/>
{{ /if }}
{{ /asset:profile_picture }}
{{ else }}
<img
x-ref="preview"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
class="absolute inset-0 w-full h-full object-cover"
/>
{{ /if }}
</div>
</div>
<span class="ml-5 rounded-md shadow-sm">
<button @click="$refs.input.click()" type="button" class="py-2 px-3 border border-gray-300 rounded-md text-sm leading-4 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition duration-150 ease-in-out">
Bild ändern
<span class="rfs-text-sm leading-5 text-gray-500">/ JPG, PNG bis 3MB</span>
</button>
</span>
<input x-ref="input" @change="updatePreview()" type="file" id="profile_picture" name="profile_picture" accept=".jpg, .jpeg, .png" class="w-0 opacity-0" />
</div>
</div>
<script>
function profilePicture() {
return {
fileTypes: [
'image/jpg',
'image/jpeg',
'image/png',
],
validFileType(file) {
return this.fileTypes.includes(file.type);
},
updatePreview() {
if (this.$refs.input.files.length === 0) return;
if (this.validFileType(this.$refs.input.files[0])) {
this.$refs.preview.src = URL.createObjectURL(this.$refs.input.files[0]);
}
},
};
}
</script>
<div class="sm:col-span-3">
<label for="name" class="block rfs-text-sm font-medium leading-5 text-gray-700">Name</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="name" type="text" name="name" value="{{ old:name }}" class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-3">
<label for="email" class="block rfs-text-sm font-medium leading-5 text-gray-700">E-Mail</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="email" type="email" name="email" value="{{ old:email }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="zip" class="block rfs-text-sm font-medium leading-5 text-gray-700">PLZ</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="zip" type="text" name="zip" value="{{ old:zip }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="city" class="block rfs-text-sm font-medium leading-5 text-gray-700">Ort</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="city" type="text" name="city" value="{{ old:city }}" class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="canton" class="block rfs-text-sm font-medium leading-5 text-gray-700">Kanton</label>
<div class="mt-1 rounded-md shadow-sm">
<select id="canton" name="cantons" class="form-select block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5">
<option selected disabled>Kanton wählen …</option>
{{ relate:general:cantons_listing_order }}
<option value="{{ slug }}" {{ if old:cantons === slug }}selected{{ /if }}>{{ title }}</option>
{{ /relate:general:cantons_listing_order }}
</select>
</div>
</div>
</div>
</div>
<div class="mt-8 border-t border-gray-200 pt-8">
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Services & Umkreis</h3>
<p class="mt-1 rfs-text-sm leading-5 text-gray-500">Wähle deine Services und den Umkreis, in dem du diese anbieten möchtest.</p>
</div>
<div class="mt-6">
<fieldset>
<legend class="rfs-text-base font-medium text-gray-900">Services</legend>
<div class="flex flex-wrap">
{{ relate:general:services_listing_order }}
<div class="mt-4 mr-6">
<div class="relative flex items-start">
<div class="absolute flex items-center h-5">
<input id="{{ slug }}" type="checkbox" name="services[]" value="{{ slug }}" {{ if (old:services | in_array:slug) }}checked{{ /if }} class="form-checkbox h-4 w-4 text-yellow-300 transition duration-150 ease-in-out" />
</div>
<div class="pl-7 rfs-text-sm leading-5">
<label for="{{ slug }}" class="font-medium text-gray-700">{{ title }}</label>
</div>
</div>
</div>
{{ /relate:general:services_listing_order }}
</div>
</fieldset>
<fieldset class="mt-6">
<legend class="rfs-text-base font-medium text-gray-900">Umkreis</legend>
<div class="flex flex-wrap">
{{ relate:general:radius_listing_order }}
<div class="mt-4 mr-6 flex items-center">
<input id="{{ slug }}" type="radio" name="radius" value="{{ slug }}" {{ if old:radius === slug }}checked{{ /if }} class="form-radio h-4 w-4 text-yellow-300 transition duration-150 ease-in-out" />
<label for="{{ slug }}" class="ml-3">
<span class="block rfs-text-sm leading-5 font-medium text-gray-700">{{ title }}</span>
</label>
</div>
{{ /relate:general:radius_listing_order }}
</div>
</fieldset>
</div>
</div>
<div class="mt-8 border-t border-gray-200 pt-8">
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Datenschutzerklärung</h3>
</div>
<div class="mt-6">
<div class="relative flex items-start">
<div class="absolute flex items-center h-5">
<input id="privacy_terms" type="checkbox" name="privacy_terms" value="accepted" {{ if old:privacy_terms }}checked{{ /if }} class="form-checkbox h-4 w-4 text-yellow-300 transition duration-150 ease-in-out" />
</div>
<div class="pl-7 rfs-text-sm leading-5">
<label for="privacy_terms" class="font-medium text-gray-700">Ich akzeptiere die <a href="https://www.iubenda.com/privacy-policy/82360217" target="_blank" class="text-yellow-300">Datenschutzerklärung</a> und bestätige, dass ich 18+ Jahre alt bin.</label>
</div>
</div>
</div>
</div>
<div class="mt-8 border-t border-gray-200 pt-5">
<div class="flex justify-end">
<span class="inline-flex rounded-md shadow-sm">
<button :disabled="submitting" :class="{ 'bg-yellow-400 cursor-not-allowed': submitting }" type="submit" class="inline-flex justify-center items-center py-2 px-4 border border-transparent rfs-text-sm leading-5 font-medium rounded-md text-white bg-yellow-300 hover:bg-yellow-400 focus:outline-none focus:border-yellow-400 focus:shadow-outline-yellow active:bg-yellow-400 transition duration-150 ease-in-out">
<i x-show="submitting" x-cloak class="fad fa-spinner-third fa-spin rfs-text-lg mr-2"></i>
Registrieren
</button>
</span>
</div>
</div>
{{ /user:register_form }}
This is the data that's saved when a user registeres through the registration form.
name: Michael
email: hello@michaelaerni.ch
zip: '3174'
city: Thörishaus
cantons: bern
services:
- einkaufen
- gespraech
radius: 5-km
privacy_terms: accepted
profile_picture: /assets/users/michael_ciy.jpg
roles:
- 1c1159d7-0ea7-4f3d-bbf4-42e611c81552
password_hash: $2y$10$.0WT0oHdvELjBFLGwqt2y.wdscDxyzG8NJ.yirSGtqiq3/XRc0kli
id: af586d8f-0dfc-40de-a53e-68468203aeb8
This form is different to the registration form, as it doesn't contain the username
and password
. It still validates though, because username
and password
are already set in the user's yaml file. In the same matter, I could remove the privacy_terms
checkbox or any other required fields that already have a value set in the user's yaml.
Saving the user works perfectly without having this checkbox or any other required elements present in the form. BUT as soon as the profile_picture
validation fails, it ALSO throws a validation error for privacy_terms
or any other expected form value.
This can be recreated by deleting some required data like radius
from the user's yaml and editing the user through this form. The validation WILL pass and not throw an error. Which it shouldn't. However, it WILL throw the error when the profile_picture
validation fails. BUT ONLY then. To test this, you have to remove the required
attributes on the HTML form elements.
Likewise you can delete a required element from the form altogether. Like it did with username
and password
. Try deleting the radius
form element in the HTML. Validation will still pass, as long as the data is already set in the user's yaml. But it WILL fail, as soon as the profile_picture
validation fails.
It will ALSO fail when the profile_picture
validation passes. Remove the validation from the profile_picture
and update the picture through the form. Now all the required data that's missing a HTML form element is throwing an error. It seems like the validation is only triggered when the profile_picture
changes. It is NOT triggered, however, when any other user data is changed. ONLY when the profile_picture
either changes or the validation fails. Try to just update another form value without changing the profile_picture
. No error will be thrown.
{{ profiler:edit_form redirect="/profile" files="true" attr="x-data:{ submitting: false }|@submit:submitting = true" }}
<div>
{{ if errors }}
<div class="p-4 mb-6 rounded-md bg-red-100">
<p class="rfs-text-sm font-medium text-red-600">
{{ errors }}
{{ value }}<br>
{{ /errors }}
</p>
</div>
{{ /if }}
{{ if success }}
<div class="p-4 mb-6 rounded-md bg-green-100">
<p class="rfs-text-sm font-medium text-green-600">
Dein Profil wurde erfolgreich aktualisiert.
</p>
</div>
{{ /if }}
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Persönliche Informationen</h3>
<p class="mt-1 rfs-text-sm leading-5 text-gray-500">Diese Informationen werden öffentlich in deinem Profil angezeigt.</p>
</div>
<div class="mt-6 grid grid-cols-1 row-gap-6 col-gap-4 sm:grid-cols-6">
<div x-data="profilePicture()" class="sm:col-span-6">
<label for="profile_picture" class="rfs-text-sm leading-5 font-medium text-gray-700 select-none">Profilbild</label>
<div class="mt-2 flex items-center">
<div @click="$refs.input.click()" class="h-12 w-12 flex-shrink-0 rounded-full overflow-hidden bg-gray-200 cursor-pointer">
<div class="aspect-ratio-square relative">
<div class="absolute inset-0 w-full h-full flex justify-center items-center">
{{ theme:output src="svg/user-solid.svg" }}
</div>
{{ if profile_picture }}
{{ asset:profile_picture }}
{{ if is_image }}
<img
x-ref="preview"
src="{{ glide:url preset="user_thumbnail" }}"
alt="{{ name }}"
class="absolute inset-0 w-full h-full object-cover"
/>
{{ /if }}
{{ /asset:profile_picture }}
{{ else }}
<img
x-ref="preview"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
class="absolute inset-0 w-full h-full object-cover"
/>
{{ /if }}
</div>
</div>
<span class="ml-5 rounded-md shadow-sm">
<button @click="$refs.input.click()" type="button" class="py-2 px-3 border border-gray-300 rounded-md text-sm leading-4 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800 transition duration-150 ease-in-out">
Bild ändern
<span class="rfs-text-sm leading-5 text-gray-500">/ JPG, PNG bis 3MB</span>
</button>
</span>
<input x-ref="input" @change="updatePreview()" type="file" id="profile_picture" name="profile_picture" accept=".jpg, .jpeg, .png" class="w-0 opacity-0" />
</div>
</div>
<script>
function profilePicture() {
return {
fileTypes: ['image/jpg', 'image/jpeg', 'image/png'],
validFileType(file) {
return this.fileTypes.includes(file.type);
},
updatePreview() {
if (this.$refs.input.files.length === 0) return;
if (this.validFileType(this.$refs.input.files[0])) {
this.$refs.preview.src = URL.createObjectURL(this.$refs.input.files[0]);
}
},
};
}
</script>
<div class="sm:col-span-3">
<label for="name" class="block rfs-text-sm font-medium leading-5 text-gray-700">Name</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="name" type="text" name="name" value="{{ old:name or name }}" placeholder="{{ name }}" required class="form-input block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-3">
<label for="email" class="block rfs-text-sm font-medium leading-5 text-gray-700">E-Mail</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="email" type="email" name="email" value="{{ old:email or email }}" placeholder="{{ email }}" required class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="zip" class="block rfs-text-sm font-medium leading-5 text-gray-700">PLZ</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="zip" type="text" name="zip" value="{{ old:zip or zip }}" placeholder="{{ zip }}" required class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="city" class="block rfs-text-sm font-medium leading-5 text-gray-700">Ort</label>
<div class="mt-1 rounded-md shadow-sm">
<input id="city" type="text" name="city" value="{{ old:city or city }}" placeholder="{{ city }}" required class="form-input block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5" />
</div>
</div>
<div class="sm:col-span-2">
<label for="canton" class="block rfs-text-sm font-medium leading-5 text-gray-700">Kanton</label>
<div class="mt-1 rounded-md shadow-sm">
<select id="canton" name="cantons" required class="form-select block w-full transition duration-150 ease-in-out sm:rfs-text-sm sm:leading-5">
{{ relate:general:cantons_listing_order }}
<option {{ if cantons === slug }}selected{{ /if }} value="{{ slug }}">{{ title }}</option>
{{ /relate:general:cantons_listing_order }}
</select>
</div>
</div>
</div>
</div>
<div class="mt-8 border-t border-gray-200 pt-8">
<div>
<h3 class="rfs-text-lg leading-6 font-medium text-gray-900">Services & Umkreis</h3>
<p class="mt-1 rfs-text-sm leading-5 text-gray-500">Wähle deine Services und den Umkreis, in dem du diese anbieten möchtest.</p>
</div>
<div class="mt-6">
<fieldset>
<legend class="rfs-text-base font-medium text-gray-900">Services</legend>
<div class="flex flex-wrap">
{{ relate:general:services_listing_order }}
<div class="mt-4 mr-6">
<div class="relative flex items-start">
<div class="absolute flex items-center h-5">
<input id="{{ slug }}" type="checkbox" name="services[]" value="{{ slug }}" {{ if (services | in_array:slug) }}checked{{ /if }} class="form-checkbox h-4 w-4 text-yellow-300 transition duration-150 ease-in-out" />
</div>
<div class="pl-7 rfs-text-sm leading-5">
<label for="{{ slug }}" class="font-medium text-gray-700">{{ title }}</label>
</div>
</div>
</div>
{{ /relate:general:services_listing_order }}
</div>
</fieldset>
<fieldset class="mt-6">
<legend class="rfs-text-base font-medium text-gray-900">Umkreis</legend>
<div class="flex flex-wrap">
{{ relate:general:radius_listing_order }}
<div class="mt-4 mr-6 flex items-center">
<input id="{{ slug }}" type="radio" name="radius" value="{{ slug }}" {{ if radius === slug }}checked{{ /if }} required class="form-radio h-4 w-4 text-yellow-300 transition duration-150 ease-in-out" />
<label for="{{ slug }}" class="ml-3">
<span class="block rfs-text-sm leading-5 font-medium text-gray-700">{{ title }}</span>
</label>
</div>
{{ /relate:general:radius_listing_order }}
</div>
</fieldset>
</div>
</div>
{{# This field is only in here, because validation fails when it's not. Weird thing is, that validation ONLY fails, if you change the profile picture. #}}
<input id="privacy_terms" type="checkbox" name="privacy_terms" value="accepted" required checked class="hidden" />
<div class="mt-8 border-t border-gray-200 pt-5">
<div class="flex justify-end">
<span class="inline-flex rounded-md shadow-sm">
<button :disabled="submitting" :class="{ 'bg-yellow-400 cursor-not-allowed': submitting }" type="submit" class="inline-flex justify-center items-center py-2 px-4 border border-transparent rfs-text-sm leading-5 font-medium rounded-md text-white bg-yellow-300 hover:bg-yellow-400 focus:outline-none focus:border-yellow-400 focus:shadow-outline-yellow active:bg-yellow-400 transition duration-150 ease-in-out">
<i x-show="submitting" x-cloak class="fad fa-spinner-third fa-spin rfs-text-lg mr-2"></i>
Speichern
</button>
</span>
</div>
</div>
{{ /profiler:edit_form }}
I hope this all makes sense and that it helps you track it down. Let me know if you need anything more.
I have a
validate
line in myuser.yaml
to restrict file size to 1MB and file type to JPG, but I am getting all kinds of files uploaded (even PDF and DOCX) of massive sizes (some 8MB).This might be a Workshop bug, since I know that Profiler is built upon Workshop, but I think it's worth noting.