We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 17403 ☆ A M B ☆
    • 183 Posts
    MODx Version 2.2.5-pl

    When creating new Resource, TVs did not load correctly when we change default template on the fly, either using Plugin or Form Customization.

    For example:
    - create a "folderTemplate" template, and attach some TVs into it (example we attach "folderTV")
    - create a "childTemplate" template, and attach some TVs into it (example we attach "childTV")
    - create a Form Customization (with resource/create rule set) to set child resource of "folderTemplate" by default use "childTemplate", or we can create a plugin to set it programmatically.
    - create a Container with "folderTemplate" as its template.

    Then try to create a new resource under the newly created Container. The template by default loaded correctly (childTemplate), but the TVs loaded incorrectly. Instead of displaying "childTV", the resource panel displaying "folderTV".

    Here what I found on modx/manager/controller/default/resource/create.class.php that extend base class modx/manager/controller/default/resource/resource.class.php


    DEBUG OUTPUT
    Assume folderTemplate's id=9, and childTemplate's id=10.


    #log-1: manager/controllers/default/resource/create.class.php line 85
    - function proccess -> $this->resource->get('template') before fireOnRenderEvent
    return template: 0

    #log-2: manager/controllers/default/resource/create.class.php line 98
    - function process -> call function getDefaultTemplate
    return defaultTemplate: 9

    #log-3: manager/controllers/default/resource/create.class.php line 121
    - function process -> get checkFormCustomizationRules()
    return $overridden template: 10

    #log-4: manager/controllers/default/resource/create.class.php line 147
    - function process -> $this->resourceArray['template']
    return template: 10

    - function process -> $this->resource->get('template')
    return template: 9

    #log-5: manager/controllers/default/resource/resource.class.php line 263
    - loadTVs:this->resource->get('template'): 9


    When creating a new resource, the default $resource::get template=0, that's correct (Log-1). Template remain 0, until just before fireOnRenderEvent.

    So a plugin with OnDocFormRender event can change the template with
    $resource->set('template', n), where "n" is template ID.


    If the template did not change, then it's search for parent container and get it's template (defaultTemplate=9), that' correct (log-2).

    Still on function process at create.class.php, it's search for FormCustomizationRules and get expected overridden template: 10, that's correct (log-3).

    Log-4 show that resourceArray has been overridden; then it will be outputed to html as jSON with template: 10, its correct (log-4a). But somehow its forgot to also override $resource object. (log-4b)

    At last, function process make a call to loadTVs function, but the loadTVs function wrongly output the TVs because it get the template from $resource->get('template') not from $resourceArray['template']. (log-5) [ed. note: lokamaya last edited this post 13 years, 10 months ago.]
      zaenal.lokamaya
      • 17403 ☆ A M B ☆
      • 183 Posts
      To make TVs loaded correctly, we should make some modification to function process() on create.class.php



      MAKE modify template on PLUGIN works

      Around line 85
              $this->fireOnRenderEvent();
      


      Modify as below
              $defaultTemplate = $this->resource->get('template');
              $this->fireOnRenderEvent();
              
              if ($defaultTemplate != $this->resource->get('template')) {
                  $this->scriptProperties['template'] = $this->resource->get('template');
              }
      




      MAKE modify template on FORM CUSTOMIZATION works

      Around line 170-175
              /* get TVs */
              $this->loadTVs($reloadData);
      


      add some line below
              if ($this->resourceArray['template'] != $this->resource->get('template')) {
                 $this->resource->set('template', $this->resourceArray['template']);
              }
      
              /* get TVs */
              $this->loadTVs($reloadData);
      



      [ed. note: lokamaya last edited this post 13 years, 10 months ago.]
        zaenal.lokamaya
        • 17403 ☆ A M B ☆
        • 183 Posts
        Actually, there are still much room for speed. For example there are so many variables that hold $resource data on create.class.php (and also update.class.php):

        • $this->resource <- MODx resource
        • $this->resourceArray <- used as JSON source
        • $scriptProperties <- passed from and required by base class
        • $placehodler['resource'] = $this->resource
          Not deeded at all because only used once in tpl (smarty). Considering MODx resource is a big object, change it to resourceArray would be sufficient:
          $placehodler['resource'] = $this->resourceArray
          Note: this should be placed at the end of function process after all changes/modifications has been made to resource object.
        • $placehodler['parent'] = $this->parent
          not used at all in tpl (smarty)

        At least we should check $this->resource and $this->resourceArray must be have same values. All changes made to $this->resource should be applied to $this->resourceArray, and vice versa. [ed. note: lokamaya last edited this post 13 years, 10 months ago.]
          zaenal.lokamaya
          • 17403 ☆ A M B ☆
          • 183 Posts
            zaenal.lokamaya