Passed
Push — 2.x ( f01285...cc9902 )
by Ramon
11:03
created

senaite.core.z3cform.widgets.basewidget   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 38
dl 0
loc 82
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A BaseWidget.get_form() 0 14 4
B BaseWidget.get_context() 0 36 8
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-2023 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
from zope.component import getUtility
26
from zope.component.interfaces import IFactory
27
28
29
class BaseWidget(Widget):
30
31
    def get_form(self):
32
        """Return the current form of the widget
33
        """
34
        if not self.form:
35
            return None
36
37
        form = self.form
38
        # form is a fieldset group
39
        if IDescriptiveGroup.providedBy(form):
40
            form = form.parentForm
41
        # form is a subform (e.g. DataGridFieldObjectSubForm)
42
        if ISubForm.providedBy(form):
43
            form = form.parentForm
44
        return form
45
46
    def get_context(self):
47
        """Get the current context
48
49
        NOTE: If we are in the ++add++ form, `self.context` is the container!
50
              Therefore, we create one here to have access to the methods.
51
        """
52
        schema_iface = self.field.interface if self.field else None
53
        if schema_iface and schema_iface.providedBy(self.context):
54
            return self.context
55
56
        # we might be in a subform, so try first to retrieve the object from
57
        # the base form itself first
58
        form = self.get_form()
59
        portal_type = getattr(form, "portal_type", None)
60
        context = getattr(form, "context", None)
61
        if api.is_object(context):
62
            if api.get_portal_type(context) == portal_type:
63
                return context
64
65
        if not self.context:
66
            return None
67
68
        # Hack alert!
69
        # we are in ++add++ form and have no context!
70
        # Create a temporary object to be able to access class methods
71
        if not portal_type:
72
            portal_type = api.get_portal_type(self.context)
73
        portal_types = api.get_tool("portal_types")
74
        fti = portal_types[portal_type]
75
        factory = getUtility(IFactory, fti.factory)
76
        context = factory("temporary")
77
        # mark the context as temporary
78
        context._temporary_ = True
79
        # hook into acquisition chain
80
        context = context.__of__(self.context)
81
        return context
82