Passed
Push — 2.x ( 0ba30f...7ab1ba )
by Jordi
08:49
created

BaseWidget.get_context()   A

Complexity

Conditions 5

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 24
rs 9.3333
c 0
b 0
f 0
cc 5
nop 1
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE.
4
#
5
# SENAITE.CORE is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2024 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
from bika.lims import api
22
from plone.z3cform.fieldsets.interfaces import IDescriptiveGroup
23
from z3c.form.interfaces import ISubForm
24
from z3c.form.widget import Widget
25
26
27
class BaseWidget(Widget):
28
29
    def get_form(self):
30
        """Return the current form of the widget
31
        """
32
        if not self.form:
33
            return None
34
35
        form = self.form
36
        # form is a fieldset group
37
        if IDescriptiveGroup.providedBy(form):
38
            form = form.parentForm
39
        # form is a subform (e.g. DataGridFieldObjectSubForm)
40
        if ISubForm.providedBy(form):
41
            form = form.parentForm
42
        return form
43
44
    def get_portal_type(self, default=None):
45
        """Extract the portal type from the form or the query
46
        """
47
        form = self.get_form()
48
        portal_type = getattr(form, "portal_type", None)
49
        if not portal_type:
50
            query = getattr(self, "query", {})
51
            portal_type = query.get("portal_type")
52
            if api.is_list(portal_type):
53
                portal_type = portal_type[0]
54
        return portal_type or default
55
56
    def get_context(self):
57
        """Get the current context
58
59
        NOTE: If we are in the ++add++ form, `self.context` is the container!
60
              Therefore, we create one here to have access to the methods.
61
        """
62
        # We are in the edit view. Return the context directly
63
        schema_iface = self.field.interface if self.field else None
64
        if schema_iface and schema_iface.providedBy(self.context):
65
            return self.context
66
        # We might be in a subform or in a datagrid widget.
67
        # Therefore, `self.context` is not set or set to `<NO_VALUE>`
68
        form = self.get_form()
69
        portal_type = self.get_portal_type()
70
        context = getattr(form, "context", None)
71
        # no context found, return
72
        # happens e.g. in the `datetimewidget.txt` doctest
73
        if context is None:
74
            return None
75
        # Hack alert!
76
        # we are in ++add++ form and have no context!
77
        # Create a temporary object to be able to access class methods
78
        view = api.get_view("temporary_context", context=context)
79
        return view.create_temporary_context(portal_type)
80