Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Admin changing a preference for all users?

mattmatt ✭✭
edited April 2007 in Vanilla 1.0 Help
Hi,

Is it possible for a forum admin to change a preference for all users? For example, I'd like to switch on whisper notification for all users.

I'd ideally like to do this without getting knee deep in SQL. Any ideas?

Thanks,
matt

Comments

  • if there arent any other preferences used in your forum, you can just add this line to a php file and run it ONCE,then delete or comment out the line:
    mysql_query("UPDATE `LUM_User` SET `Preferences` = 'a:1:{s:18:\"NotifyOnNewWhisper\";i:1;}' ");>
  • If there are other preferences, you would have to loop through each user and twiddle the bit in the array that belongs to whisper notification.

    This would really be a good extension.
  • edited April 2007
    So preference field is a text type. what does this mean a:1:{s:18:\"NotifyOnNewWhisper\";i:1;}
  • It's a array that has been serialized into a string--benefit being that you can add new preferences easily without having to add new columns to the user table for each preference. You would have to run that string through <samp>UnserializeAssociativeArray('a:1:{s:18:\"NotifyOnNewWhisper\";i:1;}')</samp> (defined in framework.functions.php) to get the array of the preferences, then toggle them like is done inside the extension. You can see how Vanilla loads that field in People.Class.User.php and saves the field in People.Class.UserManager.php
  • mattmatt ✭✭
    I'd thought of Mr Do's method, but as other have noted it will overwrite any other preferences stored for that user.

    I'd love to see an extension for this.

    a:1:{s:18:\"NotifyOnNewWhisper\";i:1;} means:
    array of length 1. first item: string of length 18, named "NotifyOnNewWhisper", with a value of integer:1

    another:

    a:5:{s:14:"ShowActivePoll";i:0;s:13:"ShowBookmarks";i:1;s:21:"ShowRecentDiscussions";i:1; s:23:"AUDIOSCROBBLER_USERNAME";s:8:"msephton";s:19:"ShowLargeCommentBox";i:1;}

    array of length 5
    string of length 14, string name "ShowActivePoll", string value (here integer of value 0),
    string of length 13, string name "ShowBookmarks", string value (here integer of value 1),
    string of length 21, string name "ShowRecentDiscussions", string value (here integer of value 1),
    string of length 23, string name "AUDIOSCROBBLER_USERNAME", string value (here string of length 8, value "msephton"),
    string of length 19, string name "ShowLargeCommentBox", string value (here integer of value 1),
  • well then, what you do i, and here is some pseudo code; for each user, recreate array from string, chek if NotifyOnNewWhisper is set to 1, if not set it to 1 or make it if not present. recreate string from array and repost it.
  • MarkMark Vanilla Staff
    edited April 2007
    Here's the meat of how you'd go about changing a user preference for all users.

    // Select all users and their preferences from the db $s = $Context->ObjectFactory->NewContextObject($Context, 'SqlBuilder'); $s->SetMainTable('User', 'u'); $s->AddSelect(array('UserID', 'Preferences'), 'u'); $ResultSet = $Context->Database->Select($s, 'YourAddOnName', 'SetPreferenceMethodName', 'An error occurred while retrieving user information.'); while ($Row = $Context->Database->GetRow($ResultSet)) { $CurrentUserID = ForceInt($Row['UserID'], 0); $SerializedPreferences = ForceString($Row['Preferences'], ''); $Preferences = UnserializeAssociativeArray($SerializedPreferences); if ($UserID > 0 && is_array($Preferences)) { // $PreferenceToChange is the name of the preference you want to change. The $Switch value can be 1 or 0. $Preferences[$PreferenceToChange] = $Switch; // Now reserialize and save to the db. $SerializedPreferences = SerializeArray($Preferences); $s->Clear(); $s->SetMainTable('User', 'u'); $s->AddFieldNameValue('Preferences', $SerializedPreferences); $s->AddWhere('u', 'UserID', '', $CurrentUserID, '='); $Context->Database->Update($s, 'YourAddOnName', 'SetPreferenceMethodName', 'An error occurred while manipulating user preferences.'); } }


    Keep in mind that your extension should pay very close attention to who is allowed to perform this change. You might want to create and add a new role permission.
  • these Table aliases like u, t, cb etc
    are they listed somewhere, or i can pick one by myself
  • edited April 2007
    They are defined in the table properties: $s->SetMainTable('User', 'u');, this associates 'u' with the User table. You could set whatever you like as the aliases.
  • MarkMark Vanilla Staff
    edited April 2007
    This declares "u" as the alias for the user table (I chose u because it's short and sweet)$s->SetMainTable('User', 'u');
    This references the user table by the "u" alias and pulls any columns from that table - in this case UserID and Preferences.$s->AddSelect(array('UserID', 'Preferences'), 'u');
  • mattmatt ✭✭
    I might take a crack at making this extension, unless somebody else has already started?

    It'd be my first extension.
  • mattmatt ✭✭
    I've got something working! I'll try to pretty it up and post it shortly.

    Constructive criticism very welcome!
  • edited April 2007
    @emf thanks for the explanation.
    I'm checking out ur extension cause i need similar functionality

    I want to save two parameters in the database in the Discussion Table. one param is a bool, another is a url
    1) Create 2 columns for both parameters
    2) One column but use comma separated fields (Param1,Parm2)
    3) One column and use Serialize and UnSerialize array

    this column will be checked for every single discussion list. So speed is important. Which of the above options is better.
  • mattmatt ✭✭
    If you're changing a table then either way is as messy.

    Serialization is used to avoid changing the db tables.
  • mattmatt ✭✭
    edited April 2007
    I'm not sure why you're bumping this thread?

    It's worth starting your own topic as you'll stand a better chance of getting your question answered. Or you could try all three of your proposed methods and see which is fastest?
This discussion has been closed.