1+ import logging
12from itertools import chain
23
34from django import forms
45from django .core .exceptions import ValidationError
6+ from django .http import HttpRequest
57from django .utils .encoding import force_str
68from django .utils .translation import gettext_lazy as _
79from phonenumber_field .formfields import PhoneNumberField
1618 guess_country ,
1719)
1820from eventyay .base .i18n import get_babel_locale , language
21+ from eventyay .base .models import Event
1922from eventyay .base .validators import EmailBanlistValidator
2023from eventyay .presale .signals import contact_form_fields
2124
25+ logger = logging .getLogger (__name__ )
26+
2227
2328class ContactForm (forms .Form ):
2429 required_css_class = 'required'
@@ -27,51 +32,78 @@ class ContactForm(forms.Form):
2732 validators = [EmailBanlistValidator ()],
2833 widget = forms .EmailInput (attrs = {'autocomplete' : 'section-contact email' }),
2934 )
35+ # This field will be dropped depending on `include_wikimedia_username` event setting.
36+ wikimedia_username = forms .CharField (
37+ label = _ ('Wikimedia Username' ),
38+ required = False ,
39+ disabled = True ,
40+ widget = forms .TextInput (attrs = {'readonly' : 'readonly' }),
41+ )
42+ phone = PhoneNumberField (
43+ label = _ ('Phone number' ),
44+ required = False ,
45+ help_text = '' ,
46+ widget = WrappedPhoneNumberPrefixWidget (),
47+ )
3048
31- def __init__ (self , * args , ** kwargs ):
32- self .event = kwargs . pop ( ' event' )
33- self .request = kwargs . pop ( ' request' )
34- self .all_optional = kwargs . pop ( ' all_optional' , False )
49+ def __init__ (self , * args , event : Event , request : HttpRequest , all_optional = False , ** kwargs ):
50+ self .event = event
51+ self .request = request
52+ self .all_optional = all_optional
3553 super ().__init__ (* args , ** kwargs )
3654
37- if self . event .settings .order_email_asked_twice :
55+ if event .settings .order_email_asked_twice :
3856 self .fields ['email_repeat' ] = forms .EmailField (
3957 label = _ ('E-mail address (repeated)' ),
4058 help_text = _ ('Please enter the same email address again to make sure you typed it correctly.' ),
4159 )
4260
43- if self .event .settings .order_phone_asked :
61+ if event .settings .order_phone_asked :
62+ self .fields ['phone' ].required = True
63+ self .fields ['phone' ].help_text = event .settings .checkout_phone_helptext
4464 with language (get_babel_locale ()):
45- default_country = guess_country (self . event )
65+ default_country = guess_country (event )
4666 default_prefix = None
67+ phone_initial = ''
4768 for prefix , values in _COUNTRY_CODE_TO_REGION_CODE .items ():
4869 if str (default_country ) in values :
4970 default_prefix = prefix
50- try :
51- initial = self .initial .pop ('phone' , None )
52- initial = PhoneNumber ().from_string (initial ) if initial else '+{}.' .format (default_prefix )
53- except NumberParseException :
54- initial = None
55- self .fields ['phone' ] = PhoneNumberField (
56- label = _ ('Phone number' ),
57- required = self .event .settings .order_phone_required ,
58- help_text = self .event .settings .checkout_phone_helptext ,
59- # We now exploit an implementation detail in PhoneNumberPrefixWidget to allow us to pass just
60- # a country code but no number as an initial value. It's a bit hacky, but should be stable for
61- # the future.
62- initial = initial ,
63- widget = WrappedPhoneNumberPrefixWidget (),
64- )
71+ break
72+ if passed_initial := self .initial .get ('phone' ):
73+ try :
74+ phone_number = PhoneNumber ().from_string (passed_initial )
75+ phone_initial = str (phone_number )
76+ except NumberParseException :
77+ pass
78+ elif default_prefix :
79+ phone_initial = f'+{ default_prefix } .'
80+ self .fields ['phone' ].initial = phone_initial
81+ else :
82+ del self .fields ['phone' ]
83+
84+ # Wikimedia username field visibility based on event setting
85+ if not event .settings .include_wikimedia_username :
86+ logger .debug ('Dropping wikimedia_username field because `include_wikimedia_username` setting is False.' )
87+ self .fields .pop ('wikimedia_username' , None )
88+ else :
89+ # Configure read-only Wikimedia username initial without redefining the field
90+ wm_initial = (
91+ self .initial .get ('wikimedia_username' )
92+ or getattr (getattr (request , 'user' , None ), 'wikimedia_username' , None )
93+ or request .session .get ('wikimedia_username' )
94+ )
95+ if wm_initial :
96+ self .fields ['wikimedia_username' ].initial = wm_initial
6597
66- if not self . request .session .get ('iframe_session' , False ):
98+ if not request .session .get ('iframe_session' , False ):
6799 # There is a browser quirk in Chrome that leads to incorrect initial scrolling in iframes if there
68100 # is an autofocus field. Who would have thought… See e.g. here:
69101 # https://floatboxjs.com/forum/topic.php?post=8440&usebb_sid=2e116486a9ec6b7070e045aea8cded5b#post8440
70102 self .fields ['email' ].widget .attrs ['autofocus' ] = 'autofocus'
71- self .fields ['email' ].help_text = self . event .settings .checkout_email_helptext
103+ self .fields ['email' ].help_text = event .settings .checkout_email_helptext
72104 self .fields ['email' ].widget .attrs ['placeholder' ] = 'Valid Email address'
73105
74- responses = contact_form_fields .send (self . event , request = self . request )
106+ responses = contact_form_fields .send (event , request = request )
75107 for r , response in responses :
76108 for key , value in response .items ():
77109 # We need to be this explicit, since OrderedDict.update does not retain ordering
0 commit comments