in kitsune/questions/views.py [0:0]
def aaq(request, product_slug=None, step=1, is_loginless=False):
"""Ask a new question."""
# After the migration to a DB based AAQ, we need to account for
# product slugs that were not present in the questions config.
should_redirect = True
match product_slug:
case "desktop":
product_slug = "firefox"
case "focus":
product_slug = "focus-firefox"
case _:
should_redirect = False
if should_redirect:
return HttpResponsePermanentRedirect(reverse("questions.aaq_step2", args=[product_slug]))
template = "questions/new_question.html"
# Check if the user is using a mobile device,
# render step 2 if they are
product_slug = product_slug or request.GET.get("product")
if product_slug is None:
change_product = False
if request.GET.get("q") == "change_product":
change_product = True
is_mobile_device = get_user_agent(request).is_mobile
if is_mobile_device and not change_product:
user_agent = request.META.get("HTTP_USER_AGENT", "")
if product_slug := get_mobile_product_from_ua(user_agent):
# redirect needed for InAAQMiddleware
step_2 = reverse("questions.aaq_step2", args=[product_slug])
return HttpResponseRedirect(step_2)
# Return 404 if the products does not have an AAQ form or if it is archived
product = None
products_with_aaqs = Product.active.filter(aaq_configs__is_active=True).distinct()
if product_slug:
try:
product = Product.active.get(slug=product_slug)
except Product.DoesNotExist:
raise Http404
else:
if product not in products_with_aaqs:
raise Http404
context = {
"products": products_with_aaqs,
"current_product": product,
"current_step": step,
"host": Site.objects.get_current().domain,
"is_loginless": is_loginless,
"ga_content_group": f"aaq-step-{step}",
}
# If the selected product doesn't exist in DB, render a 404
if step > 1:
set_aaq_context(request, product)
has_public_forum = product.questions_enabled(locale=request.LANGUAGE_CODE)
context["has_ticketing_support"] = product.has_ticketing_support
context["ga_products"] = f"/{product_slug}/"
if step == 2:
topics = topics_for(request.user, product, parent=None)
context["featured"] = get_featured_articles(product, locale=request.LANGUAGE_CODE)
context["topics"] = build_topics_data(request, product, topics)
elif step == 3:
context["cancel_url"] = get_next_url(request) or (
reverse("products.product", args=[product.slug])
if is_loginless
else reverse("questions.aaq_step2", args=[product_slug])
)
# Check if the selected product has a forum in the user's locale
if not has_public_forum:
locale, path = split_into_language_and_path(request.path_info)
path = f"/{settings.WIKI_DEFAULT_LANGUAGE}{path}"
old_lang = settings.LANGUAGES_DICT[request.LANGUAGE_CODE.lower()]
new_lang = settings.LANGUAGES_DICT[settings.WIKI_DEFAULT_LANGUAGE.lower()]
msg = _(
"The questions forum isn't available for {product} in {old_lang}, we "
"have redirected you to the {new_lang} questions forum."
).format(product=product.title, old_lang=old_lang, new_lang=new_lang)
messages.add_message(request, messages.WARNING, msg)
return HttpResponseRedirect(path)
if product.has_ticketing_support:
zendesk_form = ZendeskForm(
data=request.POST or None,
product=product,
user=request.user,
)
context["form"] = zendesk_form
context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json(
request.session, product
)
if zendesk_form.is_valid() and not is_ratelimited(request, "loginless", "3/d"):
try:
zendesk_form.send(request.user, product)
email = zendesk_form.cleaned_data["email"]
messages.add_message(
request,
messages.SUCCESS,
_(
"Done! Thank you for reaching out Mozilla Support."
" We've sent a confirmation email to {email}"
).format(email=email),
)
url = reverse("products.product", args=[product.slug])
return HttpResponseRedirect(url)
except APIException as err:
messages.add_message(
request, messages.ERROR, _("That didn't work. Please try again.")
)
capture_exception(err)
if getattr(request, "limited", False):
messages.add_message(
request,
messages.ERROR,
_("You've exceeded the number of submissions for today."),
)
return render(request, template, context)
form = NewQuestionForm(
product=product,
data=request.POST or None,
)
context["form"] = form
if form.is_valid() and not is_ratelimited(request, "aaq-day", "5/d"):
question = form.save(
user=request.user,
locale=request.LANGUAGE_CODE,
product=product,
)
if visits := get_kb_visited(request.session, product, question.topic):
question.add_metadata(kb_visits_prior=json.dumps(visits))
if form.cleaned_data.get("is_spam"):
_add_to_moderation_queue(request, question)
# Submitting the question counts as a vote
question_vote(request, question.id)
my_questions_url = reverse("users.questions", args=[request.user.username])
messages.add_message(
request,
messages.SUCCESS,
_(
"Done! Your question is now posted on the Mozilla community support forum. "
+ "You can see your post anytime by visiting the {a_open}My Questions"
+ "{a_close} page in your profile."
).format(a_open="<a href='" + my_questions_url + "'>", a_close="</a>"),
extra_tags="safe",
)
request.session["aaq-final-step"] = True
url = reverse("questions.details", kwargs={"question_id": question.id})
return HttpResponseRedirect(url)
if getattr(request, "limited", False):
raise PermissionDenied
user_ct = ContentType.objects.get_for_model(request.user)
context["images"] = ImageAttachment.objects.filter(
creator=request.user,
content_type=user_ct,
).order_by("-id")[:IMG_LIMIT]
if form.is_bound and (topic := form.cleaned_data.get("category")):
# We've got invalid POST data, but the topic has been provided.
# Let's set the proper GA4 event parameters on the submit button.
context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json(
request.session, product, topic=topic
)
else:
# We don't know the topic yet, since that's set via the form, so let's
# start by providing default GA4 event parameters for the submit button.
context["submit_event_parameters"] = get_ga_submit_event_parameters_as_json()
return render(request, template, context)