1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Alter save in ACP

Discussion in 'XenForo Development Discussions' started by katsulynx, Jan 14, 2014.

  1. katsulynx

    katsulynx Well-Known Member

    I've altered the xen_user_field table in the database and extended it by a new column.

    [​IMG]


    Also I altered the matching piece inside the ACP to support the new field.
    [​IMG]


    But as by now, the selected value inside the ACP is not altered in the table. Guess I have to edit some php file here? If so, which one and how is it normally done without altering existing xenforo files?
     
  2. Jeremy

    Jeremy XenForo Moderator Staff Member

    You need to edit a datawriter. Search for the table name in the files.
     
  3. katsulynx

    katsulynx Well-Known Member

    Guess I have to replace the DataWriter of UserField.php, as it is probably not recommended to alter the file when creating a public mod. Would have coppied and altered the file, then altered the save-call inside the template. I am however struggling to understand the call inside the template for the DataWriter or better said, how to replace the DataWriter called here.

    Code:
    <xen:form action="{xen:adminlink 'user-fields/save', $field}" class="AutoValidator" data-redirect="on">
    Is it simply enough to provide a new one with the same file name inside my addon? Probably not i guess...
     
  4. Jeremy

    Jeremy XenForo Moderator Staff Member

    You will want to use the class proxy system. That call is a submission to a URL that is run by a controller.
     
    katsulynx likes this.
  5. katsulynx

    katsulynx Well-Known Member

    I've tried to follow this Tutorial, but it seems 'unnecessary' much stuff for a single line of code. I am somewhere between creating two files and having no idea what to do next or which Event Listener to extend (probably load_class_datawriter...) but as said, is it correct that I need to set up two files for one additional line? I am effectively adding
    Code:
    'permissionSecure'        => array('type'    => self::TYPE_BOOLEAN, 'default' => 0)
    to
    Code:
    protected function _getFields()
        {
            return array(
                'xf_user_field' => array(
                    'field_id'              => array('type' => self::TYPE_STRING, 'required' => true, 'maxLength' => 25,
                            'verification' => array('$this', '_verifyFieldId'), 'requiredError' => 'please_enter_valid_field_id'
                    ),
                    'display_group'         => array('type' => self::TYPE_STRING, 'default' => 'personal',
                        'allowedValues' => array('personal', 'contact', 'preferences')
                    ),
                    'display_order'         => array('type' => self::TYPE_UINT, 'default' => 1),
                    'field_type'            => array('type' => self::TYPE_STRING, 'default' => 'textbox',
                        'allowedValues' => array('textbox', 'textarea', 'select', 'radio', 'checkbox', 'multiselect')
                    ),
                    'field_choices'         => array('type' => self::TYPE_SERIALIZED, 'default' => ''),
                    'match_type'            => array('type' => self::TYPE_STRING, 'default' => 'none',
                        'allowedValues' => array('none', 'number', 'alphanumeric', 'email', 'url', 'regex', 'callback')
                    ),
                    'match_regex'           => array('type' => self::TYPE_STRING, 'default' => '', 'maxLength' => 250),
                    'match_callback_class'  => array('type' => self::TYPE_STRING, 'default' => '', 'maxLength' => 75),
                    'match_callback_method' => array('type' => self::TYPE_STRING, 'default' => '', 'maxLength' => 75),
                    'max_length'            => array('type' => self::TYPE_UINT, 'default' => 0),
                    'required'              => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                    'show_registration'     => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                    'user_editable'         => array('type' => self::TYPE_STRING, 'default' => 'yes',
                        'allowedValues' => array('yes', 'once', 'never')
                    ),
                    'viewable_profile'      => array('type' => self::TYPE_BOOLEAN, 'default' => 1),
                    'viewable_message'      => array('type' => self::TYPE_BOOLEAN, 'default' => 0),
                    'display_template'      => array('type' => self::TYPE_STRING, 'default' => ''),
               
                    //Permission Secure Extension
                    'permissionSecure'        => array('type'    => self::TYPE_BOOLEAN, 'default' => 0)
                )
            );
        }

    Edit: I think I have done a step in the right direction. I have now created my class as "Katsulynx/KLCPFP/DataWriter/UserField.php"
    PHP:
    <?php
    class Katsulynx_KLCPFP_DataWriter_UserField extends XFCP_Katsulynx_KLCPFP_DataWriter_UserField
    {
      protected function 
    _getFields()
        {
            return array(
                
    'xf_user_field' => array(
                    
    'field_id'              => array('type' => self::TYPE_STRING'required' => true'maxLength' => 25,
                            
    'verification' => array('$this''_verifyFieldId'), 'requiredError' => 'please_enter_valid_field_id'
                    
    ),
                    
    'display_group'         => array('type' => self::TYPE_STRING'default' => 'personal',
                        
    'allowedValues' => array('personal''contact''preferences')
                    ),
                    
    'display_order'         => array('type' => self::TYPE_UINT'default' => 1),
                    
    'field_type'            => array('type' => self::TYPE_STRING'default' => 'textbox',
                        
    'allowedValues' => array('textbox''textarea''select''radio''checkbox''multiselect')
                    ),
                    
    'field_choices'         => array('type' => self::TYPE_SERIALIZED'default' => ''),
                    
    'match_type'            => array('type' => self::TYPE_STRING'default' => 'none',
                        
    'allowedValues' => array('none''number''alphanumeric''email''url''regex''callback')
                    ),
                    
    'match_regex'           => array('type' => self::TYPE_STRING'default' => '''maxLength' => 250),
                    
    'match_callback_class'  => array('type' => self::TYPE_STRING'default' => '''maxLength' => 75),
                    
    'match_callback_method' => array('type' => self::TYPE_STRING'default' => '''maxLength' => 75),
                    
    'max_length'            => array('type' => self::TYPE_UINT'default' => 0),
                    
    'required'              => array('type' => self::TYPE_BOOLEAN'default' => 0),
                    
    'show_registration'     => array('type' => self::TYPE_BOOLEAN'default' => 0),
                    
    'user_editable'         => array('type' => self::TYPE_STRING'default' => 'yes',
                        
    'allowedValues' => array('yes''once''never')
                    ),
                    
    'viewable_profile'      => array('type' => self::TYPE_BOOLEAN'default' => 1),
                    
    'viewable_message'      => array('type' => self::TYPE_BOOLEAN'default' => 0),
                    
    'display_template'      => array('type' => self::TYPE_STRING'default' => ''),
                  
                    
    //Permission Secure Extension
                    
    'permissionSecure'        => array('type'    => self::TYPE_BOOLEAN'default' => 0)
                )
            );
        }
    }
    ?>
    and the corresponding Listener "Katsulynx/KLCPFP/Listener/DataWriter.php"
    PHP:
    <?php

    class Katsulynx_KLCPFP_Listener_DataWriter
    {
        
    /**
         * Instruct the system that XenForo_ControllerPublic_Member
         * should be extended by Dev_ControllerPublic_Member
         *
         * @param string $class
         * @param array $extend
         */
        
    public static function extendUserDataWriter($class, array &$extend)
        {
            if (
    $class == 'XenForo_DataWriter_UserField')
            {
                
    $extend[] = 'Katsulynx_KLCPFP_DataWriter_UserField';
            }
        }
    }
    and set up the Code Event Listener
    01.jpg

    Is this, how it should be done?

    Edit2: Seems not to work however, don't know if it is the extension setup or I haven't done the right extensions yet.
     
    Last edited: Jan 15, 2014
  6. Jeremy

    Jeremy XenForo Moderator Staff Member

    You are on the right track. Except you don't want to full sail replace the function. You want to return the array from the parents class (generated by it) with yours inserted.

    You are now only half of the way there. You need to extend the controller as well to insert the proper data.
     
  7. katsulynx

    katsulynx Well-Known Member

    So I want to merge my single line array with the array given back by the Parent class when calling
    PHP:
    parent::_getFields()
    inside my class and return that one?

    Like this?
    PHP:
    <?php
    class Katsulynx_KLCPFP_DataWriter_UserField extends XFCP_Katsulynx_KLCPFP_DataWriter_UserField
    {
      protected function 
    _getFields()
        {
        
            return 
    array_merge parent::_getFields(), array('xf_user_field' => array('permissionSecure'=> array('type' => self::TYPE_BOOLEAN'default' => 0))));

        }
    }
    ?>
    Edit: Haha, at least I can see something happening now, when altering the options, I'll get an error message thrown when trying to save :ROFLMAO:
    Code:
    lease correct the following errors:
    
    The requested field could not be found.
    The field 'display_group' was not recognised.
    Display Order:
    The field 'display_order' was not recognised.
    The field 'field_type' was not recognised.
    The field 'match_type' was not recognised.
    The field 'match_regex' was not recognised.
    The field 'match_callback_class' was not recognised.
    The field 'match_callback_method' was not recognised.
    Maximum Length:
    The field 'max_length' was not recognised.
    The field 'required' was not recognised.
    The field 'show_registration' was not recognised.
    The field 'viewable_profile' was not recognised.
    The field 'viewable_message' was not recognised.
    Value Display HTML:
    The field 'display_template' was not recognised.
    The field 'user_editable' was not recognised.
    The field 'field_choices' was not recognised.
    Edit2: Guess this is a better approach:
    PHP:
    <?php
    class Katsulynx_KLCPFP_DataWriter_UserField extends XFCP_Katsulynx_KLCPFP_DataWriter_UserField
    {
      protected function 
    _getFields()
        {
           
            
    $parrent_array parent::_getFields();
            
    $array_extension = array('permissionSecure'=> array('type' => self::TYPE_BOOLEAN'default' => 0));
           
            
    $parrent_array['xf_user_field'] = array_merge($parrent_array['xf_user_field'], $array_extension);
           
            return 
    $parrent_array;
        }
    }
    ?>
    The error message seems to be gone, but however it still denies to save my new settings, seems like I am still missing something...
     
    Last edited: Jan 15, 2014
  8. Jeremy

    Jeremy XenForo Moderator Staff Member

    Yes, now that you have the data writer, you need to modify the actual save. Have you ever used the DataWriters?
     
  9. katsulynx

    katsulynx Well-Known Member

    Not yet, I have just started working myself into the materia.
     
  10. katsulynx

    katsulynx Well-Known Member

    I've taken a deeper look into it, but I'm somehow not clever enough to get on the right track. As I am missing the save, I'll probably have to alter either the _postSave() or _preSave() method, but they both seem pretty much completed as they are... The only other thing I could image is, that my new field is not processed in the setFieldChoices(), but I can't determine, where this method gets its arguments from. <- Stupid me, is set in the _preSave(). So I'd say I am definitly lacking something in the setFieldChoices or, more likely, in the preSave.
     
    Last edited: Jan 16, 2014
  11. katsulynx

    katsulynx Well-Known Member

    Started to edit the _preSave()-function to fit my needs. But I haven't yet found out how to receive the selected value (if the field is checked or unchecked) yet. I am however able to save a predefined value by now :LOL: My new function looks like this:

    PHP:
    protected function _preSave() {
            
    parent::_preSave();  
          
            
    //TODO: Select value and replace that zero with the respective variable
            
    $this->set('permissionSecure'0);
        }
    Could someone give me a hint on how to get the needed value? I've experimented with the getter-method, but realized that this is kind of stupid, as it (at least I think so), receives the currently set value from the database. When I did so, I achieved that the field was automatically unset if it was set in the database and the other way round when saving :ROFLMAO:.
     
  12. Jeremy

    Jeremy XenForo Moderator Staff Member

    Look at the controllers and the input filters.
     

Share This Page