Allow to pass user data to the widget (#1095)

- [x] Logic
- [x] Tests
- [x] Docs
- [x] find a way to integrate with tracking
This commit is contained in:
Raphael Michel
2018-11-20 17:55:37 +01:00
committed by GitHub
parent b49b2035bd
commit beb0ded6dc
10 changed files with 335 additions and 29 deletions

View File

@@ -1,8 +1,10 @@
import json
import mimetypes
import os
from django.conf import settings
from django.contrib import messages
from django.core.cache import caches
from django.db.models import Q
from django.http import FileResponse, Http404, JsonResponse
from django.shortcuts import get_object_or_404, redirect
@@ -33,6 +35,11 @@ from pretix.presale.views.event import (
)
from pretix.presale.views.robots import NoSearchIndexViewMixin
try:
widget_data_cache = caches['redis']
except:
widget_data_cache = caches['default']
class CartActionMixin:
@@ -266,11 +273,20 @@ def get_or_create_cart_id(request, create=True):
cart_data = {}
if prefix and 'take_cart_id' in request.GET and current_id:
new_id = current_id
cached_widget_data = widget_data_cache.get('widget_data_{}'.format(current_id))
if cached_widget_data:
cart_data['widget_data'] = cached_widget_data
else:
if not create:
return None
new_id = generate_cart_id(request, prefix=prefix)
if 'widget_data' not in cart_data and 'widget_data' in request.GET:
try:
cart_data['widget_data'] = json.loads(request.GET.get('widget_data'))
except ValueError:
pass
if 'carts' not in request.session:
request.session['carts'] = {}
if new_id not in request.session['carts']:
@@ -349,10 +365,24 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
}
def post(self, request, *args, **kwargs):
cart_id = get_or_create_cart_id(self.request)
if "widget_data" in request.POST:
try:
widget_data = json.loads(request.POST.get("widget_data", "{}"))
except ValueError:
widget_data = {}
else:
widget_data_cache.set('widget_data_{}'.format(cart_id), widget_data, 600)
cs = cart_session(request)
cs['widget_data'] = widget_data
else:
cs = cart_session(request)
widget_data = cs.get('widget_data', {})
items = self._items_from_post_data()
if items:
return self.do(self.request.event.id, items, get_or_create_cart_id(self.request), translation.get_language(),
self.invoice_address.pk)
return self.do(self.request.event.id, items, cart_id, translation.get_language(),
self.invoice_address.pk, widget_data)
else:
if 'ajax' in self.request.GET or 'ajax' in self.request.POST:
return JsonResponse({
@@ -449,6 +479,10 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, TemplateView):
def get(self, request, *args, **kwargs):
if 'iframe' in request.GET and 'require_cookie' not in request.GET:
return redirect(request.get_full_path() + '&require_cookie=1')
if len(self.request.GET.get('widget_data', '{}')) > 3:
# We've been passed data from a widget, we need to create a cart session to store it.
get_or_create_cart_id(request)
return super().get(request, *args, **kwargs)

View File

@@ -189,6 +189,9 @@ class EventIndex(EventViewMixin, CartMixin, TemplateView):
return redirect(eventreverse(request.event, 'presale:event.index', kwargs=kwargs) + '?require_cookie=true&cart_id={}'.format(
request.GET.get('take_cart_id')
))
elif request.GET.get('iframe', '') == '1' and len(self.request.GET.get('widget_data', '{}')) > 3:
# We've been passed data from a widget, we need to create a cart session to store it.
get_or_create_cart_id(request)
elif 'require_cookie' in request.GET and settings.SESSION_COOKIE_NAME not in request.COOKIES:
# Cookies are in fact not supported
r = render(request, 'pretixpresale/event/cookies.html', {