MU Affiliate work – Adding MLM aspect to affiliate program

Affiliate Multi level tree totals
Affiliate report area

Made several minor tweak to enable a virtually unlimited size down line /  commission system

Added tree view. This will display grand totals of all the members that are in your down line.

In the admin area I added a option to set the amount of levels to pay on.

From there this menu will generate the appropriate amount of boxes that can be used to set the percentage to be paid on each level.

2 Levels Deep

Then 9 levels deep

Supporter with 9 levels of commission

In order to store the data efficiently I created this table.


— Table structure for table `wp_affiliate_tree`

CREATE TABLE `wp_affiliate_tree` (
`user_id` bigint(20) NOT NULL,
`ref_user_id` bigint(20) NOT NULL,
`lvl` mediumint(6) NOT NULL,
PRIMARY KEY  (`user_id`,`ref_user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT=’affiliate support tree’;

Upon a user activation I added a hook to build the new users full tree.

This function activates the new user as a affiliate and builds there tree

function initial_register_affiliate($user_id, $password, $met){
$user_info=get_userdata($user_id);
$reference = $user_info->user_login. ‘-‘ . strrev(sprintf(‘%02d’, $user_id + 35));
update_usermeta($user_id, ‘enable_affiliate’, ‘yes’);
update_usermeta($user_id, ‘affiliate_reference’, $reference);
update_usermeta($user_id, ‘affiliate_hash’, ‘aff’ . md5(AUTH_SALT . $reference));
$refer_user_id=$user_info->affiliate_referrer;
// If referred by another user_id then build upline tree
if($refer_user_id){

global $wpdb;
$sql = $wpdb->prepare( “INSERT IGNORE INTO “.$wpdb->base_prefix.”affiliate_tree (user_id, ref_user_id, lvl) VALUES (%d, %d, 1)”, $user_id,$refer_user_id );
$queryresult = $wpdb->query($sql);

$sql = $wpdb->prepare( “INSERT IGNORE INTO  “.$wpdb->base_prefix.”affiliate_tree (user_id, ref_user_id, lvl)
SELECT %d, ref_user_id, lvl+1 FROM “.$wpdb->base_prefix.”affiliate_tree WHERE  user_id=%d”, $user_id, $refer_user_id );
$queryresult = $wpdb->query($sql);
}
}

From there I tweaked the supporter-amazon.php and paypal file as there was  a bug that was causing the affiliate payment process not to load.

Also on the affiliate program  there were some other random fixes. I worked the code regarding a user showing up on a user page without a referralid.

It now cross references the blog that they landed on with adminstrator of the blog. It uses that data to set the cookie.

There was a problem with the cookie being set by the ‘ref’ get query.. However at that point in the code it was not defined.

if(defined(‘AFFILIATE_CHECKALL’)) {
// We are here if there isn’t a reference passed, so we need to check the referrer.
if(!isset( $_COOKIE[‘affiliate_’ . COOKIEHASH]) && isset($_SERVER[‘HTTP_REFERER’])) {
// We haven’t already been referred here by someone else – note only the first referrer
// within a time period gets the cookie.
$referrer = parse_url($_SERVER[‘HTTP_REFERER’], PHP_URL_HOST);
global $wpdb;

// Check if the user is a valid referrer
//$affiliate = $this->db->get_var( $this->db->prepare( “SELECT user_id FROM {$this->db->usermeta} WHERE meta_key = ‘affiliate_referrer’ AND meta_value=’%s'”, $referrer) );
$affiliate = $this->db->get_var( $this->db->prepare( “SELECT b.user_id FROM ” . $wpdb->base_prefix . “blogs a,  ” . $wpdb->base_prefix . “bp_user_blogs b WHERE  a.blog_id=b.blog_id AND a.domain=’%s’ LIMIT 1”, $referrer) );

// Check for mapped domain.
if(!$affiliate){
$affiliate = $this->db->get_var( $this->db->prepare( “SELECT b.user_id FROM ” . $wpdb->base_prefix . “domain_mapping a,  ” . $wpdb->base_prefix . “bp_user_blogs b WHERE  a.blog_id=b.blog_id AND a.domain=’%s’ LIMIT 1”, $referrer) );
}

if($affiliate) {
$_GET[‘ref’]=$this->db->get_var( $this->db->prepare( “SELECT meta_value FROM {$this->db->usermeta} WHERE meta_key = ‘affiliate_reference’ AND user_id=’%s'”, $affiliate) );
// Update a quick count for this month
do_action( ‘affiliate_click’, $affiliate);
// Store the referrer
do_action( ‘affiliate_referrer’, $affiliate, $referrer );

// Write the affiliate hash out – valid for 30 days.
@setcookie(‘affiliate_’ . COOKIEHASH, ‘aff’ . md5(AUTH_SALT . $_GET[‘ref’]), (time() + (60*60*24*30)), COOKIEPATH, COOKIE_DOMAIN);
} else {
if(defined(‘AFFILIATE_SETNOCOOKIE’)) @setcookie(‘noaffiliate_’ . COOKIEHASH, ‘notanaff’, 0, COOKIEPATH, COOKIE_DOMAIN);
}
}
}

Using Feedback Loops Effectively

Getting email delivered has become an overtly complex job.  As large email service providers generate more restrictive spam filters and email blocking technologies, it is vital to any email marketer to stay on top of recipient’s feedback.  One crucial tool that the largest email service providers employ is Feedback Loops.  Deploying the use of feedback loops effectively will help reduce spam complaints, identify active users, and improve deliverability.

In order to create value from feedback loops, recipient identity, message identity, and server identity must link to the feedback report.  This poses a problem as providers redact a recipient’s contact information, and in many circumstances corrupt the body content of the message before sending a report.  To get around this hurdle, insert a separate recipient identifier tag into all messages sent.  Test the tag by embedding it in the body of the email, then sending it through major email providers to ensure that the tag maintained its integrity while in transit.  Once a working tag is in place, a program could parse through your feedback reports, extract the identity tag, and insert the tag information into a database with a timestamp to derive further data later.

It is important to recognize that just because an end user activated a feedback report, this does not necessarily mean the report should be treated as an unsubscribe request.  In fact, typically, users that click the “report spam” button are generally your most active recipients; they are opening, reading, and clicking your content.  These users are taking action, albeit that action is a complaint; that action is just a report stating the recipient did not want the message.  Using this report identifies the user and the message you sent them.  Take steps to ensure the recipient does not receive that category or type of mailing again; change the frequency in which you mail the recipient, and then mark that user as an active recipient.  After adjusting the mail to that recipient, it would be possible to conclude either of the following:  they initiated another report and they do not want the mail, or they got the mail and it was something that sparked their interest.  Regardless, it is possible to generate demographical data by looking at the email content to see what topics the recipient shows interest or lack thereof.  Store the demographical data and then use it to target mailing more effectively in the future.

Beyond identifying active users through a feedback loop, it is important to get recipients that clearly do not want mail off the distribution list.  A repeated complaint from the same user flags a mailer as a spammer.  This can cause a message to deliver directly into a bulk folder, or even worse, cause delivery to fail all together.  Avoid this situation by unsubscribing the user from future mailings, after receiving several reports from this recipient in a short amount time.

Mail providers use many complex algorithms to filter email.  The largest and most sophisticated networks monitor sender reputation using the following elements:  past mail volume, current mail volume, complaint rates, bounce rates.  By identifying active recipients and sending them offers they prefer to receive, complaints per volume sent drops; this results in better delivery rates.  On the other hand, removing repeat complainers will also cause the complaint rate to drop.

Email delivery is a headache for email service providers, marketers, end users and most likely, everyone in between.  There are many ways to improve deliverability.  Breaking this down to the simplest of terms “do not send people email they don’t want”; feedback loops offer a valuable tool to accomplish that goal.  Implementing them effectively will improve user response, delivery rates, and most importantly, a profit margin.

Theme Roller quick and easy jquery tab navigation

I thought I would pass it on to you guys. It involves the use of a javascript library called Jquery. The tool will let you build a theme for your site. This includes color layouts, toolbars, navigation elements, tool tips, etc.. http://jqueryui.com/themeroller/ Once you design the layout it will let you download your custom .css layout I have only had a little while to play with it.

But here is a link to a page with a navigation bar installed on it.

http://dev.contacker.com/dev_tabbed.html

The effect is the navigation bar that is loading its contents from other html pages when you click on the tab.

The elements creating this effect in the html is as follows.

Include in your header to include the stylesheet and jquery elements.

<link type="text/css" href="css/ui-lightness/jquery-ui-1.8.1.custom.css" rel="stylesheet" />
<link href="css/default.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="javascript/jquery.js"></script>
<script type="text/javascript" src="javascript/jquery-ui-1.8.1.custom.min.js"></script>
<script type="text/javascript" src="javascript/jquery.corner.js"></script>
<script type="text/javascript" src="javascript/jquery.dimensions.js"></script>

Include in your header to activate the jquery tabs effect

<script type="text/javascript">
$(function() {
$("#tabs").tabs({ remote: true });
});

</script>

HTML code for the tabs

<div id="tabs">
<l>
<li><a href="content_elements/contact.html" title="contact"><span>contact</span></a></li>
<li><a href="content_elements/blog.html" title="blog"><span>blog</span></a></li>
<li><a href="content_elements/register.html" title="register"><span>register</span></a></li>
</ul>

</div>

Note when you actually click on the links above jquery loads the external page under the tab. This can allow you to build navigation menus that do not require the page to be load just the single element that is changing.

There is of course a ton of different ways to do the same thing but this one was pretty quick and hardly any code..

Why accessibility guidelines are important.

Following accessibility guidelines are important for a bunch of reasons. By following the guide lines you save yourself a bunch of time in debugging sites on various browsers and different medium types.  I have found this to be extremely crucial coming from experience in having to relay out an entire older website to confirm with new HTML and CSS standards it can be a very tedious / nightmare of a job. It seems like the majority of accessibility guidelines can be achieved by properly separating your HTML layout from your cascading style sheets.

I have not done too many sites that need to be accessible by blind people but adding title tags and summaries to tables seem simple enough. You just need to be mindful of your audience and your guidelines for the project. Separating your layout from your styles can save make your code easier to read and easier to update. Not to mention you can totally change the looks and feel of your site by simply enabling a alternate style sheet, this can save you a absolute ton of time. One media scenario I have spent some time on it the print ability of web pages. It seems like very few website can be printed out and the printout actually looks like what you have the screen, or even is understandable at all for that matter. Here is an example below I used for my portfolio page so that it can be printed and actually look decent.

Example Alternate Style sheet

Here is a example of including an alternate style sheet just for printing purposes.  By added the tag (media=”print”) when you attempt to print the page it will load the alternate style sheet. I do this to remove navigation and other items that take up too much real estate when you are printing.

HTML Source

<link rel="stylesheet" type="text/css" href="css/main_layout.css" />
<link rel="stylesheet" media="print" type="text/css" href="css/main_layout_print.css" />

CSS Source

/* Normal Nav View */
div#nav {
float: right;
color: white;
margin-top: -.7em;
}
/* Print Nav View */
div#nav {
display: none;
float: right;
color: white;
margin-top: -.7em;
}

For this example the navigation bar on the printed version of the page will not be displayed allowing more room for your actual content to be printed.

to see the effect live you can check out
http://portfolio.totallyworthless.com/course_outcome/cis_215.htm

Setup memcached 64 bit Centos 5.4

memcached is a great program for storing session data on load balanced servers. It is very fast and easy to setup.

install repository –
Then, under either version, create a file at /etc/yum.repos.d/dag.repo with these lines in it:
>>>
[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1
>>>
yum install memcached;