- 
                Notifications
    
You must be signed in to change notification settings  - Fork 9
 
Global form submissions #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6db9572
              50d1d13
              7c17baa
              de03c07
              1053f5f
              758a85a
              351a43c
              29d389b
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| 
          
            
          
           | 
    @@ -18,6 +18,11 @@ | |||||
| import os | ||||||
| 
     | 
||||||
| 
     | 
||||||
| GLOBAL_FORM_REGISTRY_RECORD_ID = ( | ||||||
| "collective.volto.formsupport.interfaces.IGlobalFormStore.global_forms_config" | ||||||
| ) | ||||||
| 
     | 
||||||
| 
     | 
||||||
| @implementer(IPostAdapter) | ||||||
| @adapter(Interface, Interface) | ||||||
| class PostAdapter: | ||||||
| 
        
          
        
         | 
    @@ -29,8 +34,12 @@ def __init__(self, context, request): | |||||
| self.request = request | ||||||
| self.form_data = self.extract_data_from_request() | ||||||
| self.block_id = self.form_data.get("block_id", "") | ||||||
| self.global_form_id = self.extract_data_from_request().get("global_form_id", "") | ||||||
| if self.block_id: | ||||||
| self.block = self.get_block_data(block_id=self.block_id) | ||||||
| self.block = self.get_block_data( | ||||||
| block_id=self.block_id, | ||||||
| global_form_id=self.form_data.get("global_form_id"), | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||
| ) | ||||||
| 
     | 
||||||
| def __call__(self): | ||||||
| """ | ||||||
| 
        
          
        
         | 
    @@ -50,7 +59,10 @@ def extract_data_from_request(self): | |||||
| fixed_fields = [] | ||||||
| transforms = api.portal.get_tool(name="portal_transforms") | ||||||
| 
     | 
||||||
| block = self.get_block_data(block_id=form_data.get("block_id", "")) | ||||||
| block = self.get_block_data( | ||||||
| block_id=form_data.get("block_id", ""), | ||||||
| global_form_id=form_data.get("global_form_id"), | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
        Suggested change
       
    
  | 
||||||
| ) | ||||||
| block_fields = [x.get("field_id", "") for x in block.get("subblocks", [])] | ||||||
| 
     | 
||||||
| for form_field in form_data.get("data", []): | ||||||
| 
        
          
        
         | 
    @@ -68,12 +80,24 @@ def extract_data_from_request(self): | |||||
| 
     | 
||||||
| return form_data | ||||||
| 
     | 
||||||
| def get_block_data(self, block_id): | ||||||
| def get_block_data(self, block_id, global_form_id): | ||||||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably you don't need to pass global_form_id as parameter because is already set in init  | 
||||||
| blocks = get_blocks(self.context) | ||||||
| global_form_id = global_form_id | ||||||
| if global_form_id: | ||||||
| global_forms = api.portal.get_registry_record( | ||||||
| GLOBAL_FORM_REGISTRY_RECORD_ID | ||||||
| ) | ||||||
| if global_forms: | ||||||
| blocks = {**blocks, **global_forms} | ||||||
| if not blocks: | ||||||
| return {} | ||||||
| for id, block in blocks.items(): | ||||||
| if id != block_id: | ||||||
| # Prefer local forms it they're available, fall back to global form | ||||||
| if ( | ||||||
| id != block_id | ||||||
| and id != global_form_id | ||||||
| and block.get("global_form_id") != global_form_id | ||||||
| ): | ||||||
| continue | ||||||
| block_type = block.get("@type", "") | ||||||
| if block_type != "form": | ||||||
| 
          
            
          
           | 
    ||||||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,12 +1,34 @@ | ||
| from plone.api.portal import get_registry_record | ||
| from plone.api.portal import set_registry_record | ||
| from plone.dexterity.interfaces import IDexterityContent | ||
| from plone.restapi.bbb import IPloneSiteRoot | ||
| from plone.restapi.interfaces import IBlockFieldDeserializationTransformer | ||
| from Products.PortalTransforms.transforms.safe_html import SafeHTML | ||
| from uuid import uuid4 | ||
| from zope.component import adapter | ||
| from zope.interface import implementer | ||
| from zope.publisher.interfaces.browser import IBrowserRequest | ||
| 
     | 
||
| 
     | 
||
| GLOBAL_FORM_REGISTRY_RECORD_ID = ( | ||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be a good idea moving this constant in a common place and import it also in post adapter?  | 
||
| "collective.volto.formsupport.interfaces.IGlobalFormStore.global_forms_config" | ||
| ) | ||
| 
     | 
||
| 
     | 
||
| def update_global_forms(value): | ||
| global_form_id = value.get("global_form_id") | ||
| 
     | 
||
| if not global_form_id: | ||
| global_form_id = str(uuid4()) | ||
| 
     | 
||
| global_forms_record = get_registry_record(GLOBAL_FORM_REGISTRY_RECORD_ID) | ||
| global_forms_record[global_form_id] = value | ||
| set_registry_record(GLOBAL_FORM_REGISTRY_RECORD_ID, global_forms_record) | ||
| 
     | 
||
| value["global_form_id"] = global_form_id | ||
| return value | ||
| 
     | 
||
| 
     | 
||
| class FormBlockDeserializerBase: | ||
| """FormBlockDeserializerBase.""" | ||
| 
     | 
||
| 
        
          
        
         | 
    @@ -25,6 +47,7 @@ def __call__(self, value): | |
| if value.get("send_message", ""): | ||
| transform = SafeHTML() | ||
| value["send_message"] = transform.scrub_html(value["send_message"]) | ||
| value = update_global_forms(value) | ||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me better understand this..when you deserialize the block, you are storing its data twice: in the context and in registry, right? I'm not a big fan of this approach, but i don't know if there is a better way to do it, or avoid setting it globally when we are working on a content item. Or (maybe better): store form data always in registry, and in the content, only store the block_id reference. What do you think about it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I think storing both the saved data and the schema on the root object is the way to go, regardless of if there is a local page context or not. Then it's one implementation so less complicated. 
  | 
||
| return value | ||
| 
     | 
||
| 
     | 
||
| 
          
            
          
           | 
    ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.