How to save new user setting ?

I make a new form at user settings page (www.example.com/settings/user) and the form has been appeared succesfully. i use longtext form

but i don't understand why it's failed to save new setting ?

in start.php i put

elgg_register_plugin_hook_handler('usersettings:save', 'user', 'thespecialmessage');

and

function thespecialmessage($hook, $type, $value, $params)
{
        $user_guid = (int) get_input('guid');
    $new_message = get_input('specialmessage');
if($user = get_user($user_guid)){
                            elgg_set_plugin_user_setting('specialmessage',$new_message,$user->getGUID(), 'specialmessage');
                            if ($user->save()) {
                                elgg_register_plugin_hook_handler("forward", "system", "validate_specialmessage");

                                system_message(elgg_echo('Your setting have been saved succesfully'));
                            }
}                            
}

there is no error when i click "save", but the new setting is not saved.

 

i'm sorry ,I have never made a plugin before , i just study the code form other plugin :)

 

  • You can't leave away the return statements. They are important for Elgg to know what it should do after executing the code of the function.

    If you save the message using elgg_set_plugin_user_setting(), you don't need to use $user->save().

    I don't know the idea you have for using elgg_register_plugin_hook_handler("forward", "system", "validate_specialmessage"); within the callback function but I'm pretty sure this won't work. Just add a separate function, e.g. named "validate_specialmessage" that does the validation of the message and call it directly.

    elgg_echo() is used to be able to provide translations for the text you want to display - that is a good idea in the long run. So, add a language file to your plugin where you put the language strings into and then use elgg_echo() with the language string key you want to display. If you want to hard-code a text string that should be displayed, you can omit elgg_echo, e.g. system_message('My message') but it will be much harder to maintain if you ever want to change the text and you can't translate the output.

    Without having tested I hope the following code is not too wrong:

    function thespecialmessage($hook, $type, $value, $params) {
        $user_guid = (int)get_input('guid');
        $new_message = get_input('specialmessage');
    
        if (!isset($new_message)) {
            return;
        }
    
        // Fall back to logged in user if no user guid provided
        if ($user_guid) {
            $user = get_user($user_guid);
        } else {
            $user = elgg_get_logged_in_user_entity();
        }
    
        if ($user && $new_message) {
            $validated_message = validate_specialmessage($new_message);
            if ($validated_message} {
                $old_message = elgg_get_plugin_user_setting('specialmessage', $user->getGUID(), 'specialmessage', '');
                // only save if new validated message is different from already saved message
                if (strcmp($validated_message, $old_message) != 0) {
                    if (elgg_set_plugin_user_setting('specialmessage', $validated_message, $user->getGUID(), 'specialmessage')) {
                        // saved successfully
                        system_message(elgg_echo('specialmessage:message_saved:success'));
                        return true;
                    } else {
                        // saving failed
                        register_error(elgg_echo('specialmessage:message_saved:fail'));
                    }
                } else {
                    // no change
                    return;
                }
            } else {
                register_error(elgg_echo('specialmessage:message_saved:unvalidated'));
            }
        return false;
    }
    
    function validate_specialmessage($new_message) {
        // validate the message logic goes here
        // don't know what you have in mind here so you will have to add the necessary code on your own
        // it could work as follows:
        // 1. input (unvalidated) is $new_message
        // 2. do the validation - or possibly (only?) clean up of the string
        // 3a. if the message is okay, set $validated to true and return the validated message (assuming it's in $validated_message)
        // 3b. if the message is not okay, set $validated to false and return false
    
        if ($validated) {
            return $validated_message;
        } else {
            return false;
        }
    }

    And the language file (e.g. en.php):

    <?php
    return array{
        'specialmessage:message_saved:success' => "Your special message has been saved successfully.",
        'specialmessage:message_saved:fail' => "Your special message could not be saved.",
        'specialmessage:message_saved:unvalidated' => "The validation of your special message has failed. Maybe you have some invalid characters in your message.",
    }
  • Your answer is always detailed and useful :) Thank you very much for your code, i will try it :)