PDA

View Full Version : Opt-Out


TalkVirginia
03-09-2010, 12:57 PM
Can anyone tell me what the best way would be to set up a custom "opt-out" feature, say from a newsletter or mailing list?

I wanted to include a link in an email that would pass in maybe their email address and maybe userid, but I'm also thinking about security and using captcha.

Lynne
03-09-2010, 02:54 PM
Why not a User Profile Field in their User CP?

TalkVirginia
03-09-2010, 09:58 PM
Why not a User Profile Field in their User CP?

I was thinking about that but I'm not sure how to check to it in the database.

donottumbledry
03-14-2010, 01:32 PM
You can search in custom fields in the User manager in ACP. Even using the Generate Mailing list option has the same search features so you would just ensure to check the right boxes before clicking the generate list button.

Zachery
03-14-2010, 01:35 PM
Isn't there already an option to not recieve emails from administrators?

donottumbledry
03-14-2010, 01:37 PM
Yes there is but I think this only works for Admin emails such as registration signing etc. On our forum we have found it much more useful as per the OP to have a separate user field that is hidden from public view that Admin can use to generate mailing lists. Works a treat using the search method I outlined above :)

TalkVirginia
03-16-2010, 11:22 PM
Here's what I got so far:

I have a custom field set up in the usercp under General Settings as shown in the attached image.

I was planning to have a field in my mod configuration screen where the field name of the custom user field would go so I know where to pull info from.

Then on the sent email I was planning to include an unsubscribe url like:


mydomain.com/reminderemails.php?do=unsubscribe&email=johnsmith@somedomain.com


I wanted to set a field in the vb_user table to indicate they unregistered but then I realized I also needed to programmatically change the value in the userfields table so the custom field value in the usercp would reflect the optout.

I saw in the profile.php script where the set_userfields method in the userdata object to set the custom fields like so:



// custom profile fields
$userdata->set_userfields($vbulletin->GPC['userfield']);



I also googled set_userfields and found in the vb.org archives that I should be able to use this method to set a specific custom field:



// change ## to the number of the custom field,
// and fieldvalue to the value you want

$fieldvariable = array('field##' => "fieldvalue");
$userdata->set_userfields($fieldvariable, true, 'admin');



I'm not sure what the other parameters do though. I guess my question is does this sound like a viable solution or would there be a better way? Is there any way to use numeric values for the data in the table? The drawback to using a custom field is that I don't have any control of it programmatically. If there was a template hook where I could insert a custom template at the end of the General Settings template using a plugin that might work.

Sorry if I'm rambling... just trying to provide as much information as I can. :)

Anyone got any thoughts on this?

donottumbledry
03-17-2010, 01:18 PM
// custom profile fields
$userdata->set_userfields($vbulletin->GPC['userfield']);



I also googled set_userfields and found in the vb.org archives that I should be able to use this method to set a specific custom field:



// change ## to the number of the custom field,
// and fieldvalue to the value you want

$fieldvariable = array('field##' => "fieldvalue");
$userdata->set_userfields($fieldvariable, true, 'admin');




The only problem I see with the above method is that the function does not know which user it is altering. I'm thinking that the $userdata class is pre-populated with user information bases on who's logged in. So the scripts populate $userdata/$vbulletin etc classes etc each time a script(page) is called. This information will be lost though when trying to act upon an email link.

I think what you would require is to explicitly require the userid of the person in the email link, something along the lines of :

http://mydomain.com/unsubscribe_email.php?u=1&e=email@somwhere.com&s=securitycheck

Where u would be asigned their userid which I think is available when generating emails via the ACP. I would then include e= to input their email as you have done to double-check that the userid and the email address match before you unsubscribe them. The third option is up to you but I would include s which is some sort of checksum or security key. Perhaps based upon an encoded version of their userid and email combined or something. This ought to make sure that the request is genuine.

Inside your unsubscribe_emai.php file after you've validated everything you would then have to execute a MySQL query to perform the action you require. Unfortunately I do not know the phrasing of this off the top of my head but based on something I was doing the other day it would look something like:



$vbulletin->db->query =
(" UPDATE " .TABLE_PREFIX. "profilefield SET field## VALUES NULL WHERE userid = $_GET['u'] LIMIT 1");




Please note the phrase $vbulletin->db->query is me just guessing! I do not know the exact function in the db class to write to the tables off the top of my head. Plus, you'll have to have a peak inside your database as to the exact table name and, of course, the correct field name. I hope though it gives you the idea that you need to accomplish your goal. :)

TalkVirginia
03-21-2010, 04:07 PM
Ok... I've taken a different approache to this and I'm so close I can taste it. lol However, I need some help from some experts on vb bitfields and how to update them both for the user and in the database. I've been studying the information on the following article:

Add Multiple Options Per User (via Bitfields) (https://vborg.vbsupport.ru/showthread.php?t=116155&highlight=options)

I've created an custom option bitfield in the vb_user table called 'inactiveuseroptions'.

I have a bitfield_remindermail.xml file in the /includes/xml folder that looks like this:



<?xml version="1.0" encoding="ISO-8859-1"?>
<bitfields product="dbmk_reminderemail">
<bitfielddefs>
<group name="misc">
<group name="inactiveuseroptions">
<bitfield name="receivereminderemail">1</bitfield>
</group>
</group>
</bitfielddefs>
</bitfields>



I've created the following custom template in the master template:



<div class="blockrow"><label for="cb_reminders">Inactivity Emails:</label>
<ul class="checkradio group rightcol">
<li><label for="cb_receivereminderemail"><input type="checkbox" name="inactiveuseroptions[receivereminderemail]" value="1" id="cb_receivereminderemail" tabindex="1" {vb:raw checked.receivereminderemail} />{vb:rawphrase receive_inactivity_reminder_email}</label><input type="hidden" name="set_options[receivereminderemail]" value="1" /></li>
</ul>
<p class="description">From time to time, the administrators and/or other members may want to send you email notifications or messages. If you do not want to receive email from certain people then you may disable the options here</p>
</div>



Which looks like this:

http://www.talkvirginia.net/images/screenshots/3-21-2010 12-17-02 PM.png

I've got 4 plugins as follows:

Profile start:
This renders the custom template using the "usercp_options_other" template hook


$checked = array();
if ($userinfo['receivereminderemail'])
{
$checked['receivereminderemail'] = "checked=\"checked\"";
}
$templater = vB_Template::create('inactivity_reminder_optout');
$templater->register('checked', $checked);
$template_hook[usercp_options_other] .= $templater->render();



Fetch_UserInfo:



if (isset($vbulletin->bf_misc_inactiveuseroptions))
{
foreach ($vbulletin->bf_misc[inactiveuseroptions] AS $optionname => $optionval)
{
$user["$optionname"] = ($user['inactiveuseroptions'] & $optionval ? 1 : 0);
}
}



UserData_Start:


if (isset($this->registry->bf_misc_inactiveuseroptions))
{
$this->bitfields['inactiveuseroptions'] =& $this->registry->bf_misc_inactiveuseroptions['receivereminderemail'];
}



Profile_UpdateOptions:


if (isset($vbulletin->bf_misc_inactiveuseroptions))
{
$vbulletin->input->clean_gpc('p', 'inactiveuseroptions', TYPE_ARRAY_BOOL);
foreach ($vbulletin->bf_misc[inactiveuseroptions] AS $key => $val)
{
if (isset($vbulletin->GPC['inactiveuseroptions']["$key"]) OR isset($vbulletin->GPC['set_options']["$key"]))
{
$userdata->set_bitfield('inactiveuseroptions', $key, $vbulletin->GPC['inactiveuseroptions']["$key"]);
}
}
}



Basically wants happening is I can set the bitfield in the datbase 1 time, by either checking the checkbox but I can't get the check box to reload if it option has been turned on. If the option it turned on in the user data but off in the database I can't get the check box to turn off.

Are there any knowledgable vb developers out there that can point me in the right direction? Thanks If you have questions or need more info.

--------------- Added 1269219911 at 1269219911 ---------------

Oh my!! I think I figured it out!! lol :D

benstillman
10-13-2010, 06:11 PM
For vB4.0: https://vborg.vbsupport.ru/showthread.php?t=246163

For vB3.8: https://vborg.vbsupport.ru/showthread.php?t=240512

These simply set the "receive admin emails" to no. Then when you send out your newsletter, you don't include users who have it set to no. Easy as pie.