/**
 * Handle remove form submission.
 */
function affiliates_admin_affiliates_remove_submit()
{
    global $wpdb;
    $result = false;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_NONCE], 'affiliates-remove')) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $affiliate_id = isset($_POST['affiliate-id-field']) ? $_POST['affiliate-id-field'] : null;
    if ($affiliate_id) {
        $valid_affiliate = false;
        // do not mark the pseudo-affiliate as deleted: type != ...
        $check = $wpdb->prepare("SELECT affiliate_id FROM {$affiliates_table} WHERE affiliate_id = %d AND (type IS NULL OR type != '" . AFFILIATES_DIRECT_TYPE . "')", intval($affiliate_id));
        if ($wpdb->query($check)) {
            $valid_affiliate = true;
        }
        if ($valid_affiliate) {
            $result = false !== $wpdb->query($query = $wpdb->prepare("UPDATE {$affiliates_table} SET status = 'deleted' WHERE affiliate_id = %d", intval($affiliate_id)));
            do_action('affiliates_deleted_affiliate', intval($affiliate_id));
        }
    }
    return $result;
}
 /**
  * Renders the general settings section.
  */
 public static function section()
 {
     global $wp, $wpdb, $affiliates_options, $wp_roles;
     $robots_table = _affiliates_get_tablename('robots');
     if (isset($_POST['submit'])) {
         if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_SETTINGS_NONCE], 'admin')) {
             // robots
             $robots = wp_filter_nohtml_kses(trim($_POST['robots']));
             $wpdb->query("DELETE FROM {$robots_table};");
             if (!empty($robots)) {
                 $robots = str_replace(",", "\n", $robots);
                 $robots = str_replace("\r", "", $robots);
                 $robots = explode("\n", $robots);
                 foreach ($robots as $robot) {
                     $robot = trim($robot);
                     if (!empty($robot)) {
                         $query = $wpdb->prepare("INSERT INTO {$robots_table} (name) VALUES (%s);", $robot);
                         $wpdb->query($query);
                     }
                 }
             }
             $pname = !empty($_POST['pname']) ? trim($_POST['pname']) : get_option('aff_pname', AFFILIATES_PNAME);
             $forbidden_names = array();
             if (!empty($wp->public_query_vars)) {
                 $forbidden_names += $wp->public_query_vars;
             }
             if (!empty($wp->private_query_vars)) {
                 $forbidden_names += $wp->private_query_vars;
             }
             if (!empty($wp->extra_query_vars)) {
                 $forbidden_names += $wp->extra_query_vars;
             }
             if (!preg_match('/[a-z_]+/', $pname, $matches) || !isset($matches[0]) || $pname !== $matches[0]) {
                 $pname = get_option('aff_pname', AFFILIATES_PNAME);
                 echo '<div class="error">' . __('The Affiliate URL parameter name <strong>has not been changed</strong>, the suggested name <em>is not valid</em>. Only lower case letters and the underscore _ are allowed.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
             } else {
                 if (in_array($pname, $forbidden_names)) {
                     $pname = get_option('aff_pname', AFFILIATES_PNAME);
                     echo '<div class="error">' . __('The Affiliate URL parameter name <strong>has not been changed</strong>, the suggested name <em>is forbidden</em>.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                 }
             }
             $old_pname = get_option('aff_pname', AFFILIATES_PNAME);
             if ($pname !== $old_pname) {
                 update_option('aff_pname', $pname);
                 affiliates_update_rewrite_rules();
                 echo '<div class="info">' . '<p>' . sprintf(__('The Affiliate URL parameter name <strong>has been changed</strong> from <em><strong>%s</strong></em> to <em><strong>%s</strong></em>.', AFFILIATES_PLUGIN_DOMAIN), $old_pname, $pname) . '</p>' . '<p class="warning">' . __('If your affiliates are using affiliate links based on the previous Affiliate URL parameter name, they <strong>NEED</strong> to update their affiliate links.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<p class="warning">' . __('Unless the incoming affiliate links reflect the current Affiliate URL parameter name, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '</div>';
             }
             $redirect = !empty($_POST['redirect']);
             if ($redirect) {
                 if (get_option('aff_redirect', null) === null) {
                     add_option('aff_redirect', 'yes', '', 'no');
                 } else {
                     update_option('aff_redirect', 'yes');
                 }
             } else {
                 delete_option('aff_redirect');
             }
             $encoding_id = $_POST['id_encoding'];
             if (key_exists($encoding_id, affiliates_get_id_encodings())) {
                 // important: must use normal update_option/get_option otherwise we'd have a per-user encoding
                 update_option('aff_id_encoding', $encoding_id);
             }
             $rolenames = $wp_roles->get_names();
             $caps = array(AFFILIATES_ACCESS_AFFILIATES => __('Access affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_AFFILIATES => __('Administer affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_OPTIONS => __('Administer options', AFFILIATES_PLUGIN_DOMAIN));
             foreach ($rolenames as $rolekey => $rolename) {
                 $role = $wp_roles->get_role($rolekey);
                 foreach ($caps as $capkey => $capname) {
                     $role_cap_id = $rolekey . '-' . $capkey;
                     if (!empty($_POST[$role_cap_id])) {
                         $role->add_cap($capkey);
                     } else {
                         $role->remove_cap($capkey);
                     }
                 }
             }
             // prevent locking out
             _affiliates_assure_capabilities();
             if (!affiliates_is_sitewide_plugin()) {
                 delete_option('aff_delete_data');
                 add_option('aff_delete_data', !empty($_POST['delete-data']), '', 'no');
             }
             self::settings_saved_notice();
         }
     }
     $robots = '';
     $db_robots = $wpdb->get_results("SELECT name FROM {$robots_table}", OBJECT);
     foreach ($db_robots as $db_robot) {
         $robots .= $db_robot->name . "\n";
     }
     $pname = get_option('aff_pname', AFFILIATES_PNAME);
     $redirect = get_option('aff_redirect', false);
     $id_encoding = get_option('aff_id_encoding', AFFILIATES_NO_ID_ENCODING);
     $id_encoding_select = '';
     $encodings = affiliates_get_id_encodings();
     if (!empty($encodings)) {
         $id_encoding_select .= '<label class="id-encoding" for="id_encoding">' . __('Affiliate ID Encoding', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
         $id_encoding_select .= '<select class="id-encoding" name="id_encoding">';
         foreach ($encodings as $key => $value) {
             if ($id_encoding == $key) {
                 $selected = ' selected="selected" ';
             } else {
                 $selected = '';
             }
             $id_encoding_select .= '<option ' . $selected . ' value="' . esc_attr($key) . '">' . esc_attr($value) . '</option>';
         }
         $id_encoding_select .= '</select>';
     }
     $rolenames = $wp_roles->get_names();
     $caps = array(AFFILIATES_ACCESS_AFFILIATES => __('Access affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_AFFILIATES => __('Administer affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_OPTIONS => __('Administer options', AFFILIATES_PLUGIN_DOMAIN));
     $caps_table = '<table class="affiliates-permissions">';
     $caps_table .= '<thead>';
     $caps_table .= '<tr>';
     $caps_table .= '<td class="role">';
     $caps_table .= __('Role', AFFILIATES_PLUGIN_DOMAIN);
     $caps_table .= '</td>';
     foreach ($caps as $cap) {
         $caps_table .= '<td class="cap">';
         $caps_table .= $cap;
         $caps_table .= '</td>';
     }
     $caps_table .= '</tr>';
     $caps_table .= '</thead>';
     $caps_table .= '<tbody>';
     foreach ($rolenames as $rolekey => $rolename) {
         $role = $wp_roles->get_role($rolekey);
         $caps_table .= '<tr>';
         $caps_table .= '<td>';
         $caps_table .= translate_user_role($rolename);
         $caps_table .= '</td>';
         foreach ($caps as $capkey => $capname) {
             if ($role->has_cap($capkey)) {
                 $checked = ' checked="checked" ';
             } else {
                 $checked = '';
             }
             $caps_table .= '<td class="checkbox">';
             $role_cap_id = $rolekey . '-' . $capkey;
             $caps_table .= '<input type="checkbox" name="' . $role_cap_id . '" id="' . $role_cap_id . '" ' . $checked . '/>';
             $caps_table .= '</td>';
         }
         $caps_table .= '</tr>';
     }
     $caps_table .= '</tbody>';
     $caps_table .= '</table>';
     $delete_data = get_option('aff_delete_data', false);
     echo '<form action="" name="options" method="post">' . '<div>';
     echo '<h3>' . __('Affiliate URL parameter name', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<input class="pname" name="pname" type="text" value="' . esc_attr($pname) . '" />' . '</p>' . '<p>' . sprintf(__('The current Affiliate URL parameter name is: <b>%s</b>', AFFILIATES_PLUGIN_DOMAIN), $pname) . '</p>' . '<p>' . sprintf(__('The default Affiliate URL parameter name is <em>%s</em>.', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_PNAME) . '</p>' . '<p class="description warning">' . __('CAUTION: If you change this setting and have distributed affiliate links or permalinks, make sure that these are updated. Unless the incoming affiliate links reflect the current URL parameter name, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     echo '<h3>' . __('Redirection', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . sprintf('<input class="redirect" name="redirect" type="checkbox" %s/>', $redirect ? ' checked="checked" ' : '') . ' ' . __('Redirect', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('Redirect to destination without Affiliate URL parameter, after a hit on an affiliate link has been detected.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     echo '<h3>' . __('Affiliate ID encoding', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . $id_encoding_select . '</p>' . '<p>' . sprintf(__('The current encoding in effect is: <b>%s</b>', AFFILIATES_PLUGIN_DOMAIN), $encodings[$id_encoding]) . '</p>' . '<p class="description warning">' . __('CAUTION: If you change this setting and have distributed affiliate links or permalinks, make sure that these are updated. Unless the incoming affiliate links reflect the current encoding, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     echo '<h3>' . __('Permissions', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . __('Do not assign permissions to open access for affiliates here.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . __('This section is only intended to grant administrative access on affiliate management functions to privileged roles.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . $caps_table . '<p class="description">' . __('A minimum set of permissions will be preserved.', AFFILIATES_PLUGIN_DOMAIN) . '<br/>' . __('If you lock yourself out, please ask an administrator to help.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     echo '<h3>' . __('Robots', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<textarea id="robots" name="robots" rows="10" cols="45">' . wp_filter_nohtml_kses($robots) . '</textarea>' . '</p>' . '<p>' . __('Hits on affiliate links from these robots will be marked or not recorded. Put one entry on each line.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     if (!affiliates_is_sitewide_plugin()) {
         echo '<h3>' . __('Deactivation and data persistence', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="delete-data" type="checkbox" ' . ($delete_data ? 'checked="checked"' : '') . '/>' . ' ' . __('Delete all plugin data on deactivation', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description warning">' . __('CAUTION: If this option is active while the plugin is deactivated, ALL affiliate and referral data will be DELETED. If you want to retrieve data about your affiliates and their referrals and are going to deactivate the plugin, make sure to back up your data or do not enable this option. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
     }
     echo '<p>' . wp_nonce_field('admin', AFFILIATES_ADMIN_SETTINGS_NONCE, true, false) . '<input class="button button-primary" type="submit" name="submit" value="' . __('Save', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '</p>' . '</div>' . '</form>';
     affiliates_footer();
 }
function affiliates_admin_options()
{
    global $wp, $wpdb, $affiliates_options, $wp_roles;
    if (!current_user_can(AFFILIATES_ADMINISTER_OPTIONS)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $robots_table = _affiliates_get_tablename('robots');
    echo '<div>' . '<h2>' . __('Affiliates options', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>';
    $pages_generated_info = '';
    //
    // handle page generation form submission
    //
    if (isset($_POST['generate'])) {
        if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_OPTIONS_GEN_NONCE], 'admin')) {
            require_once AFFILIATES_CORE_LIB . '/class-affiliates-generator.php';
            $post_ids = Affiliates_Generator::setup_pages();
            foreach ($post_ids as $post_id) {
                $link = '<a href="' . get_permalink($post_id) . '" target="_blank">' . get_the_title($post_id) . '</a>';
                $pages_generated_info .= '<div class="info">' . __(sprintf('The %s page has been created.', $link), AFFILIATES_PLUGIN_DOMAIN) . '</div>';
            }
        }
    }
    //
    // handle options form submission
    //
    if (isset($_POST['submit'])) {
        if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_OPTIONS_NONCE], 'admin')) {
            // timeout
            $timeout = intval($_POST['timeout']);
            if ($timeout < 0) {
                $timeout = 0;
            }
            update_option('aff_cookie_timeout_days', $timeout);
            // robots
            $robots = wp_filter_nohtml_kses(trim($_POST['robots']));
            $wpdb->query("DELETE FROM {$robots_table};");
            if (!empty($robots)) {
                $robots = str_replace(",", "\n", $robots);
                $robots = str_replace("\r", "", $robots);
                $robots = explode("\n", $robots);
                foreach ($robots as $robot) {
                    $robot = trim($robot);
                    if (!empty($robot)) {
                        $query = $wpdb->prepare("INSERT INTO {$robots_table} (name) VALUES (%s);", $robot);
                        $wpdb->query($query);
                    }
                }
            }
            delete_option('aff_registration');
            add_option('aff_registration', !empty($_POST['registration']), '', 'no');
            delete_option('aff_notify_admin');
            add_option('aff_notify_admin', !empty($_POST['notify_admin']), '', 'no');
            $pname = !empty($_POST['pname']) ? trim($_POST['pname']) : get_option('aff_pname', AFFILIATES_PNAME);
            $forbidden_names = array();
            if (!empty($wp->public_query_vars)) {
                $forbidden_names += $wp->public_query_vars;
            }
            if (!empty($wp->private_query_vars)) {
                $forbidden_names += $wp->private_query_vars;
            }
            if (!empty($wp->extra_query_vars)) {
                $forbidden_names += $wp->extra_query_vars;
            }
            if (!preg_match('/[a-z_]+/', $pname, $matches) || !isset($matches[0]) || $pname !== $matches[0]) {
                $pname = get_option('aff_pname', AFFILIATES_PNAME);
                echo '<div class="error">' . __('The Affiliate URL parameter name <strong>has not been changed</strong>, the suggested name <em>is not valid</em>. Only lower case letters and the underscore _ are allowed.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
            } else {
                if (in_array($pname, $forbidden_names)) {
                    $pname = get_option('aff_pname', AFFILIATES_PNAME);
                    echo '<div class="error">' . __('The Affiliate URL parameter name <strong>has not been changed</strong>, the suggested name <em>is forbidden</em>.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                }
            }
            if ($pname !== get_option('aff_pname', AFFILIATES_PNAME)) {
                $old_pname = get_option('aff_pname', $pname);
                update_option('aff_pname', $pname);
                affiliates_update_rewrite_rules();
                echo '<div class="info">' . '<p>' . sprintf(__('The Affiliate URL parameter name <strong>has been changed</strong> from <em><strong>%s</strong></em> to <em><strong>%s</strong></em>.', AFFILIATES_PLUGIN_DOMAIN), $old_pname, $pname) . '</p>' . '<p class="warning">' . __('If your affiliates are using affiliate links based on the previous Affiliate URL parameter name, they <strong>NEED</strong> to update their affiliate links.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<p class="warning">' . __('Unless the incoming affiliate links reflect the current Affiliate URL parameter name, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '</div>';
            }
            $redirect = !empty($_POST['redirect']);
            if ($redirect) {
                if (get_option('aff_redirect', null) === null) {
                    add_option('aff_redirect', 'yes', '', 'no');
                } else {
                    update_option('aff_redirect', 'yes');
                }
            } else {
                delete_option('aff_redirect');
            }
            $encoding_id = $_POST['id_encoding'];
            if (key_exists($encoding_id, affiliates_get_id_encodings())) {
                // important: must use normal update_option/get_option otherwise we'd have a per-user encoding
                update_option('aff_id_encoding', $encoding_id);
            }
            $rolenames = $wp_roles->get_names();
            $caps = array(AFFILIATES_ACCESS_AFFILIATES => __('Access affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_AFFILIATES => __('Administer affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_OPTIONS => __('Administer options', AFFILIATES_PLUGIN_DOMAIN));
            foreach ($rolenames as $rolekey => $rolename) {
                $role = $wp_roles->get_role($rolekey);
                foreach ($caps as $capkey => $capname) {
                    $role_cap_id = $rolekey . '-' . $capkey;
                    if (!empty($_POST[$role_cap_id])) {
                        $role->add_cap($capkey);
                    } else {
                        $role->remove_cap($capkey);
                    }
                }
            }
            // prevent locking out
            _affiliates_assure_capabilities();
            if (!affiliates_is_sitewide_plugin()) {
                delete_option('aff_delete_data');
                add_option('aff_delete_data', !empty($_POST['delete-data']), '', 'no');
            }
            // direct referrals?
            delete_option('aff_use_direct');
            add_option('aff_use_direct', !empty($_POST['use-direct']), '', 'no');
            // default status
            if (!empty($_POST['status']) && Affiliates_Utility::verify_referral_status_transition($_POST['status'], $_POST['status'])) {
                update_option('aff_default_referral_status', $_POST['status']);
            } else {
                update_option('aff_default_referral_status', AFFILIATES_REFERRAL_STATUS_ACCEPTED);
            }
            // allow duplicates?
            delete_option('aff_duplicates');
            add_option('aff_duplicates', !empty($_POST['duplicates']), '', 'no');
        }
    }
    $use_direct = get_option('aff_use_direct', true);
    $duplicates = get_option('aff_duplicates', false);
    $timeout = get_option('aff_cookie_timeout_days', AFFILIATES_COOKIE_TIMEOUT_DAYS);
    $default_status = get_option('aff_default_referral_status', AFFILIATES_REFERRAL_STATUS_ACCEPTED);
    $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
    $status_select = "<select name='status'>";
    foreach ($status_descriptions as $status_key => $status_value) {
        if ($status_key == $default_status) {
            $selected = "selected='selected'";
        } else {
            $selected = "";
        }
        $status_select .= "<option value='{$status_key}' {$selected}>{$status_value}</option>";
    }
    $status_select .= "</select>";
    $robots = '';
    $db_robots = $wpdb->get_results("SELECT name FROM {$robots_table}", OBJECT);
    foreach ($db_robots as $db_robot) {
        $robots .= $db_robot->name . "\n";
    }
    $registration = get_option('aff_registration', get_option('users_can_register', false));
    $notify_admin = get_option('aff_notify_admin', get_option('aff_notify_admin', true));
    $pname = get_option('aff_pname', AFFILIATES_PNAME);
    $redirect = get_option('aff_redirect', false);
    $id_encoding = get_option('aff_id_encoding', AFFILIATES_NO_ID_ENCODING);
    $id_encoding_select = '';
    $encodings = affiliates_get_id_encodings();
    if (!empty($encodings)) {
        $id_encoding_select .= '<label class="id-encoding" for="id_encoding">' . __('Affiliate ID Encoding', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
        $id_encoding_select .= '<select class="id-encoding" name="id_encoding">';
        foreach ($encodings as $key => $value) {
            if ($id_encoding == $key) {
                $selected = ' selected="selected" ';
            } else {
                $selected = '';
            }
            $id_encoding_select .= '<option ' . $selected . ' value="' . esc_attr($key) . '">' . esc_attr($value) . '</option>';
        }
        $id_encoding_select .= '</select>';
    }
    $rolenames = $wp_roles->get_names();
    $caps = array(AFFILIATES_ACCESS_AFFILIATES => __('Access affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_AFFILIATES => __('Administer affiliates', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_ADMINISTER_OPTIONS => __('Administer options', AFFILIATES_PLUGIN_DOMAIN));
    $caps_table = '<table class="affiliates-permissions">';
    $caps_table .= '<thead>';
    $caps_table .= '<tr>';
    $caps_table .= '<td class="role">';
    $caps_table .= __('Role', AFFILIATES_PLUGIN_DOMAIN);
    $caps_table .= '</td>';
    foreach ($caps as $cap) {
        $caps_table .= '<td class="cap">';
        $caps_table .= $cap;
        $caps_table .= '</td>';
    }
    $caps_table .= '</tr>';
    $caps_table .= '</thead>';
    $caps_table .= '<tbody>';
    foreach ($rolenames as $rolekey => $rolename) {
        $role = $wp_roles->get_role($rolekey);
        $caps_table .= '<tr>';
        $caps_table .= '<td>';
        $caps_table .= translate_user_role($rolename);
        $caps_table .= '</td>';
        foreach ($caps as $capkey => $capname) {
            if ($role->has_cap($capkey)) {
                $checked = ' checked="checked" ';
            } else {
                $checked = '';
            }
            $caps_table .= '<td class="checkbox">';
            $role_cap_id = $rolekey . '-' . $capkey;
            $caps_table .= '<input type="checkbox" name="' . $role_cap_id . '" id="' . $role_cap_id . '" ' . $checked . '/>';
            $caps_table .= '</td>';
        }
        $caps_table .= '</tr>';
    }
    $caps_table .= '</tbody>';
    $caps_table .= '</table>';
    $delete_data = get_option('aff_delete_data', false);
    //
    // Generator form
    //
    echo '<form action="" name="options" method="post">' . '<div>' . '<h3>' . __('Page generation', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . __('Press the button to generate an affiliate area.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="generate button" name="generate" type="submit" value="' . __('Generate', AFFILIATES_PLUGIN_DOMAIN) . '" />' . wp_nonce_field('admin', AFFILIATES_ADMIN_OPTIONS_GEN_NONCE, true, false) . '</p>' . $pages_generated_info . '</div>' . '</form>';
    //
    // print the options form
    //
    echo '<form action="" name="options" method="post">' . '<div>' . '<h3>' . __('Referral timeout', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input class="timeout" name="timeout" type="text" value="' . esc_attr(intval($timeout)) . '" />' . ' ' . __('Days', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('This is the number of days since a visitor accessed your site via an affiliate link, for which a suggested referral will be valid.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<p>' . __('If you enter 0, referrals will only be valid until the visitor closes the browser (session).', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<p>' . __('The default value is 1. In this case, if a visitor comes to your site via an affiliate link, a suggested referral will be valid until one day after she or he clicked that affiliate link.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Direct referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="use-direct" type="checkbox" ' . ($use_direct ? 'checked="checked"' : '') . '/>' . ' ' . __('Store direct referrals', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('If this option is enabled, whenever a referral is suggested and no affiliate is attributable to it, the referral will be attributed to Direct.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Default referral status', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . $status_select . '</p>' . '<h3>' . __('Duplicate referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="duplicates" type="checkbox" ' . ($duplicates ? 'checked="checked"' : '') . '/>' . ' ' . __('Allow duplicate referrals', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('Allow to record duplicate referrals for the same affiliate (based on amount, currency, internal type and reference).', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Robots', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<textarea id="robots" name="robots" rows="10" cols="45">' . wp_filter_nohtml_kses($robots) . '</textarea>' . '</p>' . '<p>' . __('Hits on affiliate links from these robots will be marked or not recorded. Put one entry on each line.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Affiliate registration', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="registration" type="checkbox" ' . ($registration ? 'checked="checked"' : '') . '/>' . ' ' . __('Allow affiliate registration', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p>' . '<label>' . '<input name="notify_admin" type="checkbox" ' . ($notify_admin ? 'checked="checked"' : '') . '/>' . ' ' . __('Notify the site admin when a new affiliate is registered', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<h3>' . __('Affiliate URL parameter name', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<input class="pname" name="pname" type="text" value="' . esc_attr($pname) . '" />' . '</p>' . '<p>' . sprintf(__('The current Affiliate URL parameter name is: <b>%s</b>', AFFILIATES_PLUGIN_DOMAIN), $pname) . '</p>' . '<p>' . sprintf(__('The default Affiliate URL parameter name is <em>%s</em>.', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_PNAME) . '</p>' . '<p class="description warning">' . __('CAUTION: If you change this setting and have distributed affiliate links or permalinks, make sure that these are updated. Unless the incoming affiliate links reflect the current URL parameter name, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Redirection', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . sprintf('<input class="redirect" name="redirect" type="checkbox" %s/>', $redirect ? ' checked="checked" ' : '') . ' ' . __('Redirect', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('Redirect to destination without Affiliate URL parameter, after a hit on an affiliate link has been detected.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Affiliate ID encoding', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . $id_encoding_select . '</p>' . '<p>' . sprintf(__('The current encoding in effect is: <b>%s</b>', AFFILIATES_PLUGIN_DOMAIN), $encodings[$id_encoding]) . '</p>' . '<p class="description warning">' . __('CAUTION: If you change this setting and have distributed affiliate links or permalinks, make sure that these are updated. Unless the incoming affiliate links reflect the current encoding, no affiliate hits, visits or referrals will be recorded.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<h3>' . __('Permissions', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . $caps_table . '<p class="description">' . __('A minimum set of permissions will be preserved.', AFFILIATES_PLUGIN_DOMAIN) . '<br/>' . __('If you lock yourself out, please ask an administrator to help.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
    if (!affiliates_is_sitewide_plugin()) {
        echo '<h3>' . __('Deactivation and data persistence', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . '<input name="delete-data" type="checkbox" ' . ($delete_data ? 'checked="checked"' : '') . '/>' . ' ' . __('Delete all plugin data on deactivation', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description warning">' . __('CAUTION: If this option is active while the plugin is deactivated, ALL affiliate and referral data will be DELETED. If you want to retrieve data about your affiliates and their referrals and are going to deactivate the plugin, make sure to back up your data or do not enable this option. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
    }
    echo '<p>' . wp_nonce_field('admin', AFFILIATES_ADMIN_OPTIONS_NONCE, true, false) . '<input class="button" type="submit" name="submit" value="' . __('Save', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '</p>' . '</div>' . '</form>';
    affiliates_footer();
}
function affiliates_admin_hits()
{
    global $wpdb, $affiliates_options;
    $output = '';
    if (!current_user_can(AFFILIATES_ACCESS_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (isset($_POST['from_date']) || isset($_POST['thru_date']) || isset($_POST['clear_filters']) || isset($_POST['affiliate_id']) || isset($_POST['expanded']) || isset($_POST['expanded_hits']) || isset($_POST['expanded_referrals']) || isset($_POST['show_inoperative'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_FILTER_NONCE], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    // filters
    $from_date = $affiliates_options->get_option('hits_from_date', null);
    $thru_date = $affiliates_options->get_option('hits_thru_date', null);
    $affiliate_id = $affiliates_options->get_option('hits_affiliate_id', null);
    $expanded = $affiliates_options->get_option('hits_expanded', null);
    // @todo input ist not shown, eventually remove unless ...
    $expanded_referrals = $affiliates_options->get_option('hits_expanded_referrals', null);
    $expanded_hits = $affiliates_options->get_option('hits_expanded_hits', null);
    $show_inoperative = $affiliates_options->get_option('hits_show_inoperative', null);
    if (isset($_POST['clear_filters'])) {
        $affiliates_options->delete_option('hits_from_date');
        $affiliates_options->delete_option('hits_thru_date');
        $affiliates_options->delete_option('hits_affiliate_id');
        $affiliates_options->delete_option('hits_expanded');
        $affiliates_options->delete_option('hits_expanded_referrals');
        $affiliates_options->delete_option('hits_expanded_hits');
        $affiliates_options->delete_option('hits_show_inoperative');
        $from_date = null;
        $thru_date = null;
        $affiliate_id = null;
        $expanded = null;
        $expanded_hits = null;
        $expanded_referrals = null;
        $show_inoperative = null;
    } else {
        if (isset($_POST['submitted'])) {
            // filter by date(s)
            if (!empty($_POST['from_date'])) {
                $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                $affiliates_options->update_option('hits_from_date', $from_date);
            } else {
                $from_date = null;
                $affiliates_options->delete_option('hits_from_date');
            }
            if (!empty($_POST['thru_date'])) {
                $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                $affiliates_options->update_option('hits_thru_date', $thru_date);
            } else {
                $thru_date = null;
                $affiliates_options->delete_option('hits_thru_date');
            }
            if ($from_date && $thru_date) {
                if (strtotime($from_date) > strtotime($thru_date)) {
                    $thru_date = null;
                    $affiliates_options->delete_option('hits_thru_date');
                }
            }
            // filter by affiliate id
            if (!empty($_POST['affiliate_id'])) {
                $affiliate_id = affiliates_check_affiliate_id($_POST['affiliate_id']);
                if ($affiliate_id) {
                    $affiliates_options->update_option('hits_affiliate_id', $affiliate_id);
                }
            } else {
                if (isset($_POST['affiliate_id'])) {
                    // empty && isset => '' => all
                    $affiliate_id = null;
                    $affiliates_options->delete_option('hits_affiliate_id');
                }
            }
            // expanded details?
            if (!empty($_POST['expanded'])) {
                $expanded = true;
                $affiliates_options->update_option('hits_expanded', true);
            } else {
                $expanded = false;
                $affiliates_options->delete_option('hits_expanded');
            }
            if (!empty($_POST['expanded_hits'])) {
                $expanded_hits = true;
                $affiliates_options->update_option('hits_expanded_hits', true);
            } else {
                $expanded_hits = false;
                $affiliates_options->delete_option('hits_expanded_hits');
            }
            if (!empty($_POST['expanded_referrals'])) {
                $expanded_referrals = true;
                $affiliates_options->update_option('hits_expanded_referrals', true);
            } else {
                $expanded_referrals = false;
                $affiliates_options->delete_option('hits_expanded_referrals');
            }
            if (!empty($_POST['show_inoperative'])) {
                $show_inoperative = true;
                $affiliates_options->update_option('hits_show_inoperative', true);
            } else {
                $show_inoperative = false;
                $affiliates_options->delete_option('hits_show_inoperative');
            }
        }
    }
    if (isset($_POST['row_count'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_NONCE_1], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    if (isset($_POST['paged'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_NONCE_2], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('paged', $current_url);
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $referrals_table = _affiliates_get_tablename('referrals');
    $hits_table = _affiliates_get_tablename('hits');
    $output .= '<div>' . '<h1>' . __('Visits & Referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h1>' . '</div>';
    $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
    if ($row_count <= 0) {
        $row_count = $affiliates_options->get_option('affiliates_hits_per_page', AFFILIATES_HITS_PER_PAGE);
    } else {
        $affiliates_options->update_option('affiliates_hits_per_page', $row_count);
    }
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    if ($offset < 0) {
        $offset = 0;
    }
    $paged = isset($_REQUEST['paged']) ? intval($_REQUEST['paged']) : 0;
    if ($paged < 0) {
        $paged = 0;
    }
    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
    switch ($orderby) {
        case 'date':
        case 'visits':
        case 'hits':
        case 'referrals':
        case 'ratio':
            break;
        case 'affiliate_id':
            $orderby = 'name';
        default:
            $orderby = 'date';
    }
    $order = isset($_GET['order']) ? $_GET['order'] : null;
    switch ($order) {
        case 'asc':
        case 'ASC':
            $switch_order = 'DESC';
            break;
        case 'desc':
        case 'DESC':
            $switch_order = 'ASC';
            break;
        default:
            $order = 'DESC';
            $switch_order = 'ASC';
    }
    $filters = " WHERE 1=%d ";
    $filter_params = array(1);
    // We now have the desired dates from the user's point of view, i.e. in her timezone.
    // If supported, adjust the dates for the site's timezone:
    if ($from_date) {
        $from_datetime = DateHelper::u2s($from_date);
    }
    if ($thru_date) {
        $thru_datetime = DateHelper::u2s($thru_date, 24 * 3600);
    }
    if ($from_date && $thru_date) {
        $filters .= " AND datetime >= %s AND datetime < %s ";
        $filter_params[] = $from_datetime;
        $filter_params[] = $thru_datetime;
    } else {
        if ($from_date) {
            $filters .= " AND datetime >= %s ";
            $filter_params[] = $from_datetime;
        } else {
            if ($thru_date) {
                $filters .= " AND datetime < %s ";
                $filter_params[] = $thru_datetime;
            }
        }
    }
    if ($affiliate_id) {
        $filters .= " AND affiliate_id = %d ";
        $filter_params[] = $affiliate_id;
    }
    // how many are there ?
    $count_query = $wpdb->prepare("SELECT date FROM {$hits_table} h\n\t\t{$filters}\n\t\tGROUP BY date\n\t\t", $filter_params);
    $wpdb->query($count_query);
    $count = $wpdb->num_rows;
    if ($count > $row_count) {
        $paginate = true;
    } else {
        $paginate = false;
    }
    $pages = ceil($count / $row_count);
    if ($paged > $pages) {
        $paged = $pages;
    }
    if ($paged != 0) {
        $offset = ($paged - 1) * $row_count;
    }
    // Get the summarized results, these are grouped by date.
    // If there were any referral on a date without a hit, it would not be included:
    // Example conditions:
    // - 2011-02-01 23:59:59 hit recorded
    // - 2011-02-02 00:10:05 referral recorded
    // - no hits recorded on 2011-02-02
    // =>
    // - the referral will not show up
    // So, for ratio calculation, only the date with actual visits and referrals will show up.
    // Referrals on dates without visits would give an infinite ratio (x referrals / 0 visits).
    // We have a separate page which shows all referrals.
    $query = $wpdb->prepare("\n\t\tSELECT\n\t\t\t*,\n\t\t\tcount(distinct ip) visits,\n\t\t\tsum(count) hits,\n\t\t\t(select count(*) from {$referrals_table} where date(datetime) = h.date " . ($affiliate_id ? " AND affiliate_id = " . intval($affiliate_id) . " " : "") . ") referrals,\n\t\t\t((select count(*) from {$referrals_table} where date(datetime) = h.date " . ($affiliate_id ? " AND affiliate_id = " . intval($affiliate_id) . " " : "") . ")/count(distinct ip)) ratio\n\t\tFROM {$hits_table} h\n\t\t{$filters}\n\t\tGROUP BY date\n\t\tORDER BY {$orderby} {$order}\n\t\tLIMIT {$row_count} OFFSET {$offset}\n\t\t", $filter_params);
    $results = $wpdb->get_results($query, OBJECT);
    $column_display_names = array('date' => __('Date', AFFILIATES_PLUGIN_DOMAIN) . '*', 'visits' => __('Visits', AFFILIATES_PLUGIN_DOMAIN), 'hits' => __('Hits', AFFILIATES_PLUGIN_DOMAIN), 'referrals' => __('Referrals', AFFILIATES_PLUGIN_DOMAIN), 'ratio' => __('Ratio', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '<div id="" class="hits-overview">';
    $affiliates = affiliates_get_affiliates(true, !$show_inoperative);
    $affiliates_select = '';
    if (!empty($affiliates)) {
        $affiliates_select .= '<label class="affiliate-id-filter">';
        $affiliates_select .= __('Affiliate', AFFILIATES_PLUGIN_DOMAIN);
        $affiliates_select .= ' ';
        $affiliates_select .= '<select class="affiliate-id-filter" name="affiliate_id">';
        $affiliates_select .= '<option value="">--</option>';
        foreach ($affiliates as $affiliate) {
            if ($affiliate_id == $affiliate['affiliate_id']) {
                $selected = ' selected="selected" ';
            } else {
                $selected = '';
            }
            $affiliates_select .= '<option ' . $selected . ' value="' . esc_attr($affiliate['affiliate_id']) . '">' . esc_attr(stripslashes($affiliate['name'])) . '</option>';
        }
        $affiliates_select .= '</select>';
        $affiliates_select .= '</label>';
    }
    $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<div class="filter-section">' . $affiliates_select . '</div>' . '<div class="filter-section">' . '<label class="from-date-filter">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '</label>' . ' ' . '<label class="thru-date-filter">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="datefield thru-date-filter" name="thru_date" type="text" class="datefield" value="' . esc_attr($thru_date) . '"/>' . '</label>' . '</div>' . '<div class="filter-section">' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_referrals" type="checkbox" ' . ($expanded_referrals ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand referrals', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . ' ' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_hits" type="checkbox" ' . ($expanded_hits ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand hits', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . ' ' . '<label class="show-inoperative-filter">' . '<input class="show-inoperative-filter" name="show_inoperative" type="checkbox" ' . ($show_inoperative ? 'checked="checked"' : '') . '/>' . ' ' . __('Include inoperative affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</div>' . '<div class="filter-buttons">' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_FILTER_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</div>' . '</form>' . '</div>';
    $output .= '
		<div class="page-options">
			<form id="setrowcount" action="" method="post">
				<div>
					<label for="row_count">' . __('Results per page', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />
					' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_NONCE_1, true, false) . '
					<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>
				</div>
			</form>
		</div>
		';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<form id="posts-filter" method="post" action="">';
        $output .= '<div>';
        $output .= wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_NONCE_2, true, false);
        $output .= '</div>';
        $output .= '<div class="tablenav top">';
        $output .= $pagination->pagination('top');
        $output .= '</div>';
        $output .= '</form>';
    }
    $output .= '
		<table id="" class="wp-list-table widefat fixed" cellspacing="0">
		<thead>
			<tr>
			';
    foreach ($column_display_names as $key => $column_display_name) {
        $options = array('orderby' => $key, 'order' => $switch_order);
        $class = "";
        if (strcmp($key, $orderby) == 0) {
            $lorder = strtolower($order);
            $class = "{$key} manage-column sorted {$lorder}";
        } else {
            $class = "{$key} manage-column sortable";
        }
        $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
        $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
    }
    $output .= '</tr>
		</thead>
		<tbody>
		';
    if (count($results) > 0) {
        for ($i = 0; $i < count($results); $i++) {
            $result = $results[$i];
            $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
            $output .= "<td class='date'>{$result->date}</td>";
            //			$output .= '<td class="date">' . DateHelper::formatDate( DateHelper::s2u( $result->datetime ) ) . '</td>';
            $output .= "<td class='visits'>{$result->visits}</td>";
            $output .= "<td class='hits'>{$result->hits}</td>";
            $output .= "<td class='referrals'>{$result->referrals}</td>";
            $output .= "<td class='ratio'>{$result->ratio}</td>";
            $output .= '</tr>';
            if ($expanded || $expanded_referrals || $expanded_hits) {
                //
                // expanded : referrals ----------------------------------------
                //
                if ($expanded_referrals) {
                    $referrals_filters = " WHERE date(datetime) = %s ";
                    $referrals_filter_params = array($result->date);
                    if ($affiliate_id) {
                        $referrals_filters .= " AND r.affiliate_id = %d ";
                        $referrals_filter_params[] = $affiliate_id;
                    }
                    $referrals_orderby = "datetime {$order}";
                    $referrals_query = $wpdb->prepare("SELECT *\n\t\t\t\t\t\tFROM {$referrals_table} r\n\t\t\t\t\t\tLEFT JOIN {$affiliates_table} a ON r.affiliate_id = a.affiliate_id\n\t\t\t\t\t\t{$referrals_filters}\n\t\t\t\t\t\tORDER BY {$referrals_orderby}\n\t\t\t\t\t\t", $referrals_filter_params);
                    $referrals = $wpdb->get_results($referrals_query, OBJECT);
                    if (count($referrals) > 0) {
                        $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                        $output .= '<td colspan="5">';
                        $output .= '<div class="details-referrals">';
                        $output .= '<p class="description">' . __('Referrals', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
                        $output .= '
							<table id="details-referrals-' . esc_attr($result->date) . '" class="details-referrals" cellspacing="0">
							<thead>
							<tr>
							<th scope="col" class="datetime">' . __('Time', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							<th scope="col" class="post-id">' . __('Post', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							<th scope="col" class="affiliate-id">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							</tr>
							</thead>
							<tbody>
							';
                        foreach ($referrals as $referral) {
                            $output .= '<tr class="details-referrals ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                            //							$output .= "<td class='datetime'>$referral->datetime</td>";
                            $output .= '<td class="datetime">' . DateHelper::s2u($referral->datetime) . '</td>';
                            $link = get_permalink($referral->post_id);
                            $title = get_the_title($referral->post_id);
                            $output .= '<td class="post-id"><a href="' . esc_attr($link) . '" target="_blank">' . wp_filter_nohtml_kses($title) . '</a></td>';
                            $output .= "<td class='affiliate-id'>" . stripslashes(wp_filter_nohtml_kses($referral->name)) . "</td>";
                            $output .= '</tr>';
                        }
                        $output .= '</tbody></table>';
                        $output .= '</div>';
                        // .details-referrals
                        $output .= '</td></tr>';
                    }
                }
                // if $expanded_referrals
                //
                // expanded : hits ----------------------------------------
                //
                if ($expanded_hits) {
                    // get the detailed results for hits
                    $details_orderby = "date {$order}, time {$order}";
                    $details_filters = " WHERE h.date = %s ";
                    $details_filter_params = array($result->date);
                    if ($affiliate_id) {
                        $details_filters .= " AND h.affiliate_id = %d ";
                        $details_filter_params[] = $affiliate_id;
                    }
                    $details_query = $wpdb->prepare("SELECT *\n\t\t\t\t\t\tFROM {$hits_table} h\n\t\t\t\t\t\tLEFT JOIN {$affiliates_table} a ON h.affiliate_id = a.affiliate_id\n\t\t\t\t\t\t{$details_filters}\n\t\t\t\t\t\tORDER BY {$details_orderby}\n\t\t\t\t\t\t", $details_filter_params);
                    $hits = $wpdb->get_results($details_query, OBJECT);
                    $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                    $output .= '<td colspan="5">';
                    $output .= '<div class="details-hits">';
                    $output .= '<p class="description">' . __('Hits', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
                    $output .= '
						<table id="details-hits-' . esc_attr($result->date) . '" class="details-hits" cellspacing="0">
						<thead>
						<tr>
						<th scope="col" class="time">' . __('Time', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="ip">' . __('IP', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="affiliate-id">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						</tr>
						</thead>
						<tbody>
						';
                    foreach ($hits as $hit) {
                        $output .= '<tr class=" details ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                        //						$output .= "<td class='time'>$hit->time</td>";
                        $output .= '<td class="time">' . DateHelper::s2u($hit->datetime) . '</td>';
                        $output .= "<td class='ip'>" . long2ip($hit->ip) . "</td>";
                        $output .= "<td class='affiliate-id'>" . stripslashes(wp_filter_nohtml_kses($hit->name)) . "</td>";
                        $output .= '</tr>';
                    }
                    $output .= '</tbody></table>';
                    $output .= '</div>';
                    // .details-hits
                    $output .= '</td></tr>';
                }
                // if $expanded_hits
            }
            // expanded
        }
    } else {
        $output .= '<tr><td colspan="5">' . __('There are no results.', AFFILIATES_PLUGIN_DOMAIN) . '</td></tr>';
    }
    $output .= '</tbody>';
    $output .= '</table>';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<div class="tablenav bottom">';
        $output .= $pagination->pagination('bottom');
        $output .= '</div>';
    }
    $server_dtz = DateHelper::getServerDateTimeZone();
    $output .= '<p>' . sprintf(__("* Date is given for the server's time zone : %s, which has an offset of %s hours with respect to GMT.", AFFILIATES_PLUGIN_DOMAIN), $server_dtz->getName(), $server_dtz->getOffset(new DateTime()) / 3600.0) . '</p>';
    $output .= '</div>';
    // .visits-overview
    echo $output;
    affiliates_footer();
}
/**
 * Affiliate table and action handling.
 */
function affiliates_admin_affiliates()
{
    global $wpdb, $wp_rewrite, $affiliates_options;
    $output = '';
    $today = date('Y-m-d', time());
    $pname = get_option('aff_pname', AFFILIATES_PNAME);
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (!$wp_rewrite->using_permalinks()) {
        $output .= '<p class="warning">' . sprintf(__('Your site is not using pretty <a href="%s">permalinks</a>. You will only be able to use URL parameter based <span class="affiliate-link">affiliate links</span> but not pretty <span class="affiliate-permalink">affiliate permalinks</span>, unless you change your permalink settings.', AFFILIATES_PLUGIN_DOMAIN), get_admin_url(null, 'options-permalink.php')) . '</p>';
    }
    //
    // handle actions
    //
    if (isset($_POST['action'])) {
        //  handle action submit - do it
        switch ($_POST['action']) {
            case 'add':
                if (!affiliates_admin_affiliates_add_submit()) {
                    return affiliates_admin_affiliates_add();
                }
                break;
            case 'edit':
                if (!affiliates_admin_affiliates_edit_submit()) {
                    return affiliates_admin_affiliates_edit($_POST['affiliate-id-field']);
                }
                break;
            case 'remove':
                affiliates_admin_affiliates_remove_submit();
                break;
        }
    } else {
        if (isset($_GET['action'])) {
            // handle action request - show form
            switch ($_GET['action']) {
                case 'add':
                    return affiliates_admin_affiliates_add();
                    break;
                case 'edit':
                    if (isset($_GET['affiliate_id'])) {
                        return affiliates_admin_affiliates_edit($_GET['affiliate_id']);
                    }
                    break;
                case 'remove':
                    if (isset($_GET['affiliate_id'])) {
                        return affiliates_admin_affiliates_remove($_GET['affiliate_id']);
                    }
                    break;
            }
        }
    }
    //
    // affiliate table
    //
    if (isset($_POST['from_date']) || isset($_POST['thru_date']) || isset($_POST['clear_filters']) || isset($_POST['affiliate_id']) || isset($_POST['affiliate_name']) || isset($_POST['affiliates_email']) || isset($_POST['affiliate_user_login']) || isset($_POST['show_deleted']) || isset($_POST['show_inoperative'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_FILTER_NONCE], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    // filters
    $from_date = $affiliates_options->get_option('affiliates_from_date', null);
    $from_datetime = null;
    $thru_date = $affiliates_options->get_option('affiliates_thru_date', null);
    $thru_datetime = null;
    $affiliate_id = $affiliates_options->get_option('affiliates_affiliate_id', null);
    $affiliate_name = $affiliates_options->get_option('affiliates_affiliate_name', null);
    $affiliate_email = $affiliates_options->get_option('affiliates_affiliate_email', null);
    $affiliate_user_login = $affiliates_options->get_option('affiliates_affiliate_user_login', null);
    $show_deleted = $affiliates_options->get_option('affiliates_show_deleted', false);
    $show_inoperative = $affiliates_options->get_option('affiliates_show_inoperative', false);
    if (isset($_POST['clear_filters'])) {
        $affiliates_options->delete_option('affiliates_from_date');
        $affiliates_options->delete_option('affiliates_thru_date');
        $affiliates_options->delete_option('affiliates_affiliate_id');
        $affiliates_options->delete_option('affiliates_affiliate_name');
        $affiliates_options->delete_option('affiliates_affiliate_email');
        $affiliates_options->delete_option('affiliates_affiliate_user_login');
        $affiliates_options->delete_option('affiliates_show_deleted');
        $affiliates_options->delete_option('affiliates_show_inoperative');
        $from_date = null;
        $from_datetime = null;
        $thru_date = null;
        $thru_datetime = null;
        $affiliate_id = null;
        $affiliate_name = null;
        $affiliate_email = null;
        $affiliate_user_login = null;
        $show_deleted = false;
        $show_inoperative = false;
    } else {
        if (isset($_POST['submitted'])) {
            if (!empty($_POST['affiliate_name'])) {
                $affiliate_name = trim($_POST['affiliate_name']);
                if (strlen($affiliate_name) > 0) {
                    $affiliates_options->update_option('affiliates_affiliate_name', $affiliate_name);
                } else {
                    $affiliate_name = null;
                    $affiliates_options->delete_option('affiliates_affiliate_name');
                }
            } else {
                $affiliate_name = null;
                $affiliates_options->delete_option('affiliates_affiliate_name');
            }
            if (!empty($_POST['affiliate_email'])) {
                $affiliate_email = trim($_POST['affiliate_email']);
                if (strlen($affiliate_email) > 0) {
                    $affiliates_options->update_option('affiliates_affiliate_email', $affiliate_email);
                } else {
                    $affiliate_email = null;
                    $affiliates_options->delete_option('affiliates_affiliate_email');
                }
            } else {
                $affiliate_email = null;
                $affiliates_options->delete_option('affiliates_affiliate_email');
            }
            if (!empty($_POST['affiliate_user_login'])) {
                $affiliate_user_login = trim($_POST['affiliate_user_login']);
                if (strlen($affiliate_user_login) > 0) {
                    $affiliates_options->update_option('affiliates_affiliate_user_login', $affiliate_user_login);
                } else {
                    $affiliate_user_login = null;
                    $affiliates_options->delete_option('affiliates_affiliate_user_login');
                }
            } else {
                $affiliate_user_login = null;
                $affiliates_options->delete_option('affiliates_affiliate_user_login');
            }
            $show_deleted = isset($_POST['show_deleted']);
            $affiliates_options->update_option('affiliates_show_deleted', $show_deleted);
            $show_inoperative = isset($_POST['show_inoperative']);
            $affiliates_options->update_option('affiliates_show_inoperative', $show_inoperative);
            // filter by date(s)
            if (!empty($_POST['from_date'])) {
                $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                $affiliates_options->update_option('affiliates_from_date', $from_date);
            } else {
                $from_date = null;
                $affiliates_options->delete_option('affiliates_from_date');
            }
            if (!empty($_POST['thru_date'])) {
                $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                $affiliates_options->update_option('affiliates_thru_date', $thru_date);
            } else {
                $thru_date = null;
                $affiliates_options->delete_option('affiliates_thru_date');
            }
            if ($from_date && $thru_date) {
                if (strtotime($from_date) > strtotime($thru_date)) {
                    $thru_date = null;
                    $affiliates_options->delete_option('affiliates_thru_date');
                }
            }
            // We now have the desired dates from the user's point of view, i.e. in her timezone.
            // If supported, adjust the dates for the site's timezone:
            if ($from_date) {
                $from_datetime = DateHelper::u2s($from_date);
            }
            if ($thru_date) {
                $thru_datetime = DateHelper::u2s($thru_date, 24 * 3600);
            }
            // filter by affiliate id
            if (!empty($_POST['affiliate_id'])) {
                $affiliate_id = affiliates_check_affiliate_id($_POST['affiliate_id']);
                if ($affiliate_id) {
                    $affiliates_options->update_option('affiliates_affiliate_id', $affiliate_id);
                }
            } else {
                if (isset($_POST['affiliate_id'])) {
                    // empty && isset => '' => all
                    $affiliate_id = null;
                    $affiliates_options->delete_option('affiliates_affiliate_id');
                }
            }
        }
    }
    if (isset($_POST['row_count'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_NONCE_1], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    if (isset($_POST['paged'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_NONCE_2], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('paged', $current_url);
    $current_url = remove_query_arg('action', $current_url);
    $current_url = remove_query_arg('affiliate_id', $current_url);
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $output .= '<div class="manage-affiliates">' . '<div>' . '<h2>' . __('Manage Affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>';
    $output .= '<div class="manage">' . "<a title='" . __('Click to add a new affiliate', AFFILIATES_PLUGIN_DOMAIN) . "' class='button add' href='" . esc_url($current_url) . "&action=add'><img class='icon' alt='" . __('Add', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/add.png'/><span class='label'>" . __('New Affiliate', AFFILIATES_PLUGIN_DOMAIN) . "</span></a>" . '</div>';
    $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
    if ($row_count <= 0) {
        $row_count = $affiliates_options->get_option('affiliates_per_page', AFFILIATES_AFFILIATES_PER_PAGE);
    } else {
        $affiliates_options->update_option('affiliates_per_page', $row_count);
    }
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    if ($offset < 0) {
        $offset = 0;
    }
    $paged = isset($_GET['paged']) ? intval($_GET['paged']) : 0;
    if ($paged < 0) {
        $paged = 0;
    }
    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
    switch ($orderby) {
        case 'from_date':
        case 'thru_date':
        case 'email':
        case 'affiliate_id':
        case 'name':
        case 'user_login':
            break;
        default:
            $orderby = 'name';
    }
    $order = isset($_GET['order']) ? $_GET['order'] : null;
    switch ($order) {
        case 'asc':
        case 'ASC':
            $switch_order = 'DESC';
            break;
        case 'desc':
        case 'DESC':
            $switch_order = 'ASC';
            break;
        default:
            $order = 'ASC';
            $switch_order = 'DESC';
    }
    //	if ( $from_date || $thru_date || $affiliate_id ) {
    //		$filters = " WHERE ";
    //	} else {
    //		$filters = '';
    //	}
    $filters = array();
    $filter_params = array();
    if ($affiliate_id) {
        $filters[] = " {$affiliates_table}.affiliate_id = %d ";
        $filter_params[] = $affiliate_id;
    }
    if ($affiliate_name) {
        $filters[] = " {$affiliates_table}.name LIKE '%%%s%%' ";
        $filter_params[] = $affiliate_name;
    }
    if ($affiliate_email) {
        $filters[] = " {$affiliates_table}.email LIKE '%%%s%%' ";
        $filter_params[] = $affiliate_email;
    }
    if ($affiliate_user_login) {
        $filters[] = " {$wpdb->users}.user_login LIKE '%%%s%%' ";
        $filter_params[] = $affiliate_user_login;
    }
    if (!$show_deleted) {
        $filters[] = " {$affiliates_table}.status = %s ";
        $filter_params[] = 'active';
    }
    if (!$show_inoperative) {
        $filters[] = " {$affiliates_table}.from_date <= %s AND ( {$affiliates_table}.thru_date IS NULL OR {$affiliates_table}.thru_date >= %s ) ";
        $filter_params[] = $today;
        $filter_params[] = $today;
    }
    if ($from_datetime && $thru_datetime) {
        $filters[] = " {$affiliates_table}.from_date >= %s AND ( {$affiliates_table}.thru_date IS NULL OR {$affiliates_table}.thru_date < %s ) ";
        $filter_params[] = $from_datetime;
        $filter_params[] = $thru_datetime;
    } else {
        if ($from_datetime) {
            $filters[] = " {$affiliates_table}.from_date >= %s ";
            $filter_params[] = $from_datetime;
        } else {
            if ($thru_datetime) {
                $filters[] = " {$affiliates_table}.thru_date < %s ";
                $filter_params[] = $thru_datetime;
            }
        }
    }
    if (!empty($filters)) {
        $filters = " WHERE " . implode(" AND ", $filters);
    } else {
        $filters = '';
    }
    $count_query = $wpdb->prepare("SELECT COUNT(*) FROM {$affiliates_table} LEFT JOIN {$affiliates_users_table} ON {$affiliates_table}.affiliate_id = {$affiliates_users_table}.affiliate_id LEFT JOIN {$wpdb->users} on {$affiliates_users_table}.user_id = {$wpdb->users}.ID {$filters}", $filter_params);
    $count = $wpdb->get_var($count_query);
    if ($count > $row_count) {
        $paginate = true;
    } else {
        $paginate = false;
    }
    $pages = ceil($count / $row_count);
    if ($paged > $pages) {
        $paged = $pages;
    }
    if ($paged != 0) {
        $offset = ($paged - 1) * $row_count;
    }
    $query = $wpdb->prepare("SELECT {$affiliates_table}.*, {$wpdb->users}.* FROM {$affiliates_table} LEFT JOIN {$affiliates_users_table} ON {$affiliates_table}.affiliate_id = {$affiliates_users_table}.affiliate_id LEFT JOIN {$wpdb->users} on {$affiliates_users_table}.user_id = {$wpdb->users}.ID {$filters} ORDER BY {$orderby} {$order} LIMIT {$row_count} OFFSET {$offset}", $filter_params);
    $results = $wpdb->get_results($query, OBJECT);
    $column_display_names = array('affiliate_id' => __('Id', AFFILIATES_PLUGIN_DOMAIN), 'name' => __('Affiliate', AFFILIATES_PLUGIN_DOMAIN), 'email' => __('Email', AFFILIATES_PLUGIN_DOMAIN), 'user_login' => __('Username', AFFILIATES_PLUGIN_DOMAIN), 'from_date' => __('From', AFFILIATES_PLUGIN_DOMAIN), 'thru_date' => __('Until', AFFILIATES_PLUGIN_DOMAIN), 'edit' => __('Edit', AFFILIATES_PLUGIN_DOMAIN), 'remove' => __('Remove', AFFILIATES_PLUGIN_DOMAIN), 'links' => __('Links', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '<div class="affiliates-overview">';
    $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<p>' . '<label class="affiliate-id-filter" for="affiliate_id">' . __('Affiliate Id', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="affiliate-id-filter" name="affiliate_id" type="text" value="' . esc_attr($affiliate_id) . '"/>' . '<label class="affiliate-name-filter" for="affiliate_name">' . __('Affiliate Name', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="affiliate-name-filter" name="affiliate_name" type="text" value="' . $affiliate_name . '"/>' . '<label class="affiliate-email-filter" for="affiliate_email">' . __('Affiliate Email', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="affiliate-email-filter" name="affiliate_email" type="text" value="' . $affiliate_email . '"/>' . '<label class="affiliate-user-login-filter" for="affiliate_user_login">' . __('Affiliate Username', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="affiliate-user-login-filter" name="affiliate_user_login" type="text" value="' . $affiliate_user_login . '" />' . '</p>' . '<p>' . '<label class="from-date-filter" for="from_date">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '<label class="thru-date-filter" for="thru_date">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield thru-date-filter" name="thru_date" type="text" class="datefield" value="' . esc_attr($thru_date) . '"/>' . '<label class="show-inoperative-filter">' . '<input class="show-inoperative-filter" name="show_inoperative" type="checkbox" ' . ($show_inoperative ? 'checked="checked"' : '') . '/>' . ' ' . __('Include inoperative affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<label class="show-deleted-filter">' . '<input class="show-deleted-filter" name="show_deleted" type="checkbox" ' . ($show_deleted ? 'checked="checked"' : '') . '/>' . ' ' . __('Include removed affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>
				<p>' . wp_nonce_field('admin', AFFILIATES_ADMIN_AFFILIATES_FILTER_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</p>' . '</form>' . '</div>';
    $output .= '
		<div class="page-options">
			<form id="setrowcount" action="" method="post">
				<div>
					<label for="row_count">' . __('Results per page', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />
					' . wp_nonce_field('admin', AFFILIATES_ADMIN_AFFILIATES_NONCE_1, true, false) . '
					<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>
				</div>
			</form>
		</div>
		';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<form id="posts-filter" method="post" action="">';
        $output .= '<div>';
        $output .= wp_nonce_field('admin', AFFILIATES_ADMIN_AFFILIATES_NONCE_2, true, false);
        $output .= '</div>';
        $output .= '<div class="tablenav top">';
        $output .= $pagination->pagination('top');
        $output .= '</div>';
        $output .= '</form>';
    }
    $output .= '
		<table id="" class="wp-list-table widefat fixed" cellspacing="0">
		<thead>
			<tr>
			';
    foreach ($column_display_names as $key => $column_display_name) {
        $options = array('orderby' => $key, 'order' => $switch_order);
        $class = $key;
        if (!in_array($key, array('edit', 'remove', 'links'))) {
            if (strcmp($key, $orderby) == 0) {
                $lorder = strtolower($order);
                $class = "{$key} manage-column sorted {$lorder}";
            } else {
                $class = "{$key} manage-column sortable";
            }
            $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
        }
        $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
    }
    $output .= '</tr>
		</thead>
		<tbody>
		';
    if (count($results) > 0) {
        for ($i = 0; $i < count($results); $i++) {
            $result = $results[$i];
            $name_suffix = '';
            $class_deleted = '';
            if ($is_deleted = strcmp($result->status, 'deleted') == 0) {
                $class_deleted = ' deleted ';
                $name_suffix .= " " . __('(removed)', AFFILIATES_PLUGIN_DOMAIN);
            }
            $class_inoperative = '';
            if ($is_inoperative = !($result->from_date <= $today && ($result->thru_date == null || $result->thru_date >= $today))) {
                $class_inoperative = ' inoperative ';
                $name_suffix .= " " . __('(inoperative)', AFFILIATES_PLUGIN_DOMAIN);
            }
            $output .= '<tr class="' . $class_deleted . $class_inoperative . ($i % 2 == 0 ? 'even' : 'odd') . '">';
            $output .= "<td class='affiliate-id'>";
            if (affiliates_encode_affiliate_id($result->affiliate_id) != $result->affiliate_id) {
                $output .= '<span class="encoded-hint" title="' . affiliates_encode_affiliate_id($result->affiliate_id) . '">' . $result->affiliate_id . '</span>';
            } else {
                $output .= $result->affiliate_id;
            }
            $output .= "</td>";
            $output .= "<td class='affiliate-name'>" . stripslashes(wp_filter_nohtml_kses($result->name)) . $name_suffix . "</td>";
            $output .= "<td class='affiliate-email'>" . $result->email;
            if (isset($result->email) && isset($result->user_email) && strcmp($result->email, $result->user_email) !== 0) {
                $output .= '<span title="' . sprintf(__('There are different email addresses on record for the affiliate and the associated user. This might be ok, but if in doubt please check. The email address on file for the user is %s', AFFILIATES_PLUGIN_DOMAIN), $result->user_email) . '" class="warning"> [&nbsp;!&nbsp]</span>';
            }
            $output .= "</td>";
            $output .= "<td class='affiliate-user-login'>";
            if (!empty($result->ID)) {
                if (current_user_can('edit_user', $result->ID)) {
                    $output .= '<a target="_blank" href="' . esc_url("user-edit.php?user_id={$result->ID}") . '">' . $result->user_login . '</a>';
                } else {
                    $output .= $result->user_login;
                }
            }
            $output .= "</td>";
            $output .= "<td class='from-date'>{$result->from_date}</td>";
            $output .= "<td class='thru-date'>{$result->thru_date}</td>";
            $output .= "<td class='edit'><a href='" . esc_url(add_query_arg('paged', $paged, $current_url)) . "&action=edit&affiliate_id=" . $result->affiliate_id . "' alt='" . __('Edit', AFFILIATES_PLUGIN_DOMAIN) . "'><img src='" . AFFILIATES_PLUGIN_URL . "images/edit.png'/></a></td>";
            $output .= "<td class='remove'>" . (!$is_deleted && (!isset($result->type) || $result->type != AFFILIATES_DIRECT_TYPE) ? "<a href='" . esc_url($current_url) . "&action=remove&affiliate_id=" . $result->affiliate_id . "' alt='" . __('Remove', AFFILIATES_PLUGIN_DOMAIN) . "'><img src='" . AFFILIATES_PLUGIN_URL . "images/remove.png'/></a>" : "") . "</td>";
            $output .= "<td class='links'>";
            $encoded_id = affiliates_encode_affiliate_id($result->affiliate_id);
            $output .= __('Link', AFFILIATES_PLUGIN_DOMAIN) . ': ' . '<span class="affiliate-link">' . get_bloginfo('url') . '?' . $pname . '=' . $encoded_id . '</span>' . ' &nbsp; ' . __('URL Parameter', AFFILIATES_PLUGIN_DOMAIN) . ': ' . '<span class="affiliate-link-param">' . '?' . $pname . '=' . $encoded_id . '</span>' . '<br/>' . __('Pretty', AFFILIATES_PLUGIN_DOMAIN) . ': ' . '<span class="affiliate-permalink">' . get_bloginfo('url') . '/' . $pname . '/' . $encoded_id . '</span>' . ($wp_rewrite->using_permalinks() ? '' : '<span class="warning">' . '&nbsp;' . sprintf(__('you need to adjust your <a href="%s">permalink settings</a>.', AFFILIATES_PLUGIN_DOMAIN), get_admin_url(null, 'options-permalink.php')) . '</span>');
            $output .= "</td>";
            $output .= '</tr>';
        }
    } else {
        $output .= '<tr><td colspan="10">' . __('There are no results.', AFFILIATES_PLUGIN_DOMAIN) . '</td></tr>';
    }
    $output .= '</tbody>';
    $output .= '</table>';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<div class="tablenav bottom">';
        $output .= $pagination->pagination('bottom');
        $output .= '</div>';
    }
    $output .= '</div>';
    // .affiliates-overview
    $output .= '</div>';
    // .manage-affiliates
    echo $output;
    affiliates_footer();
}
 /**
  * URL shortcode - renders the affiliate url.
  *
  * @param array $atts attributes
  * @param string $content (is not used)
  */
 public static function affiliates_url($atts, $content = null)
 {
     global $wpdb;
     remove_shortcode('affiliates_url');
     $content = do_shortcode($content);
     add_shortcode('affiliates_url', array(__CLASS__, 'affiliates_url'));
     $output = "";
     $user_id = get_current_user_id();
     if ($user_id && affiliates_user_is_affiliate($user_id)) {
         $affiliates_table = _affiliates_get_tablename('affiliates');
         $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
         if ($affiliate_id = $wpdb->get_var($wpdb->prepare("SELECT {$affiliates_users_table}.affiliate_id FROM {$affiliates_users_table} LEFT JOIN {$affiliates_table} ON {$affiliates_users_table}.affiliate_id = {$affiliates_table}.affiliate_id WHERE {$affiliates_users_table}.user_id = %d AND {$affiliates_table}.status = 'active'", intval($user_id)))) {
             if (strlen($content) == 0) {
                 $base_url = get_bloginfo('url');
             } else {
                 // wp_texturize() has already been applied to $content and
                 // it indiscriminately replaces ampersands with the HTML
                 // entity &#038; - we need to undo this so path separators
                 // are not messed up. Note that it does that even though we
                 // have indicated to exclude affiliates_url via the
                 // no_texturize_shortcodes filter.
                 $base_url = trim($content);
                 $base_url = str_replace('&#038;', '&', $base_url);
                 $base_url = strip_tags($base_url);
                 $base_url = preg_replace('/\\r|\\n/', '', $base_url);
                 $base_url = trim($base_url);
             }
             $output .= affiliates_get_affiliate_url($base_url, $affiliate_id);
         }
     }
     return $output;
 }
/**
 * Affiliates overview and summarized statistics.
 */
function affiliates_admin()
{
    global $wpdb, $affiliates_options;
    if (!current_user_can(AFFILIATES_ACCESS_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    echo '<h2>' . __('Affiliates Overview', AFFILIATES_PLUGIN_DOMAIN) . '</h2>';
    $today = date('Y-m-d', time());
    $day_interval = 7;
    $min_days_back = 14;
    $max_days_back = 1100;
    // filters
    if (isset($_POST['from_date']) || isset($_POST['thru_date']) || isset($_POST['days_back']) || isset($_POST['clear_filters'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_OVERVIEW_NONCE], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $from_date = $affiliates_options->get_option('overview_from_date', null);
    $thru_date = $affiliates_options->get_option('overview_thru_date', null);
    $days_back = $affiliates_options->get_option('overview_days_back', $min_days_back);
    if (isset($_POST['clear_filters'])) {
        $affiliates_options->delete_option('overview_from_date');
        $affiliates_options->delete_option('overview_thru_date');
        $affiliates_options->delete_option('overview_days_back');
        $from_date = null;
        $thru_date = null;
        $days_back = $min_days_back;
    } else {
        if (isset($_POST['submitted'])) {
            if (empty($_POST['from_date']) && !empty($_POST['days_back'])) {
                $days_back = abs(intval($_POST['days_back']));
                if ($days_back < $min_days_back) {
                    $days_back = $min_days_back;
                } else {
                    if ($days_back > $max_days_back) {
                        $days_back = $max_days_back;
                    }
                }
                $affiliates_options->update_option('overview_days_back', $days_back);
                unset($_POST['from_date']);
            } else {
                $days_back = null;
                $affiliates_options->delete_option('overview_days_back');
            }
            // filter by date(s)
            if (!empty($_POST['from_date'])) {
                $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                $affiliates_options->update_option('overview_from_date', $from_date);
            } else {
                $from_date = null;
                $affiliates_options->delete_option('overview_from_date');
            }
            if (!empty($_POST['thru_date'])) {
                $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                $affiliates_options->update_option('overview_thru_date', $thru_date);
            } else {
                $thru_date = null;
                $affiliates_options->delete_option('overview_thru_date');
            }
            // coherent dates
            if ($from_date && $thru_date) {
                if (strtotime($from_date) > strtotime($thru_date)) {
                    $thru_date = null;
                    $affiliates_options->delete_option('overview_thru_date');
                }
            }
        }
    }
    if (!empty($from_date) || !empty($thru_date)) {
        if (!empty($from_date) && !empty($thru_date)) {
            $delta = (strtotime($thru_date) - strtotime($from_date)) / (3600 * 24);
        } else {
            $delta = $days_back;
        }
        if ($delta > $max_days_back || $delta < $min_days_back) {
            if ($delta > $max_days_back) {
                $delta = $max_days_back;
            }
            if ($delta < $min_days_back) {
                $delta = $min_days_back;
            }
            $days_back = $delta;
            $day_interval = intval($days_back / 2);
            $from_date = date('Y-m-d', strtotime($thru_date) - $days_back * 3600 * 24);
        } else {
            $days_back = $delta;
            $day_interval = intval($days_back / 2);
        }
        if (empty($from_date) && empty($_POST['days_back'])) {
            $from_date = date('Y-m-d', strtotime($thru_date) - $days_back * 3600 * 24);
        }
        if (empty($thru_date)) {
            $thru_date = date('Y-m-d', strtotime($from_date) + $days_back * 3600 * 24);
        }
    }
    // fill this in before the final $from_date and $thru_date are set
    $filters_form = '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<p>' . '<label class="from-date-filter" for="from_date">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '<label class="thru-date-filter" for="thru_date">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield thru-date-filter" name="thru_date" type="text" value="' . esc_attr($thru_date) . '"/>' . '<label class="days-back-filter" for="days_back">' . __('Days back', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="days-back-filter" name="days_back" type="text" value="' . esc_attr($days_back) . '"/>' . wp_nonce_field('admin', AFFILIATES_ADMIN_OVERVIEW_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</p>' . '</form>' . '</div>';
    if (empty($thru_date)) {
        $thru_date = $today;
    }
    if (empty($from_date)) {
        $from_date = date('Y-m-d', strtotime($thru_date) - $days_back * 3600 * 24);
    }
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $hits_table = _affiliates_get_tablename('hits');
    $referrals_table = _affiliates_get_tablename('referrals');
    $affiliates_subquery = " affiliate_id IN (SELECT affiliate_id FROM {$affiliates_table} WHERE status = 'active') ";
    // hits per day
    $query = "SELECT date, sum(count) as hits FROM {$hits_table} WHERE date >= %s AND date <= %s AND " . $affiliates_subquery . " GROUP BY date";
    $hit_results = $wpdb->get_results($wpdb->prepare($query, $from_date, $thru_date, $from_date, $thru_date));
    $hits = array();
    foreach ($hit_results as $hit_result) {
        $hits[$hit_result->date] = $hit_result->hits;
    }
    // visits per day
    $query = "SELECT count(DISTINCT IP) visits, date FROM {$hits_table} WHERE date >= %s AND date <= %s AND " . $affiliates_subquery . " GROUP BY date";
    $visit_results = $wpdb->get_results($wpdb->prepare($query, $from_date, $thru_date, $from_date, $thru_date));
    $visits = array();
    foreach ($visit_results as $visit_result) {
        $visits[$visit_result->date] = $visit_result->visits;
    }
    // referrals per day
    $query = "SELECT count(referral_id) referrals, date(datetime) date FROM {$referrals_table} WHERE status = %s AND date(datetime) >= %s AND date(datetime) <= %s AND " . $affiliates_subquery . " GROUP BY date";
    $results = $wpdb->get_results($wpdb->prepare($query, AFFILIATES_REFERRAL_STATUS_ACCEPTED, $from_date, $thru_date, $from_date, $thru_date));
    $accepted = array();
    foreach ($results as $result) {
        $accepted[$result->date] = $result->referrals;
    }
    $results = $wpdb->get_results($wpdb->prepare($query, AFFILIATES_REFERRAL_STATUS_CLOSED, $from_date, $thru_date, $from_date, $thru_date));
    $closed = array();
    foreach ($results as $result) {
        $closed[$result->date] = $result->referrals;
    }
    $results = $wpdb->get_results($wpdb->prepare($query, AFFILIATES_REFERRAL_STATUS_PENDING, $from_date, $thru_date, $from_date, $thru_date));
    $pending = array();
    foreach ($results as $result) {
        $pending[$result->date] = $result->referrals;
    }
    $results = $wpdb->get_results($wpdb->prepare($query, AFFILIATES_REFERRAL_STATUS_REJECTED, $from_date, $thru_date, $from_date, $thru_date));
    $rejected = array();
    foreach ($results as $result) {
        $rejected[$result->date] = $result->referrals;
    }
    $accepted_series = array();
    $pending_series = array();
    $rejected_series = array();
    $closed_series = array();
    $hits_series = array();
    $visits_series = array();
    $ticks = array();
    $dates = array();
    for ($day = -$days_back; $day <= 0; $day++) {
        $date = date('Y-m-d', strtotime($thru_date) + $day * 3600 * 24);
        $dates[$day] = $date;
        if (isset($accepted[$date])) {
            $accepted_series[] = array($day, intval($accepted[$date]));
        }
        if (isset($pending[$date])) {
            $pending_series[] = array($day, intval($pending[$date]));
        }
        if (isset($rejected[$date])) {
            $rejected_series[] = array($day, intval($rejected[$date]));
        }
        if (isset($closed[$date])) {
            $closed_series[] = array($day, intval($closed[$date]));
        }
        if (isset($hits[$date])) {
            $hits_series[] = array($day, intval($hits[$date]));
        }
        if (isset($visits[$date])) {
            $visits_series[] = array($day, intval($visits[$date]));
        }
        if ($days_back <= $day_interval + $min_days_back) {
            $label = date('m-d', strtotime($date));
            $ticks[] = array($day, $label);
        } else {
            if ($days_back <= 91) {
                $d = date('d', strtotime($date));
                if ($d == '1' || $d == '15') {
                    $label = date('m-d', strtotime($date));
                    $ticks[] = array($day, $label);
                }
            } else {
                if (date('d', strtotime($date)) == '1') {
                    if (date('m', strtotime($date)) == '1') {
                        $label = '<strong>' . date('Y', strtotime($date)) . '</strong>';
                    } else {
                        $label = date('m-d', strtotime($date));
                    }
                    $ticks[] = array($day, $label);
                }
            }
        }
    }
    $accepted_series_json = json_encode($accepted_series);
    $pending_series_json = json_encode($pending_series);
    $rejected_series_json = json_encode($rejected_series);
    $closed_series_json = json_encode($closed_series);
    $hits_series_json = json_encode($hits_series);
    $visits_series_json = json_encode($visits_series);
    $span_series_json = json_encode(array(array(intval(-$days_back), 0), array(0, 0)));
    $ticks_json = json_encode($ticks);
    $dates_json = json_encode($dates);
    echo '<h3>' . sprintf(__('%d Day Charts', AFFILIATES_PLUGIN_DOMAIN), $days_back) . '</h2>';
    echo '<div class="manage" style="margin-right:1em">';
    ?>
	<div id="stats" class="" style="width:100%;height:400px;"></div>
	<script type="text/javascript">
		(function($){
			$(document).ready(function(){
				var data = [
					{
						label : "<?php 
    _e('Hits', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $hits_series_json;
    ?>
,
						lines : { show : true },
						yaxis : 2,
						color : '#ccddff'
					},
					{
						label : "<?php 
    _e('Visits', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $visits_series_json;
    ?>
,
						lines : { show : true },
						yaxis : 2,
						color : '#ffddcc'
					},
					{
						label : "<?php 
    _e('Accepted', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $accepted_series_json;
    ?>
,
						color : '#009900',
						bars : { align : "center", show : true, barWidth : 1 },
						hoverable : true,
						yaxis : 1
					},
					{
						label : "<?php 
    _e('Pending', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $pending_series_json;
    ?>
,
						color : '#0000ff',
						bars : { align : "center", show : true, barWidth : 0.6 },
						yaxis : 1
					},
					{
						label : "<?php 
    _e('Rejected', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $rejected_series_json;
    ?>
,
						color : '#ff0000',
						bars : { align : "center", show : true, barWidth : .3 },
						yaxis : 1
					},
					{
						label : "<?php 
    _e('Closed', AFFILIATES_PLUGIN_DOMAIN);
    ?>
",
						data : <?php 
    echo $closed_series_json;
    ?>
,
						color : '#333333',
						points : { show : true },
						yaxis : 1
					},
					{
						data : <?php 
    echo $span_series_json;
    ?>
,
						lines : { show : false },
						yaxis : 1
					}
				];

				var options = {
					xaxis : {
						ticks : <?php 
    echo $ticks_json;
    ?>
					},
					yaxis : {
						min : 0,
						tickDecimals : 0
					},
					yaxes : [
						{},
						{ position : 'right' }
					],
					grid : {
						hoverable : true
					},
					legend : {
						position : 'nw'
					}
				};

				$.plot($("#stats"),data,options);

				function statsTooltip(x, y, contents) {
					$('<div id="tooltip">' + contents + '</div>').css( {
						position: 'absolute',
						display: 'none',
						top: y + 5,
						left: x + 5,
						border: '1px solid #333',
						'border-radius' : '4px',
						padding: '6px',
						'background-color': '#ccc',
						opacity: 0.90
					}).appendTo("body").fadeIn(200);
				}

				var tooltipItem = null;
				var statsDates = <?php 
    echo $dates_json;
    ?>
;
				$("#stats").bind("plothover", function (event, pos, item) {
					if (item) {
						if (tooltipItem === null || item.dataIndex != tooltipItem.dataIndex || item.seriesIndex != tooltipItem.seriesIndex) {
							tooltipItem = item;
							$("#tooltip").remove();
							var x = item.datapoint[0];
								y = item.datapoint[1];
							statsTooltip(
								item.pageX,
								item.pageY,
								item.series.label + " : " + y +  '<br/>' + statsDates[x] 
							);
						}
					} else {
						$("#tooltip").remove();
						tooltipItem = null;
					}
				});
			});
		})(jQuery);
	</script>
	<?php 
    echo '<br class="clear"/>';
    echo $filters_form;
    echo '</div>';
    echo '<h3>' . __('Statistics Summary', AFFILIATES_PLUGIN_DOMAIN) . '</h3>';
    for ($i = 0; $i < 3; $i++) {
        $add_class = "";
        switch ($i) {
            case 0:
                $affiliates = affiliates_get_affiliates(true, true);
                $title = __('From operative affiliates:', AFFILIATES_PLUGIN_DOMAIN);
                $info = sprintf(_n('There is 1 operative affiliate', 'There are %d operative affiliates', count($affiliates), AFFILIATES_PLUGIN_DOMAIN), count($affiliates));
                $add_class = "active valid";
                break;
            case 1:
                $affiliates = affiliates_get_affiliates(true, false);
                $title = __('From operative and non-operative affiliates:', AFFILIATES_PLUGIN_DOMAIN);
                $info = sprintf(_n('There is 1 affiliate in this set', 'There are %d affiliates in this set', count($affiliates), AFFILIATES_PLUGIN_DOMAIN), count($affiliates));
                $add_class = "active";
                break;
            case 2:
                $affiliates = affiliates_get_affiliates(false, false);
                $title = __('All time (includes data from deleted affiliates):', AFFILIATES_PLUGIN_DOMAIN);
                $info = sprintf(_n('There is 1 affiliate in this set', 'There are %d affiliates in this set', count($affiliates), AFFILIATES_PLUGIN_DOMAIN), count($affiliates));
                break;
        }
        $hits = 0;
        $visits = 0;
        $referrals_accepted = 0;
        $referrals_closed = 0;
        $referrals_pending = 0;
        $referrals_rejected = 0;
        foreach ($affiliates as $affiliate) {
            $affiliate_id = $affiliate['affiliate_id'];
            $hits += affiliates_get_affiliate_hits($affiliate_id);
            $visits += affiliates_get_affiliate_visits($affiliate_id);
            $referrals_accepted += affiliates_get_affiliate_referrals($affiliate_id, null, null, AFFILIATES_REFERRAL_STATUS_ACCEPTED);
            $referrals_closed += affiliates_get_affiliate_referrals($affiliate_id, null, null, AFFILIATES_REFERRAL_STATUS_CLOSED);
            $referrals_pending += affiliates_get_affiliate_referrals($affiliate_id, null, null, AFFILIATES_REFERRAL_STATUS_PENDING);
            $referrals_rejected += affiliates_get_affiliate_referrals($affiliate_id, null, null, AFFILIATES_REFERRAL_STATUS_REJECTED);
        }
        $accepted_icon = "<img class='icon' alt='" . __('Accepted', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/accepted.png'/>";
        $closed_icon = "<img class='icon' alt='" . __('Closed', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/closed.png'/>";
        $pending_icon = "<img class='icon' alt='" . __('Pending', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/pending.png'/>";
        $rejected_icon = "<img class='icon' alt='" . __('Rejected', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/rejected.png'/>";
        echo '<div class="manage" style="margin-right:1em">';
        echo '<p>';
        echo '<strong>' . $title . '</strong>&nbsp;' . $info;
        echo '</p>';
        echo '<ul>';
        echo '<li>' . __('<strong>Referrals:</strong>', AFFILIATES_PLUGIN_DOMAIN) . '</li>';
        echo '<li><ul>';
        echo '<li>' . $accepted_icon . '&nbsp;' . sprintf(__('%10d Accepted', AFFILIATES_PLUGIN_DOMAIN), $referrals_accepted) . '</li>';
        echo '<li>' . $closed_icon . '&nbsp;' . sprintf(__('%10d Closed', AFFILIATES_PLUGIN_DOMAIN), $referrals_closed) . '</li>';
        echo '<li>' . $pending_icon . '&nbsp;' . sprintf(__('%10d Pending', AFFILIATES_PLUGIN_DOMAIN), $referrals_pending) . '</li>';
        echo '<li>' . $rejected_icon . '&nbsp;' . sprintf(__('%10d Rejected', AFFILIATES_PLUGIN_DOMAIN), $referrals_rejected) . '</li>';
        echo '</li></ul>';
        echo '<li>' . sprintf(__('%10d Hits', AFFILIATES_PLUGIN_DOMAIN), $hits) . '</li>';
        echo '<li>' . sprintf(__('%10d Visits', AFFILIATES_PLUGIN_DOMAIN), $visits) . '</li>';
        echo '</ul>';
        echo '</div>';
    }
    affiliates_footer();
}
 /**
  * URL shortcode - renders the affiliate url.
  *
  * @param array $atts attributes
  * @param string $content (is not used)
  */
 public static function affiliates_url($atts, $content = null)
 {
     global $wpdb;
     $pname = get_option('aff_pname', AFFILIATES_PNAME);
     remove_shortcode('affiliates_url');
     $content = do_shortcode($content);
     add_shortcode('affiliates_url', array(__CLASS__, 'affiliates_url'));
     $output = "";
     $user_id = get_current_user_id();
     if ($user_id && affiliates_user_is_affiliate($user_id)) {
         $affiliates_table = _affiliates_get_tablename('affiliates');
         $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
         if ($affiliate_id = $wpdb->get_var($wpdb->prepare("SELECT {$affiliates_users_table}.affiliate_id FROM {$affiliates_users_table} LEFT JOIN {$affiliates_table} ON {$affiliates_users_table}.affiliate_id = {$affiliates_table}.affiliate_id WHERE {$affiliates_users_table}.user_id = %d AND {$affiliates_table}.status = 'active'", intval($user_id)))) {
             $encoded_affiliate_id = affiliates_encode_affiliate_id($affiliate_id);
             if (strlen($content) == 0) {
                 $base_url = get_bloginfo('url');
             } else {
                 $base_url = $content;
             }
             $separator = '?';
             $url_query = parse_url($base_url, PHP_URL_QUERY);
             if (!empty($url_query)) {
                 $separator = '&';
             }
             $output .= $base_url . $separator . $pname . '=' . $encoded_affiliate_id;
         }
     }
     return $output;
 }
 /**
  * Returns totals for the given period or for all time.
  * @param string $from_date
  * @param string $thru_date
  * @param string $status
  */
 private static function get_totals($from_date = null, $thru_date = null, $status = AFFILIATES_REFERRAL_STATUS_ACCEPTED)
 {
     global $wpdb;
     $referrals_table = _affiliates_get_tablename('referrals');
     $where = " WHERE TRUE ";
     $values = array();
     if ($from_date) {
         $from_date = date('Y-m-d', strtotime($from_date));
     }
     if ($thru_date) {
         $thru_date = date('Y-m-d', strtotime($thru_date) + 24 * 3600);
     }
     if ($from_date && $thru_date) {
         $where .= " AND datetime >= %s AND datetime < %s ";
         $values[] = $from_date;
         $values[] = $thru_date;
     } else {
         if ($from_date) {
             $where .= " AND datetime >= %s ";
             $values[] = $from_date;
         } else {
             if ($thru_date) {
                 $where .= " AND datetime < %s ";
                 $values[] = $thru_date;
             }
         }
     }
     if (!empty($status)) {
         $where .= " AND status = %s ";
         $values[] = $status;
     }
     $totals = $wpdb->get_results($wpdb->prepare("SELECT SUM(amount) total, currency_id FROM {$referrals_table}\n\t\t\t{$where}\n\t\t\tGROUP BY currency_id\n\t\t\t", $values));
     if ($totals) {
         $result = array();
         foreach ($totals as $total) {
             if ($total->currency_id !== null && $total->total !== null) {
                 $result[$total->currency_id] = $total->total;
             }
         }
         return $result;
     } else {
         return false;
     }
 }
function affiliates_admin_hits_affiliate()
{
    global $wpdb, $affiliates_options;
    $output = '';
    if (!current_user_can(AFFILIATES_ACCESS_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (isset($_POST['from_date']) || isset($_POST['thru_date']) || isset($_POST['clear_filters']) || isset($_POST['affiliate_id']) || isset($_POST['expanded']) || isset($_POST['expanded_hits']) || isset($_POST['expanded_referrals']) || isset($_POST['show_inoperative'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_AFF_FILTER_NONCE], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    // filters
    $from_date = $affiliates_options->get_option('hits_affiliate_from_date', null);
    $thru_date = $affiliates_options->get_option('hits_affiliate_thru_date', null);
    $affiliate_id = $affiliates_options->get_option('hits_affiliate_affiliate_id', null);
    $status = $affiliates_options->get_option('hits_affiliate_status', null);
    $expanded = $affiliates_options->get_option('hits_affiliate_expanded', null);
    // @todo input ist not shown, eventually remove unless ...
    $expanded_referrals = $affiliates_options->get_option('hits_affiliate_expanded_referrals', null);
    $expanded_hits = $affiliates_options->get_option('hits_affiliate_expanded_hits', null);
    $show_inoperative = $affiliates_options->get_option('hits_affiliate_show_inoperative', null);
    if (isset($_POST['clear_filters'])) {
        $affiliates_options->delete_option('hits_affiliate_from_date');
        $affiliates_options->delete_option('hits_affiliate_thru_date');
        $affiliates_options->delete_option('hits_affiliate_affiliate_id');
        $affiliates_options->delete_option('hits_affiliate_status');
        $affiliates_options->delete_option('hits_affiliate_expanded');
        $affiliates_options->delete_option('hits_affiliate_expanded_referrals');
        $affiliates_options->delete_option('hits_affiliate_expanded_hits');
        $affiliates_options->delete_option('hits_affiliate_show_inoperative');
        $from_date = null;
        $thru_date = null;
        $affiliate_id = null;
        $status = null;
        $expanded = null;
        $expanded_hits = null;
        $expanded_referrals = null;
        $show_inoperative = null;
    } else {
        if (isset($_POST['submitted'])) {
            // filter by date(s)
            if (!empty($_POST['from_date'])) {
                $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                $affiliates_options->update_option('hits_affiliate_from_date', $from_date);
            } else {
                $from_date = null;
                $affiliates_options->delete_option('hits_affiliate_from_date');
            }
            if (!empty($_POST['thru_date'])) {
                $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                $affiliates_options->update_option('hits_affiliate_thru_date', $thru_date);
            } else {
                $thru_date = null;
                $affiliates_options->delete_option('hits_affiliate_thru_date');
            }
            if ($from_date && $thru_date) {
                if (strtotime($from_date) > strtotime($thru_date)) {
                    $thru_date = null;
                    $affiliates_options->delete_option('hits_affiliate_thru_date');
                }
            }
            // filter by affiliate id
            if (!empty($_POST['affiliate_id'])) {
                $affiliate_id = affiliates_check_affiliate_id($_POST['affiliate_id']);
                if ($affiliate_id) {
                    $affiliates_options->update_option('hits_affiliate_affiliate_id', $affiliate_id);
                }
            } else {
                if (isset($_POST['affiliate_id'])) {
                    // empty && isset => '' => all
                    $affiliate_id = null;
                    $affiliates_options->delete_option('hits_affiliate_affiliate_id');
                }
            }
            if (!empty($_POST['status'])) {
                if (is_array($_POST['status'])) {
                    $stati = array();
                    foreach ($_POST['status'] as $status) {
                        if ($status = Affiliates_Utility::verify_referral_status_transition($status, $status)) {
                            $stati[] = $status;
                        }
                    }
                    if (count($stati) > 0) {
                        $status = $stati;
                        $affiliates_options->update_option('hits_affiliate_status', $stati);
                    } else {
                        $status = null;
                        $affiliates_options->delete_option('hits_affiliate_status');
                    }
                }
            } else {
                $status = null;
                $affiliates_options->delete_option('hits_affiliate_status');
            }
            // expanded details?
            if (!empty($_POST['expanded'])) {
                $expanded = true;
                $affiliates_options->update_option('hits_affiliate_expanded', true);
            } else {
                $expanded = false;
                $affiliates_options->delete_option('hits_affiliate_expanded');
            }
            if (!empty($_POST['expanded_hits'])) {
                $expanded_hits = true;
                $affiliates_options->update_option('hits_affiliate_expanded_hits', true);
            } else {
                $expanded_hits = false;
                $affiliates_options->delete_option('hits_affiliate_expanded_hits');
            }
            if (!empty($_POST['expanded_referrals'])) {
                $expanded_referrals = true;
                $affiliates_options->update_option('hits_affiliate_expanded_referrals', true);
            } else {
                $expanded_referrals = false;
                $affiliates_options->delete_option('hits_affiliate_expanded_referrals');
            }
            if (!empty($_POST['show_inoperative'])) {
                $show_inoperative = true;
                $affiliates_options->update_option('hits_affiliate_show_inoperative', true);
            } else {
                $show_inoperative = false;
                $affiliates_options->delete_option('hits_affiliate_show_inoperative');
            }
        }
    }
    if (isset($_POST['row_count'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_AFF_NONCE_1], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    if (isset($_POST['paged'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_AFF_NONCE_2], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('paged', $current_url);
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $referrals_table = _affiliates_get_tablename('referrals');
    $hits_table = _affiliates_get_tablename('hits');
    $output .= '<div>' . '<h1>' . __('Affiliates & Referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h1>' . '</div>';
    $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
    if ($row_count <= 0) {
        $row_count = $affiliates_options->get_option('hits_affiliate_per_page', AFFILIATES_HITS_AFFILIATE_PER_PAGE);
    } else {
        $affiliates_options->update_option('hits_affiliate_per_page', $row_count);
    }
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    if ($offset < 0) {
        $offset = 0;
    }
    $paged = isset($_REQUEST['paged']) ? intval($_REQUEST['paged']) : 0;
    if ($paged < 0) {
        $paged = 0;
    }
    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
    switch ($orderby) {
        case 'date':
        case 'visits':
        case 'hits':
        case 'referrals':
        case 'ratio':
        case 'name':
            break;
        default:
            $orderby = 'name';
    }
    $order = isset($_GET['order']) ? $_GET['order'] : null;
    switch ($order) {
        case 'asc':
        case 'ASC':
            $switch_order = 'DESC';
            break;
        case 'desc':
        case 'DESC':
            $switch_order = 'ASC';
            break;
        default:
            $order = 'ASC';
            $switch_order = 'DESC';
    }
    $filters = " WHERE 1=%d ";
    $filter_params = array(1);
    // We now have the desired dates from the user's point of view, i.e. in her timezone.
    // If supported, adjust the dates for the site's timezone:
    if ($from_date) {
        $from_datetime = DateHelper::u2s($from_date);
    }
    if ($thru_date) {
        $thru_datetime = DateHelper::u2s($thru_date, 24 * 3600);
    }
    if ($from_date && $thru_date) {
        $filters .= " AND datetime >= %s AND datetime < %s ";
        $filter_params[] = $from_datetime;
        $filter_params[] = $thru_datetime;
    } else {
        if ($from_date) {
            $filters .= " AND datetime >= %s ";
            $filter_params[] = $from_datetime;
        } else {
            if ($thru_date) {
                $filters .= " AND datetime < %s ";
                $filter_params[] = $thru_datetime;
            }
        }
    }
    if ($affiliate_id) {
        $filters .= " AND h.affiliate_id = %d ";
        $filter_params[] = $affiliate_id;
    }
    // how many are there ?
    $count_query = $wpdb->prepare("SELECT affiliate_id FROM {$hits_table} h\n\t\t{$filters}\n\t\tGROUP BY affiliate_id\n\t\t", $filter_params);
    $wpdb->query($count_query);
    $count = $wpdb->num_rows;
    if ($count > $row_count) {
        $paginate = true;
    } else {
        $paginate = false;
    }
    $pages = ceil($count / $row_count);
    if ($paged > $pages) {
        $paged = $pages;
    }
    if ($paged != 0) {
        $offset = ($paged - 1) * $row_count;
    }
    // Get the summarized results, these are grouped by date.
    // Note: Referrals on dates without a hit will not be included.
    // @see notes about this in affiliates_admin_hits()
    $date_condition = "";
    if ($from_date && $thru_date) {
        $date_condition = " AND datetime >= '" . $from_datetime . "' AND datetime < '" . $thru_datetime . "' ";
    } else {
        if ($from_date) {
            $date_condition = " AND datetime >= '" . $from_datetime . "' ";
        } else {
            if ($thru_date) {
                $date_condition = " AND datetime < '" . $thru_datetime . "' ";
            }
        }
    }
    $status_condition = "";
    if (is_array($status) && count($status) > 0) {
        $status_condition = " AND status IN ('" . implode("','", $status) . "') ";
    }
    $query = $wpdb->prepare("\n\t\t\tSELECT\n\t\t\t\t*,\n\t\t\t\tcount(distinct ip) visits,\n\t\t\t\tsum(count) hits,\n\t\t\t\t(SELECT COUNT(*) FROM {$referrals_table} WHERE affiliate_id = h.affiliate_id {$date_condition} {$status_condition} ) referrals,\n\t\t\t\t((SELECT COUNT(*) FROM {$referrals_table} WHERE affiliate_id = h.affiliate_id {$date_condition} {$status_condition} )/COUNT(DISTINCT ip)) ratio\n\t\t\tFROM {$hits_table} h\n\t\t\tLEFT JOIN {$affiliates_table} a ON h.affiliate_id = a.affiliate_id\n\t\t\t{$filters}\n\t\t\tGROUP BY h.affiliate_id\n\t\t\tORDER BY {$orderby} {$order}\n\t\t\tLIMIT {$row_count} OFFSET {$offset}\n\t\t\t", $filter_params);
    $results = $wpdb->get_results($query, OBJECT);
    $column_display_names = array('name' => __('Affiliate', AFFILIATES_PLUGIN_DOMAIN), 'visits' => __('Visitors', AFFILIATES_PLUGIN_DOMAIN), 'hits' => __('Hits', AFFILIATES_PLUGIN_DOMAIN), 'referrals' => __('Referrals', AFFILIATES_PLUGIN_DOMAIN), 'ratio' => __('Ratio', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '<div id="" class="hits-affiliates-overview">';
    $affiliates = affiliates_get_affiliates(true, !$show_inoperative);
    $affiliates_select = '';
    if (!empty($affiliates)) {
        $affiliates_select .= '<label class="affiliate-id-filter">';
        $affiliates_select .= __('Affiliate', AFFILIATES_PLUGIN_DOMAIN);
        $affiliates_select .= ' ';
        $affiliates_select .= '<select class="affiliate-id-filter" name="affiliate_id">';
        $affiliates_select .= '<option value="">--</option>';
        foreach ($affiliates as $affiliate) {
            if ($affiliate_id == $affiliate['affiliate_id']) {
                $selected = ' selected="selected" ';
            } else {
                $selected = '';
            }
            $affiliates_select .= '<option ' . $selected . ' value="' . esc_attr($affiliate['affiliate_id']) . '">' . esc_attr(stripslashes($affiliate['name'])) . '</option>';
        }
        $affiliates_select .= '</select>';
        $affiliates_select .= '</label>';
    }
    $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
    $status_icons = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => "<img class='icon' alt='" . __('Accepted', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/accepted.png'/>", AFFILIATES_REFERRAL_STATUS_CLOSED => "<img class='icon' alt='" . __('Closed', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/closed.png'/>", AFFILIATES_REFERRAL_STATUS_PENDING => "<img class='icon' alt='" . __('Pending', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/pending.png'/>", AFFILIATES_REFERRAL_STATUS_REJECTED => "<img class='icon' alt='" . __('Rejected', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/rejected.png'/>");
    $status_checkboxes = '';
    foreach ($status_descriptions as $key => $label) {
        $checked = empty($status) || is_array($status) && in_array($key, $status) ? ' checked="checked" ' : '';
        $status_checkboxes .= '<label style="padding-right:1em;">';
        $status_checkboxes .= sprintf('<input type="checkbox" name="status[]" value="%s" %s />', esc_attr($key), $checked);
        $status_checkboxes .= $status_icons[$key] . ' ' . $label;
        $status_checkboxes .= '</label>';
    }
    $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<div class="filter-section">' . $affiliates_select . '</div>' . '<div class="filter-section">' . '<label class="from-date-filter">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '</label>' . ' ' . '<label class="thru-date-filter">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="datefield thru-date-filter" name="thru_date" type="text" class="datefield" value="' . esc_attr($thru_date) . '"/>' . '</label>' . '</div>' . '<div class="filter-section">' . '<span style="padding-right:1em">' . __('Status', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . $status_checkboxes . '</div>' . '<div class="filter-section">' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_referrals" type="checkbox" ' . ($expanded_referrals ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand referrals', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . ' ' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_hits" type="checkbox" ' . ($expanded_hits ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand hits', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . ' ' . '<label class="show-inoperative-filter">' . '<input class="show-inoperative-filter" name="show_inoperative" type="checkbox" ' . ($show_inoperative ? 'checked="checked"' : '') . '/>' . ' ' . __('Include inoperative affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</div>' . '<div class="filter-buttons">' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_AFF_FILTER_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</div>' . '</form>' . '</div>';
    $output .= '
		<div class="page-options">
			<form id="setrowcount" action="" method="post">
				<div>
					<label for="row_count">' . __('Results per page', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />
					' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_AFF_NONCE_1, true, false) . '
					<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>
				</div>
			</form>
		</div>
		';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<form id="posts-filter" method="post" action="">';
        $output .= '<div>';
        $output .= wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_AFF_NONCE_2, true, false);
        $output .= '</div>';
        $output .= '<div class="tablenav top">';
        $output .= $pagination->pagination('top');
        $output .= '</div>';
        $output .= '</form>';
    }
    $output .= '
		<table id="" class="wp-list-table widefat fixed" cellspacing="0">
		<thead>
			<tr>
			';
    foreach ($column_display_names as $key => $column_display_name) {
        $options = array('orderby' => $key, 'order' => $switch_order);
        $class = "";
        if (strcmp($key, $orderby) == 0) {
            $lorder = strtolower($order);
            $class = "{$key} manage-column sorted {$lorder}";
        } else {
            $class = "{$key} manage-column sortable";
        }
        $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
        $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
    }
    $output .= '</tr>
		</thead>
		<tbody>
		';
    if (count($results) > 0) {
        for ($i = 0; $i < count($results); $i++) {
            $result = $results[$i];
            $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
            $affiliate = affiliates_get_affiliate($result->affiliate_id);
            $output .= "<td class='affiliate-name'>" . stripslashes(wp_filter_nohtml_kses($affiliate['name'])) . "</td>";
            $output .= "<td class='visits'>{$result->visits}</td>";
            $output .= "<td class='hits'>{$result->hits}</td>";
            $output .= "<td class='referrals'>{$result->referrals}</td>";
            $output .= "<td class='ratio'>{$result->ratio}</td>";
            $output .= '</tr>';
            if ($expanded || $expanded_referrals || $expanded_hits) {
                //
                // expanded : referrals ----------------------------------------
                //
                if ($expanded_referrals) {
                    // get the detailed results for referrals
                    $referrals_filters = " WHERE r.affiliate_id = %d ";
                    $referrals_filter_params = array($result->affiliate_id);
                    if ($from_date && $thru_date) {
                        $referrals_filters .= " AND datetime >= %s AND datetime < %s ";
                        $referrals_filter_params[] = $from_datetime;
                        $referrals_filter_params[] = $thru_datetime;
                    } else {
                        if ($from_date) {
                            $referrals_filters .= " AND datetime >= %s ";
                            $referrals_filter_params[] = $from_datetime;
                        } else {
                            if ($thru_date) {
                                $referrals_filters .= " datetime < %s ";
                                $referrals_filter_params[] = $thru_datetime;
                            }
                        }
                    }
                    $referrals_orderby = "datetime {$order}";
                    $referrals_query = $wpdb->prepare("SELECT *\n\t\t\t\t\t\tFROM {$referrals_table} r\n\t\t\t\t\t\tLEFT JOIN {$affiliates_table} a ON r.affiliate_id = a.affiliate_id\n\t\t\t\t\t\t{$referrals_filters}\n\t\t\t\t\t\tORDER BY {$referrals_orderby}\n\t\t\t\t\t\t", $referrals_filter_params);
                    $referrals = $wpdb->get_results($referrals_query, OBJECT);
                    if (count($referrals) > 0) {
                        $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                        $output .= '<td colspan="5">';
                        $output .= '<div class="details-referrals">';
                        $output .= '<p class="description">' . __('Referrals', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
                        $output .= '
							<table id="details-referrals-' . esc_attr($result->date) . '" class="details-referrals" cellspacing="0">
							<thead>
							<tr>
							<th scope="col" class="datetime">' . __('Time', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							<th scope="col" class="post-id">' . __('Post', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							<th scope="col" class="affiliate-id">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</th>
							</tr>
							</thead>
							<tbody>
							';
                        foreach ($referrals as $referral) {
                            $output .= '<tr class="details-referrals ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                            $output .= "<td class='datetime'>" . DateHelper::s2u($referral->datetime) . "</td>";
                            $link = get_permalink($referral->post_id);
                            $title = get_the_title($referral->post_id);
                            $output .= '<td class="post-id"><a href="' . esc_attr($link) . '" target="_blank">' . stripslashes(wp_filter_nohtml_kses($title)) . '</a></td>';
                            $output .= "<td class='affiliate-id'>" . stripslashes(wp_filter_nohtml_kses($referral->name)) . "</td>";
                            $output .= '</tr>';
                        }
                        $output .= '</tbody></table>';
                        $output .= '</div>';
                        // .details-referrals
                        $output .= '</td></tr>';
                    }
                }
                // if $expanded_referrals
                //
                // expanded : hits ----------------------------------------
                //
                if ($expanded_hits) {
                    // get the detailed results for hits
                    $details_orderby = "date {$order}, time {$order}";
                    $details_filters = " WHERE h.affiliate_id = %d ";
                    $details_filter_params = array($result->affiliate_id);
                    if ($from_date && $thru_date) {
                        $details_filters .= " AND datetime >= %s AND datetime < %s ";
                        $details_filter_params[] = $from_datetime;
                        $details_filter_params[] = $thru_datetime;
                    } else {
                        if ($from_date) {
                            $details_filters .= " AND datetime >= %s ";
                            $details_filter_params[] = $from_datetime;
                        } else {
                            if ($thru_date) {
                                $details_filters .= " datetime < %s ";
                                $details_filter_params[] = $thru_datetime;
                            }
                        }
                    }
                    $details_query = $wpdb->prepare("SELECT *\n\t\t\t\t\t\tFROM {$hits_table} h\n\t\t\t\t\t\tLEFT JOIN {$affiliates_table} a ON h.affiliate_id = a.affiliate_id\n\t\t\t\t\t\t{$details_filters}\n\t\t\t\t\t\tORDER BY {$details_orderby}\n\t\t\t\t\t\t", $details_filter_params);
                    $hits = $wpdb->get_results($details_query, OBJECT);
                    $output .= '<tr class=" ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                    $output .= '<td colspan="5">';
                    $output .= '<div class="details-hits">';
                    $output .= '<p class="description">' . __('Hits', AFFILIATES_PLUGIN_DOMAIN) . '</p>';
                    $output .= '
						<table id="details-hits-' . esc_attr($result->date) . '" class="details-hits" cellspacing="0">
						<thead>
						<tr>
						<th scope="col" class="date">' . __('Date', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="time">' . __('Time', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="ip">' . __('IP', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="count">' . __('Count', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						<th scope="col" class="affiliate-id">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</th>
						</tr>
						</thead>
						<tbody>
						';
                    foreach ($hits as $hit) {
                        $output .= '<tr class="details ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                        //						$output .= "<td class='date'>$hit->date</td>";
                        $output .= '<td class="date">' . DateHelper::formatDate(DateHelper::s2u($hit->datetime)) . '</td>';
                        //						$output .= "<td class='time'>$hit->time</td>";
                        $output .= '<td class="time">' . DateHelper::formatTime(DateHelper::s2u($hit->datetime)) . '</td>';
                        $output .= "<td class='ip'>" . long2ip($hit->ip) . "</td>";
                        $output .= "<td class='count'>{$hit->count}</td>";
                        $output .= "<td class='affiliate-id'>" . stripslashes(wp_filter_nohtml_kses($hit->name)) . "</td>";
                        $output .= '</tr>';
                    }
                    $output .= '</tbody></table>';
                    $output .= '</div>';
                    // .details-hits
                    $output .= '</td></tr>';
                }
                // if $expanded_hits
            }
            // expanded
        }
    } else {
        $output .= '<tr><td colspan="5">' . __('There are no results.', AFFILIATES_PLUGIN_DOMAIN) . '</td></tr>';
    }
    $output .= '</tbody>';
    $output .= '</table>';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<div class="tablenav bottom">';
        $output .= $pagination->pagination('bottom');
        $output .= '</div>';
    }
    $output .= '</div>';
    // .visits-overview
    echo $output;
    affiliates_footer();
}
        public static function view()
        {
            global $wpdb, $affiliates_options;
            $output = '';
            $today = date('Y-m-d', time());
            if (!current_user_can(AFFILIATES_ACCESS_AFFILIATES)) {
                wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
            }
            if (isset($_GET['action'])) {
                switch ($_GET['action']) {
                    case 'close_referrals':
                        $params = array('tables' => array('referrals' => _affiliates_get_tablename('referrals'), 'affiliates' => _affiliates_get_tablename('affiliates'), 'affiliates_users' => _affiliates_get_tablename('affiliates_users'), 'users' => $wpdb->users));
                        $params = array_merge($_GET, $params);
                        echo self::update_status(AFFILIATES_REFERRAL_STATUS_CLOSED, $params);
                        die;
                        break;
                }
            }
            $from_date = $affiliates_options->get_option('totals_from_date', null);
            $from_datetime = null;
            $thru_date = $affiliates_options->get_option('totals_thru_date', null);
            $thru_datetime = null;
            $referral_status = $affiliates_options->get_option('totals_referral_status', null);
            $currency_id = $affiliates_options->get_option('totals_currency_id', null);
            if (isset($_POST['clear_filters']) || isset($_POST['submitted'])) {
                if (!wp_verify_nonce($_POST[self::NONCE], self::SET_FILTERS)) {
                    wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
                }
            }
            if (isset($_POST['clear_filters'])) {
                $affiliates_options->delete_option('totals_from_date');
                $affiliates_options->delete_option('totals_thru_date');
                $affiliates_options->delete_option('totals_referral_status');
                $affiliates_options->delete_option('totals_currency_id');
                $from_date = null;
                $from_datetime = null;
                $thru_date = null;
                $thru_datetime = null;
                $referral_status = null;
                $currency_id = null;
            } else {
                if (isset($_POST['submitted'])) {
                    if (!empty($_POST['from_date'])) {
                        $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                        $affiliates_options->update_option('totals_from_date', $from_date);
                    } else {
                        $from_date = null;
                        $affiliates_options->delete_option('totals_from_date');
                    }
                    if (!empty($_POST['thru_date'])) {
                        $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                        $affiliates_options->update_option('totals_thru_date', $thru_date);
                    } else {
                        $thru_date = null;
                        $affiliates_options->delete_option('totals_thru_date');
                    }
                    if ($from_date && $thru_date) {
                        if (strtotime($from_date) > strtotime($thru_date)) {
                            $thru_date = null;
                            $affiliates_options->delete_option('totals_thru_date');
                        }
                    }
                    if (!empty($_POST['referral_status']) && ($referral_status = Affiliates_Utility::verify_referral_status_transition($_POST['referral_status'], $_POST['referral_status']))) {
                        $affiliates_options->update_option('totals_referral_status', $referral_status);
                    } else {
                        $referral_status = null;
                        $affiliates_options->delete_option('totals_referral_status');
                    }
                    if (!empty($_POST['currency_id']) && ($currency_id = Affiliates_Utility::verify_currency_id($_POST['currency_id']))) {
                        $affiliates_options->update_option('totals_currency_id', $currency_id);
                    } else {
                        $currency_id = null;
                        $affiliates_options->delete_option('totals_currency_id');
                    }
                }
            }
            if (isset($_POST['row_count'])) {
                if (!wp_verify_nonce($_POST[self::NONCE_1], self::SET_RPP)) {
                    wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
                }
            }
            if (isset($_POST['paged'])) {
                if (!wp_verify_nonce($_POST[self::NONCE_2], self::SET_PAGE)) {
                    wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
                }
            }
            $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
            $current_url = remove_query_arg('paged', $current_url);
            $current_url = remove_query_arg('action', $current_url);
            $current_url = remove_query_arg('affiliate_id', $current_url);
            $referrals_table = _affiliates_get_tablename('referrals');
            $affiliates_table = _affiliates_get_tablename('affiliates');
            $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
            $output .= '<div class="totals">';
            $output .= '<h1>';
            $output .= __('Totals', AFFILIATES_PLUGIN_DOMAIN);
            $output .= '</h1>';
            $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
            if ($row_count <= 0) {
                $row_count = $affiliates_options->get_option('totals_per_page', self::TOTALS_PER_PAGE);
            } else {
                $affiliates_options->update_option('totals_per_page', $row_count);
            }
            $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
            if ($offset < 0) {
                $offset = 0;
            }
            $paged = isset($_REQUEST['paged']) ? intval($_REQUEST['paged']) : 0;
            if ($paged < 0) {
                $paged = 0;
            }
            $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
            switch ($orderby) {
                case 'affiliate_id':
                case 'name':
                case 'user_login':
                case 'email':
                case 'total':
                case 'currency_id':
                    break;
                default:
                    $orderby = 'name';
            }
            $order = isset($_GET['order']) ? $_GET['order'] : null;
            switch ($order) {
                case 'asc':
                case 'ASC':
                    $switch_order = 'DESC';
                    break;
                case 'desc':
                case 'DESC':
                    $switch_order = 'ASC';
                    break;
                default:
                    $order = 'ASC';
                    $switch_order = 'DESC';
            }
            $filters = array(" 1=%d ");
            $filter_params = array(1);
            // We have the desired dates from the user's point of view, i.e. in her timezone.
            // If supported, adjust the dates for the site's timezone:
            if ($from_date) {
                $from_datetime = DateHelper::u2s($from_date);
            }
            if ($thru_date) {
                $thru_datetime = DateHelper::u2s($thru_date, 24 * 3600);
            }
            if ($from_datetime && $thru_datetime) {
                $filters[] = " r.datetime >= %s AND r.datetime < %s ";
                $filter_params[] = $from_datetime;
                $filter_params[] = $thru_datetime;
            } else {
                if ($from_datetime) {
                    $filters[] = " r.datetime >= %s ";
                    $filter_params[] = $from_datetime;
                } else {
                    if ($thru_datetime) {
                        $filters[] = " r.datetime < %s ";
                        $filter_params[] = $thru_datetime;
                    }
                }
            }
            if ($referral_status) {
                $filters[] = " r.status = %s ";
                $filter_params[] = $referral_status;
            }
            if ($currency_id) {
                $filters[] = " r.currency_id = %s ";
                $filter_params[] = $currency_id;
            }
            if (!empty($filters)) {
                $filters = " WHERE " . implode(" AND ", $filters);
            } else {
                $filters = '';
            }
            $having = '';
            // note double select to obtain number of rows (otherwise group counts are obtained)
            $count = $wpdb->get_var($wpdb->prepare("\n\t\t\tSELECT COUNT(*) FROM (\n\t\t\tSELECT r.affiliate_id\n\t\t\tFROM {$referrals_table} r\n\t\t\tLEFT JOIN {$affiliates_table} a ON r.affiliate_id = a.affiliate_id\n\t\t\tLEFT JOIN {$affiliates_users_table} au ON a.affiliate_id = au.affiliate_id\n\t\t\tLEFT JOIN {$wpdb->users} u on au.user_id = u.ID\n\t\t\t{$filters} \n\t\t\tGROUP BY r.affiliate_id, r.currency_id\n\t\t\t{$having}\n\t\t\t) tmp\n\t\t\t", $filter_params));
            if ($count > $row_count) {
                $paginate = true;
            } else {
                $paginate = false;
            }
            $pages = ceil($count / $row_count);
            if ($paged > $pages) {
                $paged = $pages;
            }
            if ($paged != 0) {
                $offset = ($paged - 1) * $row_count;
            }
            $results = $wpdb->get_results($wpdb->prepare("\n\t\t\tSELECT a.*, u.user_login, SUM(r.amount) as total, r.currency_id\n\t\t\tFROM {$referrals_table} r\n\t\t\tLEFT JOIN {$affiliates_table} a ON r.affiliate_id = a.affiliate_id\n\t\t\tLEFT JOIN {$affiliates_users_table} au ON a.affiliate_id = au.affiliate_id\n\t\t\tLEFT JOIN {$wpdb->users} u on au.user_id = u.ID\n\t\t\t{$filters}\n\t\t\tGROUP BY r.affiliate_id, r.currency_id\n\t\t\t{$having}\n\t\t\tORDER BY {$orderby} {$order} LIMIT {$row_count} OFFSET {$offset}\n\t\t\t", $filter_params));
            $column_display_names = array('affiliate_id' => __('Id', AFFILIATES_PLUGIN_DOMAIN), 'name' => __('Affiliate', AFFILIATES_PLUGIN_DOMAIN), 'email' => __('Email', AFFILIATES_PLUGIN_DOMAIN), 'user_login' => __('Username', AFFILIATES_PLUGIN_DOMAIN), 'total' => __('Total', AFFILIATES_PLUGIN_DOMAIN), 'currency_id' => __('Currency', AFFILIATES_PLUGIN_DOMAIN));
            $output .= '<div class="totals-overview">';
            $mp_params = "";
            if (!empty($from_date)) {
                $mp_params .= "&from_date=" . urlencode($from_date);
            }
            if (!empty($thru_date)) {
                $mp_params .= "&thru_date=" . urlencode($thru_date);
            }
            if (!empty($referral_status)) {
                $mp_params .= "&referral_status=" . urlencode($referral_status);
            }
            if (!empty($currency_id)) {
                $mp_params .= "&currency_id=" . urlencode($currency_id);
            }
            if (!empty($orderby)) {
                $mp_params .= "&orderby=" . urlencode($orderby);
            }
            if (!empty($order)) {
                $mp_params .= "&order=" . urlencode($order);
            }
            $output .= '<style type="text/css">';
            $output .= '.close-referrals img, .close-referrals span.label { vertical-align: middle; }';
            $output .= '</style>';
            $output .= '<div class="manage">';
            $output .= '<p>';
            $output .= "<a title='" . __('Click to close these referrals', AFFILIATES_PLUGIN_DOMAIN) . "' " . "class='button close-referrals' " . "href='" . esc_url($current_url) . "&action=close_referrals" . $mp_params . "'>" . "<img class='icon' alt='" . __('Close referrals', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/closed.png'/>" . "<span class='label'>" . __('Close Referrals', AFFILIATES_PLUGIN_DOMAIN) . "</span>" . "</a>";
            $output .= "</p>";
            $output .= '</div>';
            $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
            $status_select = '<label class="referral-status-filter" for="referral_status">' . __('Referral Status', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
            $status_select .= ' ';
            $status_select .= '<select class="referral-status-filter" name="referral_status">';
            $status_select .= '<option value="" ' . (empty($referral_status) ? ' selected="selected" ' : '') . '>--</option>';
            foreach ($status_descriptions as $key => $label) {
                $selected = $key == $referral_status ? ' selected="selected" ' : '';
                $status_select .= '<option ' . $selected . ' value="' . esc_attr($key) . '">' . $label . '</option>';
            }
            $status_select .= '</select>';
            $currencies = $wpdb->get_results("SELECT DISTINCT(currency_id) FROM {$referrals_table} WHERE currency_id IS NOT NULL");
            $currency_select = '<label class="currency-id-filter" for="currency_id">' . __('Currency', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
            $currency_select .= ' ';
            $currency_select .= '<select class="currency-id-filter" name="currency_id">';
            $currency_select .= '<option value="" ' . (empty($currency_id) ? ' selected="selected" ' : '') . '>--</option>';
            foreach ($currencies as $currency) {
                $selected = $currency->currency_id == $currency_id ? ' selected="selected" ' : '';
                $currency_select .= '<option ' . $selected . ' value="' . esc_attr($currency->currency_id) . '">' . $currency->currency_id . '</option>';
            }
            $currency_select .= '</select>';
            $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<p>' . $status_select . ' ' . $currency_select . '</p>' . '<p>' . '<label class="from-date-filter" for="from_date">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '<label class="thru-date-filter" for="thru_date">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield thru-date-filter" name="thru_date" type="text" class="datefield" value="' . esc_attr($thru_date) . '"/>' . '</p>
					<p>' . wp_nonce_field(self::SET_FILTERS, self::NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</p>' . '</form>' . '</div>';
            $output .= '
			<div class="page-options">
				<form id="setrowcount" action="" method="post">
					<div>
						<label for="row_count">' . __('Results per page', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />
						' . wp_nonce_field(self::SET_RPP, self::NONCE_1, true, false) . '
						<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>
					</div>
				</form>
			</div>
			';
            if ($paginate) {
                require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
                $pagination = new Affiliates_Pagination($count, null, $row_count);
                $output .= '<form id="posts-filter" method="post" action="">';
                $output .= '<div>';
                $output .= wp_nonce_field(self::SET_PAGE, self::NONCE_2, true, false);
                $output .= '</div>';
                $output .= '<div class="tablenav top">';
                $output .= $pagination->pagination('top');
                $output .= '</div>';
                $output .= '</form>';
            }
            $output .= '
			<table class="wp-list-table widefat fixed" cellspacing="0">
			<thead>
				<tr>
				';
            foreach ($column_display_names as $key => $column_display_name) {
                $options = array('orderby' => $key, 'order' => $switch_order);
                $class = $key;
                if (!in_array($key, array('edit', 'remove', 'links'))) {
                    if (strcmp($key, $orderby) == 0) {
                        $lorder = strtolower($order);
                        $class = "{$key} manage-column sorted {$lorder}";
                    } else {
                        $class = "{$key} manage-column sortable";
                    }
                    $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
                }
                $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
            }
            $output .= '</tr>
			</thead>
			<tbody>
			';
            if (count($results) > 0) {
                for ($i = 0; $i < count($results); $i++) {
                    $result = $results[$i];
                    $name_suffix = '';
                    $class_deleted = '';
                    if ($is_deleted = strcmp($result->status, 'deleted') == 0) {
                        $class_deleted = ' deleted ';
                        $name_suffix .= " " . __('(removed)', AFFILIATES_PLUGIN_DOMAIN);
                    }
                    $class_inoperative = '';
                    if ($is_inoperative = !($result->from_date <= $today && ($result->thru_date == null || $result->thru_date >= $today))) {
                        $class_inoperative = ' inoperative ';
                        $name_suffix .= " " . __('(inoperative)', AFFILIATES_PLUGIN_DOMAIN);
                    }
                    $output .= '<tr class="' . $class_deleted . $class_inoperative . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                    $output .= "<td class='affiliate-id'>";
                    if (affiliates_encode_affiliate_id($result->affiliate_id) != $result->affiliate_id) {
                        $output .= '<span class="encoded-hint" title="' . affiliates_encode_affiliate_id($result->affiliate_id) . '">' . $result->affiliate_id . '</span>';
                    } else {
                        $output .= $result->affiliate_id;
                    }
                    $output .= "</td>";
                    $output .= "<td class='affiliate-name'>" . stripslashes(wp_filter_nohtml_kses($result->name)) . $name_suffix . "</td>";
                    $output .= "<td class='affiliate-email'>" . $result->email . "</td>";
                    $output .= "<td class='affiliate-user-login'>" . $result->user_login . "</td>";
                    $output .= "<td class='total'>{$result->total}</td>";
                    $output .= "<td class='currency-id'>{$result->currency_id}</td>";
                    $output .= '</tr>';
                }
            } else {
                $output .= '<tr><td colspan="' . count($column_display_names) . '">' . __('There are no results.', AFFILIATES_PLUGIN_DOMAIN) . '</td></tr>';
            }
            $output .= '</tbody>';
            $output .= '</table>';
            if ($paginate) {
                $pagination = new Affiliates_Pagination($count, null, $row_count);
                $output .= '<div class="tablenav bottom">';
                $output .= $pagination->pagination('bottom');
                $output .= '</div>';
            }
            $output .= '</div>';
            // .totals-overview
            $output .= '</div>';
            // .totals
            echo $output;
            affiliates_footer();
        }
function affiliate_referrer_info($attr = array(), $content = null)
{
    global $wpdb;
    $affiliate_referrer = 1;
    $active_plugins = get_option('active_plugins', array());
    $affiliates_pro_is_active = in_array('affiliates-pro/affiliates-pro.php', $active_plugins);
    $affiliates_entr_is_active = in_array('affiliates-pro/affiliates-enterprise.php', $active_plugins);
    $options = shortcode_atts(array('direct' => false, 'display' => 'user_login'), $attr);
    extract($options);
    $output = '';
    $user_id = get_current_user_id();
    if ($affiliates_entr_is_active) {
        $relations_table = _affiliates_get_tablename('affiliates_relations');
        if ($user_id && affiliates_user_is_affiliate($user_id)) {
            if ($affiliate_ids = affiliates_get_user_affiliate($user_id)) {
                foreach ($affiliate_ids as $affiliate_id) {
                    if ($affiliate_referrer = $wpdb->get_var($wpdb->prepare("SELECT from_affiliate_id FROM {$relations_table} WHERE to_affiliate_id=%d ", $affiliate_id))) {
                        continue;
                    }
                }
            }
        }
    } else {
        if ($affiliates_pro_is_active) {
            $affiliate_referrers = get_option('affiliate_referrers');
            $relations = count($affiliate_referrers);
            if ($user_id && affiliates_user_is_affiliate($user_id)) {
                if ($affiliate_ids = affiliates_get_user_affiliate($user_id)) {
                    $affiliate_id = $affiliate_ids[0];
                    for ($i = 0; $i <= $relations; $i++) {
                        foreach ($affiliate_referrers[$i] as $key => $value) {
                            if ($affiliate_id == $value) {
                                $affiliate_referrer = $key;
                            }
                        }
                    }
                }
            }
        } else {
            echo "<div class='error'>The <strong>Affiliates Referrer Info</strong> plugin requires on of the Affiliates plugins by <a href='http://itthinx.com'>Itthinx</a> to be installed and activated.</div>";
        }
    }
    if ($user_id = affiliates_get_affiliate_user($affiliate_referrer)) {
        if ($user = get_user_by('id', $user_id)) {
            switch ($display) {
                case 'user_login':
                    $output .= $user->user_login;
                    break;
                case 'user_nicename':
                    $output .= $user->user_nicename;
                    break;
                case 'user_email':
                    $output .= $user->user_email;
                    break;
                case 'user_url':
                    $output .= $user->user_url;
                    break;
                case 'display_name':
                    $output .= $user->display_name;
                    break;
                default:
                    $output .= $user->user_login;
            }
            $output = wp_strip_all_tags($output);
        }
    }
    return $output;
}
/**
 * Referrals screen.
 */
function affiliates_admin_referrals()
{
    global $wpdb, $affiliates_options;
    $output = '';
    if (!current_user_can(AFFILIATES_ACCESS_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    // $_GET actions
    if (isset($_GET['action'])) {
        switch ($_GET['action']) {
            case 'edit':
                require_once AFFILIATES_CORE_LIB . '/affiliates-admin-referral-edit.php';
                if (isset($_GET['referral_id'])) {
                    return affiliates_admin_referral_edit(intval($_GET['referral_id']));
                } else {
                    return affiliates_admin_referral_edit();
                }
                break;
            case 'remove':
                if (isset($_GET['referral_id'])) {
                    require_once AFFILIATES_CORE_LIB . '/affiliates-admin-referral-remove.php';
                    return affiliates_admin_referral_remove($_GET['referral_id']);
                }
                break;
        }
    }
    if (isset($_POST['from_date']) || isset($_POST['thru_date']) || isset($_POST['clear_filters']) || isset($_POST['affiliate_id']) || isset($_POST['status']) || isset($_POST['search']) || isset($_POST['expanded']) || isset($_POST['expanded_data']) || isset($_POST['expanded_description']) || isset($_POST['show_inoperative'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_FILTER_NONCE], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $referrals_table = _affiliates_get_tablename('referrals');
    $hits_table = _affiliates_get_tablename('hits');
    $posts_table = $wpdb->prefix . 'posts';
    // actions
    if (isset($_POST['affiliate_id']) && isset($_POST['post_id']) && isset($_POST['datetime']) && isset($_POST['action'])) {
        if (isset($_POST['status'])) {
            $referral = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$referrals_table} WHERE affiliate_id = %d AND post_id = %d AND datetime = %s", intval($_POST['affiliate_id']), intval($_POST['post_id']), $_POST['datetime']));
            if ($referral) {
                if (Affiliates_Utility::verify_referral_status_transition($referral->status, $_POST['status'])) {
                    $wpdb->query($wpdb->prepare("UPDATE {$referrals_table} SET status = %s WHERE affiliate_id = %d AND post_id = %d AND datetime = %s AND status = %s", $_POST['status'], intval($referral->affiliate_id), intval($referral->post_id), $referral->datetime, $referral->status));
                }
            }
        }
    }
    // filters
    $from_date = $affiliates_options->get_option('referrals_from_date', null);
    $thru_date = $affiliates_options->get_option('referrals_thru_date', null);
    $affiliate_id = $affiliates_options->get_option('referrals_affiliate_id', null);
    $status = $affiliates_options->get_option('referrals_status', null);
    $search = $affiliates_options->get_option('referrals_search', null);
    $search_description = $affiliates_options->get_option('referrals_search_description', null);
    $expanded = $affiliates_options->get_option('referrals_expanded', null);
    $expanded_description = $affiliates_options->get_option('referrals_expanded_description', null);
    $expanded_data = $affiliates_options->get_option('referrals_expanded_data', null);
    $show_inoperative = $affiliates_options->get_option('referrals_show_inoperative', null);
    if (!isset($_POST['action']) && isset($_POST['clear_filters'])) {
        $affiliates_options->delete_option('referrals_from_date');
        $affiliates_options->delete_option('referrals_thru_date');
        $affiliates_options->delete_option('referrals_affiliate_id');
        $affiliates_options->delete_option('referrals_status');
        $affiliates_options->delete_option('referrals_search');
        $affiliates_options->delete_option('referrals_expanded');
        $affiliates_options->delete_option('referrals_expanded_description');
        $affiliates_options->delete_option('referrals_expanded_data');
        $affiliates_options->delete_option('referrals_show_inoperative');
        $from_date = null;
        $thru_date = null;
        $affiliate_id = null;
        $status = null;
        $search = null;
        $search_description = null;
        $expanded = null;
        $expanded_data = null;
        $expanded_description = null;
        $show_inoperative = null;
    } else {
        if (!isset($_POST['action']) && isset($_POST['submitted'])) {
            // filter by date(s)
            if (!empty($_POST['from_date'])) {
                $from_date = date('Y-m-d', strtotime($_POST['from_date']));
                $affiliates_options->update_option('referrals_from_date', $from_date);
            } else {
                $from_date = null;
                $affiliates_options->delete_option('referrals_from_date');
            }
            if (!empty($_POST['thru_date'])) {
                $thru_date = date('Y-m-d', strtotime($_POST['thru_date']));
                $affiliates_options->update_option('referrals_thru_date', $thru_date);
            } else {
                $thru_date = null;
                $affiliates_options->delete_option('referrals_thru_date');
            }
            if ($from_date && $thru_date) {
                if (strtotime($from_date) > strtotime($thru_date)) {
                    $thru_date = null;
                    $affiliates_options->delete_option('referrals_thru_date');
                }
            }
            // filter by affiliate id
            if (!empty($_POST['affiliate_id'])) {
                $affiliate_id = affiliates_check_affiliate_id($_POST['affiliate_id']);
                if ($affiliate_id) {
                    $affiliates_options->update_option('referrals_affiliate_id', $affiliate_id);
                }
            } else {
                if (isset($_POST['affiliate_id'])) {
                    // empty && isset => '' => all
                    $affiliate_id = null;
                    $affiliates_options->delete_option('referrals_affiliate_id');
                }
            }
            if (!empty($_POST['status'])) {
                if ($status = Affiliates_Utility::verify_referral_status_transition($_POST['status'], $_POST['status'])) {
                    $affiliates_options->update_option('referrals_status', $status);
                } else {
                    $status = null;
                    $affiliates_options->delete_option('referrals_status');
                }
            } else {
                $status = null;
                $affiliates_options->delete_option('referrals_status');
            }
            if (!empty($_POST['search'])) {
                $search = $_POST['search'];
                $affiliates_options->update_option('referrals_search', $_POST['search']);
            } else {
                $search = null;
                $affiliates_options->delete_option('referrals_search');
            }
            if (!empty($_POST['search_description'])) {
                $search_description = true;
                $affiliates_options->update_option('referrals_search_description', true);
            } else {
                $search_description = false;
                $affiliates_options->delete_option('referrals_search_description');
            }
            // expanded details?
            if (!empty($_POST['expanded'])) {
                $expanded = true;
                $affiliates_options->update_option('referrals_expanded', true);
            } else {
                $expanded = false;
                $affiliates_options->delete_option('referrals_expanded');
            }
            if (!empty($_POST['expanded_data'])) {
                $expanded_data = true;
                $affiliates_options->update_option('referrals_expanded_data', true);
            } else {
                $expanded_data = false;
                $affiliates_options->delete_option('referrals_expanded_data');
            }
            if (!empty($_POST['expanded_description'])) {
                $expanded_description = true;
                $affiliates_options->update_option('referrals_expanded_description', true);
            } else {
                $expanded_description = false;
                $affiliates_options->delete_option('referrals_expanded_description');
            }
            if (!empty($_POST['show_inoperative'])) {
                $show_inoperative = true;
                $affiliates_options->update_option('referrals_show_inoperative', true);
            } else {
                $show_inoperative = false;
                $affiliates_options->delete_option('referrals_show_inoperative');
            }
        }
    }
    if (isset($_POST['row_count'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_NONCE_1], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    if (isset($_POST['paged'])) {
        if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_HITS_NONCE_2], 'admin')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('paged', $current_url);
    $output .= '<div>' . '<h2>' . __('Referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>';
    $output .= '<div class="manage add">';
    $output .= sprintf('<a title="%s" class="add button" href="%s"><img class="icon" alt="%s" src="%s" /><span class="label">%s</span></a>', __('Click to add a referral manually', AFFILIATES_PLUGIN_DOMAIN), esc_url(add_query_arg('action', 'edit', $current_url)), __('Add', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_PLUGIN_URL . 'images/add.png', __('Add', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '</div>';
    $row_count = isset($_POST['row_count']) ? intval($_POST['row_count']) : 0;
    if ($row_count <= 0) {
        $row_count = $affiliates_options->get_option('referrals_per_page', AFFILIATES_HITS_PER_PAGE);
    } else {
        $affiliates_options->update_option('referrals_per_page', $row_count);
    }
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;
    if ($offset < 0) {
        $offset = 0;
    }
    $paged = isset($_GET['paged']) ? intval($_GET['paged']) : 0;
    if ($paged < 0) {
        $paged = 0;
    }
    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : null;
    switch ($orderby) {
        case 'datetime':
        case 'name':
        case 'post_title':
        case 'amount':
        case 'currency_id':
        case 'status':
            break;
        default:
            $orderby = 'datetime';
    }
    $order = isset($_GET['order']) ? $_GET['order'] : null;
    switch ($order) {
        case 'asc':
        case 'ASC':
            $switch_order = 'DESC';
            break;
        case 'desc':
        case 'DESC':
            $switch_order = 'ASC';
            break;
        default:
            $order = 'DESC';
            $switch_order = 'ASC';
    }
    if ($from_date || $thru_date || $affiliate_id || $status || $search) {
        $filters = " WHERE ";
    } else {
        $filters = '';
    }
    $filter_params = array();
    // We have the desired dates from the user's point of view, i.e. in her timezone.
    // If supported, adjust the dates for the site's timezone:
    if ($from_date) {
        $from_datetime = DateHelper::u2s($from_date);
    }
    if ($thru_date) {
        $thru_datetime = DateHelper::u2s($thru_date, 24 * 3600);
    }
    if ($from_date && $thru_date) {
        $filters .= " datetime >= %s AND datetime < %s ";
        $filter_params[] = $from_datetime;
        $filter_params[] = $thru_datetime;
    } else {
        if ($from_date) {
            $filters .= " datetime >= %s ";
            $filter_params[] = $from_datetime;
        } else {
            if ($thru_date) {
                $filters .= " datetime < %s ";
                $filter_params[] = $thru_datetime;
            }
        }
    }
    if ($affiliate_id) {
        if ($from_date || $thru_date) {
            $filters .= " AND ";
        }
        $filters .= " r.affiliate_id = %d ";
        $filter_params[] = $affiliate_id;
    }
    if ($status) {
        if ($from_date || $thru_date || $affiliate_id) {
            $filters .= " AND ";
        }
        $filters .= " r.status = %s ";
        $filter_params[] = $status;
    }
    if ($search) {
        if ($from_date || $thru_date || $affiliate_id || $status) {
            $filters .= " AND ";
        }
        if ($search_description) {
            $filters .= " ( r.data LIKE '%%%s%%' OR r.description LIKE '%%%s%%' ) ";
            $filter_params[] = $search;
            $filter_params[] = $search;
        } else {
            $filters .= " r.data LIKE '%%%s%%' ";
            $filter_params[] = $search;
        }
    }
    // how many are there ?
    $count_query = $wpdb->prepare("SELECT count(*) FROM {$referrals_table} r\n\t\t{$filters}\n\t\t", $filter_params);
    $count = $wpdb->get_var($count_query);
    if ($count > $row_count) {
        $paginate = true;
    } else {
        $paginate = false;
    }
    $pages = ceil($count / $row_count);
    if ($paged > $pages) {
        $paged = $pages;
    }
    if ($paged != 0) {
        $offset = ($paged - 1) * $row_count;
    }
    $query = $wpdb->prepare("\n\t\tSELECT r.*, a.affiliate_id, a.name \n\t\tFROM {$referrals_table} r\n\t\tLEFT JOIN {$affiliates_table} a ON r.affiliate_id = a.affiliate_id\n\t\tLEFT JOIN {$posts_table} p ON r.post_id = p.ID\n\t\t{$filters}\n\t\tORDER BY {$orderby} {$order}\n\t\tLIMIT {$row_count} OFFSET {$offset}\n\t\t", $filter_params + $filter_params);
    $results = $wpdb->get_results($query, OBJECT);
    $column_display_names = array('datetime' => __('Date', AFFILIATES_PLUGIN_DOMAIN), 'post_title' => __('Post', AFFILIATES_PLUGIN_DOMAIN), 'name' => __('Affiliate', AFFILIATES_PLUGIN_DOMAIN), 'amount' => __('Amount', AFFILIATES_PLUGIN_DOMAIN), 'currency_id' => __('Currency', AFFILIATES_PLUGIN_DOMAIN), 'status' => __('Status', AFFILIATES_PLUGIN_DOMAIN), 'edit' => __('', AFFILIATES_PLUGIN_DOMAIN), 'remove' => __('', AFFILIATES_PLUGIN_DOMAIN));
    $column_count = count($column_display_names);
    $output .= '<div id="referrals-overview" class="referrals-overview">';
    $affiliates = affiliates_get_affiliates(true, !$show_inoperative);
    $affiliates_select = '';
    if (!empty($affiliates)) {
        $affiliates_select .= '<label class="affiliate-id-filter" for="affiliate_id">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
        $affiliates_select .= '<select class="affiliate-id-filter" name="affiliate_id">';
        $affiliates_select .= '<option value="">--</option>';
        foreach ($affiliates as $affiliate) {
            if ($affiliate_id == $affiliate['affiliate_id']) {
                $selected = ' selected="selected" ';
            } else {
                $selected = '';
            }
            $affiliates_select .= '<option ' . $selected . ' value="' . esc_attr($affiliate['affiliate_id']) . '">' . esc_attr(stripslashes($affiliate['name'])) . '</option>';
        }
        $affiliates_select .= '</select>';
    }
    $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
    $status_icons = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => "<img class='icon' alt='" . __('Accepted', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/accepted.png'/>", AFFILIATES_REFERRAL_STATUS_CLOSED => "<img class='icon' alt='" . __('Closed', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/closed.png'/>", AFFILIATES_REFERRAL_STATUS_PENDING => "<img class='icon' alt='" . __('Pending', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/pending.png'/>", AFFILIATES_REFERRAL_STATUS_REJECTED => "<img class='icon' alt='" . __('Rejected', AFFILIATES_PLUGIN_DOMAIN) . "' src='" . AFFILIATES_PLUGIN_URL . "images/rejected.png'/>");
    $status_select = '<label class="status-filter" for="status">' . __('Status', AFFILIATES_PLUGIN_DOMAIN) . '</label>';
    $status_select .= '<select name="status">';
    $status_select .= '<option value="" ' . (empty($status) ? ' selected="selected" ' : '') . '>--</option>';
    foreach ($status_descriptions as $key => $label) {
        $selected = $key == $status ? ' selected="selected" ' : '';
        $status_select .= '<option ' . $selected . ' value="' . esc_attr($key) . '">' . $label . '</option>';
    }
    $status_select .= '</select>';
    $output .= '<div class="filters">' . '<label class="description" for="setfilters">' . __('Filters', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<form id="setfilters" action="" method="post">' . '<p>' . $affiliates_select . $status_select . ' <label class="search-filter" for="search" title="Search in data">' . __('Search', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . ' <input class="search-filter" name="search" type="text" value="' . esc_attr($search) . '"/>' . ' ' . sprintf('<label class="search-description-filter" title="%s">', __('Also search in descriptions', AFFILIATES_PLUGIN_DOMAIN)) . '<input class="search-description-filter" name="search_description" type="checkbox" ' . ($search_description ? 'checked="checked"' : '') . '/>' . ' ' . __('Descriptions', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>
				<p>' . '<label class="from-date-filter" for="from_date">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield from-date-filter" name="from_date" type="text" value="' . esc_attr($from_date) . '"/>' . '<label class="thru-date-filter" for="thru_date">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="datefield thru-date-filter" name="thru_date" type="text" class="datefield" value="' . esc_attr($thru_date) . '"/>' . '</p>
				<p>' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_FILTER_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded" type="checkbox" ' . ($expanded ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand details', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_description" type="checkbox" ' . ($expanded_description ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand descriptions', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<label class="expanded-filter">' . '<input class="expanded-filter" name="expanded_data" type="checkbox" ' . ($expanded_data ? 'checked="checked"' : '') . '/>' . ' ' . __('Expand data', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<label class="show-inoperative-filter">' . '<input class="show-inoperative-filter" name="show_inoperative" type="checkbox" ' . ($show_inoperative ? 'checked="checked"' : '') . '/>' . ' ' . __('Include inoperative affiliates', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input class="button" type="submit" name="clear_filters" value="' . __('Clear', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="submitted" name="submitted"/>' . '</p>' . '</form>' . '</div>';
    $output .= '
		<div class="page-options">
			<form id="setrowcount" action="" method="post">
				<div>
					<label for="row_count">' . __('Results per page', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input name="row_count" type="text" size="2" value="' . esc_attr($row_count) . '" />
					' . wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_NONCE_1, true, false) . '
					<input class="button" type="submit" value="' . __('Apply', AFFILIATES_PLUGIN_DOMAIN) . '"/>
				</div>
			</form>
		</div>
		';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<form id="posts-filter" method="post" action="">';
        $output .= '<div>';
        $output .= wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_NONCE_2, true, false);
        $output .= '</div>';
        $output .= '<div class="tablenav top">';
        $output .= $pagination->pagination('top');
        $output .= '</div>';
        $output .= '</form>';
    }
    $output .= '
		<table id="referrals" class="referrals wp-list-table widefat fixed" cellspacing="0">
		<thead>
			<tr>
			';
    foreach ($column_display_names as $key => $column_display_name) {
        $options = array('orderby' => $key, 'order' => $switch_order);
        $class = "";
        if (strcmp($key, $orderby) == 0) {
            $lorder = strtolower($order);
            $class = "{$key} manage-column sorted {$lorder}";
        } else {
            $class = "{$key} manage-column sortable";
        }
        $column_display_name = '<a href="' . esc_url(add_query_arg($options, $current_url)) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
        $output .= "<th scope='col' class='{$class}'>{$column_display_name}</th>";
    }
    $output .= '</tr>
		</thead>
		<tbody>
		';
    if (count($results) > 0) {
        for ($i = 0; $i < count($results); $i++) {
            $result = $results[$i];
            $output .= '<tr class="details-referrals ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
            $output .= '<td class="datetime">' . DateHelper::s2u($result->datetime) . '</td>';
            $link = get_permalink($result->post_id);
            $title = get_the_title($result->post_id);
            $output .= '<td class="post_title"><a href="' . esc_attr($link) . '" target="_blank">' . wp_filter_nohtml_kses($title) . '</a></td>';
            $output .= "<td class='name'>" . stripslashes(wp_filter_nohtml_kses($result->name)) . "</td>";
            $output .= "<td class='amount'>" . stripslashes(wp_filter_nohtml_kses($result->amount)) . "</td>";
            $output .= "<td class='currency_id'>" . stripslashes(wp_filter_nohtml_kses($result->currency_id)) . "</td>";
            $output .= "<td class='status'>";
            $output .= isset($status_icons[$result->status]) ? $status_icons[$result->status] : '';
            $output .= "<form method='post' action=''>";
            $output .= "<div>";
            $output .= "<select name='status'>";
            foreach ($status_descriptions as $status_key => $status_value) {
                if ($status_key == $result->status) {
                    $selected = "selected='selected'";
                } else {
                    $selected = "";
                }
                $output .= "<option value='{$status_key}' {$selected}>{$status_value}</option>";
            }
            $output .= "</select>";
            $output .= '<input class="button" type="submit" value="' . __('Set', AFFILIATES_PLUGIN_DOMAIN) . '"/>';
            $output .= '<input name="affiliate_id" type="hidden" value="' . esc_attr($result->affiliate_id) . '"/>';
            $output .= '<input name="post_id" type="hidden" value="' . esc_attr($result->post_id) . '"/>';
            $output .= '<input name="datetime" type="hidden" value="' . esc_attr($result->datetime) . '"/>';
            $output .= '<input name="action" type="hidden" value="set_status"/>';
            $output .= wp_nonce_field('admin', AFFILIATES_ADMIN_HITS_FILTER_NONCE, true, false);
            $output .= "</div>";
            $output .= "</form>";
            $output .= "</td>";
            $output .= '<td class="edit">';
            $edit_url = add_query_arg('referral_id', $result->referral_id, add_query_arg('action', 'edit', $current_url));
            $output .= sprintf('<a href="%s">', esc_url(add_query_arg('paged', $paged, $edit_url)));
            $output .= sprintf('<img src="%s" alt="%s"/>', AFFILIATES_PLUGIN_URL . 'images/edit.png', __('Edit', AFFILIATES_PLUGIN_DOMAIN));
            $output .= '</a>';
            $output .= '</td>';
            $output .= '<td class="remove">';
            $remove_url = add_query_arg('referral_id', $result->referral_id, add_query_arg('action', 'remove', $current_url));
            $output .= sprintf('<a href="%s">', esc_url(add_query_arg('paged', $paged, $remove_url)));
            $output .= sprintf('<img src="%s" alt="%s"/>', AFFILIATES_PLUGIN_URL . 'images/remove.png', __('Remove', AFFILIATES_PLUGIN_DOMAIN));
            $output .= '</a>';
            $output .= '</td>';
            $output .= '</tr>';
            $data = $result->data;
            if (!empty($data) && $expanded) {
                if ($expanded_data) {
                    $data_view_style = '';
                    $expander = AFFILIATES_EXPANDER_RETRACT;
                } else {
                    $data_view_style = ' style="display:none;" ';
                    $expander = AFFILIATES_EXPANDER_EXPAND;
                }
                $data = unserialize($data);
                if ($data) {
                    $output .= '<tr class="data ' . ($i % 2 == 0 ? 'even' : 'odd') . '">';
                    $output .= "<td colspan='{$column_count}'>";
                    $output .= '<div class="view-toggle">';
                    $output .= "<div class='expander'>{$expander}</div>";
                    $output .= '<div class="view-toggle-label">' . __('Data', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                    $output .= "<div class='view' {$data_view_style}>";
                    $output .= '<table class="referral-data wp-list-table widefat fixed" cellspacing="0">';
                    if (is_array($data)) {
                        foreach ($data as $key => $info) {
                            $title = __($info['title'], $info['domain']);
                            $value = $info['value'];
                            $output .= "<tr id='referral-data-{$i}'>";
                            $output .= '<td class="referral-data-title">';
                            $output .= stripslashes(wp_filter_nohtml_kses($title));
                            $output .= '</td>';
                            $output .= '<td class="referral-data-value">';
                            // @todo revise
                            // $output .= wp_filter_nohtml_kses( $value );
                            $output .= stripslashes($value);
                            $output .= '</td>';
                            $output .= '</tr>';
                        }
                    } else {
                        $output .= "<tr id='referral-data-{$i}'>";
                        $output .= '<td class="referral-data-title">';
                        $output .= __('Data', AFFILIATES_PLUGIN_DOMAIN);
                        $output .= '</td>';
                        $output .= '<td class="referral-data-value">';
                        // @todo revise
                        //$output .= wp_filter_nohtml_kses( $data );
                        $output .= stripslashes($value);
                        $output .= '</td>';
                        $output .= '</tr>';
                    }
                    $output .= '</table>';
                    $output .= '</div>';
                    // .view
                    $output .= '</div>';
                    // .view-toggle
                    $output .= '</td>';
                    $output .= '</tr>';
                }
            }
            if (!empty($result->description) && $expanded) {
                if ($expanded_description) {
                    $description_view_style = '';
                    $expander = AFFILIATES_EXPANDER_RETRACT;
                } else {
                    $description_view_style = ' style="display:none;" ';
                    $expander = AFFILIATES_EXPANDER_EXPAND;
                }
                $output .= sprintf("<tr id='referral-description-%d' class='%s'>", $i, $i % 2 == 0 ? 'even' : 'odd') . '<td colspan="' . $column_count . '">' . '<div class="view-toggle">' . "<div class='expander'>{$expander}</div>" . '<div class="view-toggle-label">' . __('Description', AFFILIATES_PLUGIN_DOMAIN) . '</div>' . "<div class='view' {$description_view_style}>" . wp_filter_kses(addslashes($result->description)) . '</div>' . '</div>' . '</td>' . '</tr>';
            }
        }
    } else {
        $output .= '<tr><td colspan="' . $column_count . '">' . __('There are no results.', AFFILIATES_PLUGIN_DOMAIN) . '</td></tr>';
    }
    $output .= '</tbody>';
    $output .= '</table>';
    if ($paginate) {
        require_once AFFILIATES_CORE_LIB . '/class-affiliates-pagination.php';
        $pagination = new Affiliates_Pagination($count, null, $row_count);
        $output .= '<div class="tablenav bottom">';
        $output .= $pagination->pagination('bottom');
        $output .= '</div>';
    }
    $output .= '</div>';
    // .referrals-overview
    echo $output;
    affiliates_footer();
}
 /**
  * Hooked on delete_user to mark affiliate as deleted.
  * Note that the affiliate-user association is maintained.
  * @param int $user_id
  */
 public static function deleted_user($user_id)
 {
     global $wpdb;
     $affiliates_table = _affiliates_get_tablename('affiliates');
     $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
     if ($affiliate_user = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$affiliates_users_table} WHERE user_id = %d", intval($user_id)))) {
         $affiliate_id = $affiliate_user->affiliate_id;
         // do not mark the pseudo-affiliate as deleted: type != ...
         $check = $wpdb->prepare("SELECT affiliate_id FROM {$affiliates_table} WHERE affiliate_id = %d AND (type IS NULL OR type != '" . AFFILIATES_DIRECT_TYPE . "')", intval($affiliate_id));
         if ($wpdb->query($check)) {
             $valid_affiliate = true;
         }
         if ($valid_affiliate) {
             // mark the affiliate as deleted - will go through and also
             // clean up the association even if the affiliate was already
             // marked as deleted
             $wpdb->query($query = $wpdb->prepare("UPDATE {$affiliates_table} SET status = 'deleted' WHERE affiliate_id = %d", intval($affiliate_id)));
             do_action('affiliates_deleted_affiliate', intval($affiliate_id));
             // the user is removed from the users table, it wouldn't make sense to maintain
             // a dangling reference to a non-existent user so release the association as well
             $wpdb->query($query = $wpdb->prepare("DELETE FROM {$affiliates_users_table} WHERE affiliate_id = %d AND user_id = %d", intval($affiliate_id), intval($user_id)));
         }
     }
 }
Example #15
0
/**
 * Returns the number of referrals for a given affiliate.
 *
 * @param int $affiliate_id the affiliate's id
 * @param string $from_date optional from date
 * @param string $thru_date optional thru date
 * @return int number of hits
 */
function affiliates_get_affiliate_referrals($affiliate_id, $from_date = null, $thru_date = null, $status = null, $precise = false)
{
    global $wpdb;
    $referrals_table = _affiliates_get_tablename('referrals');
    $result = 0;
    $where = " WHERE affiliate_id = %d";
    $values = array($affiliate_id);
    if ($from_date) {
        if ($precise) {
            $from_date = date('Y-m-d H:i:s', strtotime($from_date));
        } else {
            $from_date = date('Y-m-d', strtotime($from_date));
        }
    }
    if ($thru_date) {
        if ($precise) {
            $thru_date = date('Y-m-d H:i:s', strtotime($thru_date));
        } else {
            $thru_date = date('Y-m-d', strtotime($thru_date) + 24 * 3600);
        }
    }
    if ($from_date && $thru_date) {
        $where .= " AND datetime >= %s AND datetime < %s ";
        $values[] = $from_date;
        $values[] = $thru_date;
    } else {
        if ($from_date) {
            $where .= " AND datetime >= %s ";
            $values[] = $from_date;
        } else {
            if ($thru_date) {
                $where .= " AND datetime < %s ";
                $values[] = $thru_date;
            }
        }
    }
    if (!empty($status)) {
        $where .= " AND status = %s ";
        $values[] = $status;
    } else {
        $where .= " AND status IN ( %s, %s ) ";
        $values[] = AFFILIATES_REFERRAL_STATUS_ACCEPTED;
        $values[] = AFFILIATES_REFERRAL_STATUS_CLOSED;
    }
    $query = $wpdb->prepare("\n\t\tSELECT count(*) FROM {$referrals_table} {$where}\n\t\t", $values);
    $result = intval($wpdb->get_var($query));
    return $result;
}
/**
 * Create/Edit referral form.
 */
function affiliates_admin_referral_edit($referral_id = null)
{
    global $wpdb, $affiliates_options;
    $output = '';
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $cancel_url = remove_query_arg('referral_id', remove_query_arg('action', $current_url));
    $current_url = remove_query_arg('paged', $current_url);
    $current_url = remove_query_arg('affiliate_id', $current_url);
    if ($referral_id === null) {
        $referral_id = isset($_POST['referral_id']) ? intval($_POST['referral_id']) : null;
    }
    $affiliate_id = isset($_POST['affiliate_id']) ? intval($_POST['affiliate_id']) : null;
    $datetime = isset($_POST['datetime']) ? date('Y-m-d H:i:s', strtotime($_POST['datetime'])) : date('Y-m-d H:i:s', time());
    $description = isset($_POST['description']) ? wp_strip_all_tags($_POST['description']) : '';
    $amount = !empty($_POST['amount']) ? bcadd('0', $_POST['amount'], AFFILIATES_REFERRAL_AMOUNT_DECIMALS) : null;
    $currency_id = substr(strtoupper(isset($_POST['currency_id']) ? wp_strip_all_tags($_POST['currency_id']) : ''), 0, 3);
    $status = $affiliates_options->get_option('referrals_status', AFFILIATES_REFERRAL_STATUS_ACCEPTED);
    if (isset($_POST['status'])) {
        switch ($_POST['status']) {
            case AFFILIATES_REFERRAL_STATUS_ACCEPTED:
            case AFFILIATES_REFERRAL_STATUS_CLOSED:
            case AFFILIATES_REFERRAL_STATUS_PENDING:
            case AFFILIATES_REFERRAL_STATUS_REJECTED:
                $status = $_POST['status'];
                break;
        }
    }
    $reference = isset($_POST['reference']) ? wp_strip_all_tags($_POST['reference']) : '';
    $saved = false;
    if (isset($_POST['save'])) {
        if (!wp_verify_nonce($_POST['referral-nonce'], 'save')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        } else {
            if (!empty($affiliate_id)) {
                if (empty($referral_id)) {
                    add_action('affiliates_referral', 'affiliates_admin_referral_capture_id');
                    if (class_exists('Affiliates_Referral_WordPress')) {
                        $r = new Affiliates_Referral_WordPress();
                        $r->add_referrals(array($affiliate_id), null, $description, null, null, $amount, $currency_id, $status, 'manual', $reference);
                    } else {
                        affiliates_add_referral($affiliate_id, null, $description, null, $amount, $currency_id, $status, 'manual', $reference);
                    }
                    remove_action('affiliates_referral', 'affiliates_admin_referral_capture_id');
                    global $captured_referral_id;
                    if (isset($captured_referral_id)) {
                        $referral_id = $captured_referral_id;
                        $output .= '<br/>';
                        $output .= '<div class="info">' . __('The referral has been created.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                        $saved = true;
                    } else {
                        $output .= '<br/>';
                        $output .= '<div class="warning">' . __('The referral has not been created. Duplicate?', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                    }
                } else {
                    if (class_exists('Affiliates_Referral_WordPress')) {
                        try {
                            $r = new Affiliates_Referral_WordPress($referral_id);
                            if ($r->update(array('affiliate_id' => intval($affiliate_id), 'datetime' => $datetime, 'description' => $description, 'amount' => $amount, 'currency_id' => $currency_id, 'status' => $status, 'reference' => $reference))) {
                                $output .= '<br/>';
                                $output .= '<div class="info">' . __('The referral has been saved.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                                $saved = true;
                            }
                        } catch (Exception $ex) {
                            $output .= '<br/>';
                            $output .= '<div class="error">' . __('The referral could not be saved.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                        }
                    } else {
                        if (affiliates_update_referral($referral_id, array('affiliate_id' => intval($affiliate_id), 'datetime' => $datetime, 'description' => $description, 'amount' => $amount, 'currency_id' => $currency_id, 'status' => $status, 'reference' => $reference))) {
                            $output .= '<br/>';
                            $output .= '<div class="info">' . __('The referral has been saved.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                            $saved = true;
                        }
                    }
                }
            }
        }
    }
    if ($referral_id !== null) {
        $referrals_table = _affiliates_get_tablename('referrals');
        if ($referrals = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$referrals_table} WHERE referral_id = %d", $referral_id))) {
            if (count($referrals) > 0) {
                $referral = $referrals[0];
                $affiliate_id = $referral->affiliate_id;
                $datetime = $referral->datetime;
                $description = $referral->description;
                $amount = $referral->amount;
                $currency_id = $referral->currency_id;
                $status = $referral->status;
                $reference = $referral->reference;
            }
        }
    }
    $output .= '<div class="referral">';
    $output .= '<h2>';
    if (empty($referral_id)) {
        $output .= __('New Referral', AFFILIATES_PLUGIN_DOMAIN);
    } else {
        $output .= __('Edit Referral', AFFILIATES_PLUGIN_DOMAIN);
    }
    $output .= '</h2>';
    $output .= '<form id="referral" action="' . $current_url . '" method="post">';
    $output .= '<div>';
    if ($referral_id) {
        $output .= sprintf('<input type="hidden" name="referral_id" value="%d" />', intval($referral_id));
    }
    $output .= '<input type="hidden" name="action" value="edit" />';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $affiliates = affiliates_get_affiliates(true, true);
    $output .= '<select name="affiliate_id">';
    foreach ($affiliates as $affiliate) {
        if ($affiliate_id == $affiliate['affiliate_id']) {
            $selected = ' selected="selected" ';
        } else {
            $selected = '';
        }
        $output .= '<option ' . $selected . ' value="' . esc_attr($affiliate['affiliate_id']) . '">' . esc_attr(stripslashes($affiliate['name'])) . '</option>';
    }
    $output .= '</select>';
    $output .= '</label>';
    $output .= '</p>';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Date & Time', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= sprintf('<input type="text" name="datetime" value="%s" />', esc_attr($datetime));
    $output .= ' ';
    $output .= '<span class="description">' . __('Format : YYYY-MM-DD HH:MM:SS', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= '</label>';
    $output .= '</p>';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Description', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= '<textarea name="description">';
    $output .= stripslashes($description);
    $output .= '</textarea>';
    $output .= '</label>';
    $output .= '</p>';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Amount', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= sprintf('<input type="text" name="amount" value="%s" />', esc_attr($amount));
    $output .= '</label>';
    $output .= '</p>';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Currency ID', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= sprintf('<input type="text" name="currency_id" value="%s" />', esc_attr($currency_id));
    $output .= ' ';
    $output .= '<span class="description">' . __('* Required when an amount is provided. Examples: USD, GBP, EUR, ...', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= '</label>';
    $output .= '</p>';
    $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Status', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= '<select name="status">';
    foreach ($status_descriptions as $key => $label) {
        $selected = $key == $status ? ' selected="selected" ' : '';
        $output .= '<option ' . $selected . ' value="' . esc_attr($key) . '">' . $label . '</option>';
    }
    $output .= '</select>';
    $output .= '</label>';
    $output .= '</p>';
    $output .= '<p>';
    $output .= '<label>';
    $output .= '<span class="title">' . __('Reference', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
    $output .= ' ';
    $output .= sprintf('<input type="text" name="reference" value="%s" />', esc_attr($reference));
    $output .= '</label>';
    $output .= '</p>';
    $output .= wp_nonce_field('save', 'referral-nonce', true, false);
    $output .= sprintf('<input class="button" type="submit" name="save" value="%s"/>', __('Save', AFFILIATES_PLUGIN_DOMAIN));
    $output .= ' ';
    $output .= sprintf('<a class="cancel" href="%s">%s</a>', $cancel_url, $saved ? __('Back', AFFILIATES_PLUGIN_DOMAIN) : __('Cancel', AFFILIATES_PLUGIN_DOMAIN));
    $output .= '</div>';
    $output .= '</form>';
    $output .= '</div>';
    echo $output;
    affiliates_footer();
}
/**
 * Handle add affiliate form submission.
 */
function affiliates_admin_affiliates_add_submit()
{
    global $wpdb;
    $result = true;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_NONCE], 'affiliates-add')) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $name = isset($_POST['name-field']) ? $_POST['name-field'] : null;
    if (!empty($name)) {
        // Note the trickery (*) that has to be used because wpdb::prepare() is not
        // able to handle null values.
        // @see http://core.trac.wordpress.org/ticket/11622
        // @see http://core.trac.wordpress.org/ticket/12819
        $data = array('name' => $name);
        $formats = array('%s');
        $email = trim($_POST['email-field']);
        if (is_email($email)) {
            $data['email'] = $email;
            $formats[] = '%s';
        } else {
            $data['email'] = null;
            // (*)
            $formats[] = 'NULL';
            // (*)
        }
        $from_date = $_POST['from-date-field'];
        if (empty($from_date)) {
            $from_date = date('Y-m-d', time());
        } else {
            $from_date = date('Y-m-d', strtotime($from_date));
        }
        $data['from_date'] = $from_date;
        $formats[] = '%s';
        $thru_date = $_POST['thru-date-field'];
        if (!empty($thru_date) && strtotime($thru_date) < strtotime($from_date)) {
            // thru_date is before from_date => set to null
            $thru_date = null;
        }
        if (!empty($thru_date)) {
            $thru_date = date('Y-m-d', strtotime($thru_date));
            $data['thru_date'] = $thru_date;
            $formats[] = '%s';
        } else {
            $data['thru_date'] = null;
            // (*)
            $formats[] = 'NULL';
            // (*)
        }
        $data_ = array();
        $formats_ = array();
        foreach ($data as $key => $value) {
            // (*)
            if ($value) {
                $data_[$key] = $value;
            }
        }
        foreach ($formats as $format) {
            // (*)
            if ($format != "NULL") {
                $formats_[] = $format;
            }
        }
        if ($wpdb->insert($affiliates_table, $data_, $formats_)) {
            $affiliate_id = $wpdb->get_var("SELECT LAST_INSERT_ID()");
        }
        // user association
        $new_associated_user_login = trim($_POST['user-field']);
        // new association
        if (!empty($affiliate_id) && !empty($new_associated_user_login)) {
            $new_associated_user = get_user_by('login', $new_associated_user_login);
            if (!empty($new_associated_user)) {
                if ($wpdb->query($wpdb->prepare("INSERT INTO {$affiliates_users_table} SET affiliate_id = %d, user_id = %d", intval($affiliate_id), intval($new_associated_user->ID)))) {
                    if (empty($email) && !empty($new_associated_user->user_email)) {
                        $wpdb->query($wpdb->prepare("UPDATE {$affiliates_table} SET email = %s WHERE affiliate_id = %d", $new_associated_user->user_email, $affiliate_id));
                    }
                }
            }
        }
        // hook
        if (!empty($affiliate_id)) {
            do_action('affiliates_added_affiliate', intval($affiliate_id));
        }
    } else {
        $result = false;
    }
    return $result;
}
/**
 * Delete a referral.
 */
function affiliates_admin_referral_remove($referral_id = null)
{
    global $wpdb;
    $output = '';
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $cancel_url = remove_query_arg('referral_id', remove_query_arg('action', $current_url));
    $current_url = remove_query_arg('paged', $current_url);
    $output .= '<div class="referral remove">';
    $output .= '<h2>';
    $output .= __('Remove a Referral', AFFILIATES_PLUGIN_DOMAIN);
    $output .= '</h2>';
    if (isset($_POST['submit'])) {
        if (!wp_verify_nonce($_POST['referral-nonce'], 'remove')) {
            wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
        } else {
            if (!empty($_POST['referral_id'])) {
                // remove the referral
                $referrals_table = _affiliates_get_tablename('referrals');
                if ($wpdb->query($wpdb->prepare("DELETE FROM {$referrals_table} WHERE referral_id = %d", intval($_POST['referral_id'])))) {
                    $output .= '<br/>';
                    $output .= '<div class="info">';
                    $output .= __('The referral has been removed.', AFFILIATES_PLUGIN_DOMAIN);
                    $output .= ' ';
                    $output .= sprintf('<a href="%s">%s</a>', $cancel_url, __('Return', AFFILIATES_PLUGIN_DOMAIN));
                    $output .= '</div>';
                    $output .= '<br/>';
                } else {
                    $output .= '<div class="error">' . __('I do not know how to delete what does not exist.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                }
            }
        }
    } else {
        if ($referral_id !== null) {
            $referrals_table = _affiliates_get_tablename('referrals');
            if ($referrals = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$referrals_table} WHERE referral_id = %d", $referral_id))) {
                if (count($referrals) > 0) {
                    $referral = $referrals[0];
                    $affiliate_id = $referral->affiliate_id;
                    $datetime = $referral->datetime;
                    $description = wp_strip_all_tags($referral->description);
                    $amount = $referral->amount;
                    $currency_id = $referral->currency_id;
                    $status = $referral->status;
                    $reference = wp_strip_all_tags($referral->reference);
                    $output .= '<form id="referral" action="' . $current_url . '" method="post">';
                    $output .= '<div>';
                    $output .= sprintf('<input type="hidden" name="referral_id" value="%d" />', intval($referral_id));
                    $output .= '<input type="hidden" name="action" value="edit" />';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $affiliate = affiliates_get_affiliate($affiliate_id);
                    $output .= stripslashes($affiliate['name']);
                    $output .= '</p>';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Date & Time', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $datetime;
                    $output .= '</p>';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Description', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $description;
                    $output .= '</p>';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Amount', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $amount;
                    $output .= '</p>';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Currency ID', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $currency_id;
                    $output .= '</p>';
                    $status_descriptions = array(AFFILIATES_REFERRAL_STATUS_ACCEPTED => __('Accepted', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_CLOSED => __('Closed', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_PENDING => __('Pending', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_REFERRAL_STATUS_REJECTED => __('Rejected', AFFILIATES_PLUGIN_DOMAIN));
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Status', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $status_descriptions[$status];
                    $output .= '</p>';
                    $output .= '<p>';
                    $output .= '<span class="title">' . __('Reference', AFFILIATES_PLUGIN_DOMAIN) . '</span>';
                    $output .= ' ';
                    $output .= $reference;
                    $output .= '</p>';
                    $output .= wp_nonce_field('remove', 'referral-nonce', true, false);
                    $output .= '<p class="description">';
                    $output .= __('Remove this referral? This action can not be undone.', AFFILIATES_PLUGIN_DOMAIN);
                    $output .= '</p>';
                    $output .= sprintf('<input class="button" type="submit" name="submit" value="%s"/>', __('Remove', AFFILIATES_PLUGIN_DOMAIN));
                    $output .= ' ';
                    $output .= sprintf('<a class="cancel" href="%s">%s</a>', $cancel_url, __('Cancel', AFFILIATES_PLUGIN_DOMAIN));
                    $output .= '</div>';
                    $output .= '</form>';
                } else {
                    $output .= '<div class="error">' . __('This referral does not exist.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
                }
            } else {
                $output .= '<div class="error">' . __('This referral does not exist.', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
            }
        } else {
            $output .= '<div class="error">' . __('Pretty pointless ...', AFFILIATES_PLUGIN_DOMAIN) . '</div>';
        }
    }
    $output .= '</div>';
    echo $output;
    affiliates_footer();
}
 /**
  * Updates the affiliate entry.
  * 
  * @param int $user_id
  * @param array $old_userdata
  */
 public static function profile_update($user_id, $old_userdata)
 {
     global $wpdb;
     // update affiliate entry
     $affiliate_ids = affiliates_get_user_affiliate($user_id);
     if (!empty($affiliate_ids)) {
         if ($affiliate_id = array_shift($affiliate_ids)) {
             if ($user = get_userdata($user_id)) {
                 $affiliates_table = _affiliates_get_tablename('affiliates');
                 $query = $wpdb->prepare("UPDATE {$affiliates_table} SET name = %s, email = %s WHERE affiliate_id = %d", $user->first_name . ' ' . $user->last_name, $user->user_email, intval($affiliate_id));
                 if ($wpdb->query($query)) {
                     do_action('affiliates_updated_affiliate', $affiliate_id);
                 }
             }
         }
     }
 }
/**
 * Handle edit form submission.
 */
function affiliates_admin_affiliates_edit_submit()
{
    global $wpdb;
    $result = true;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    if (!wp_verify_nonce($_POST[AFFILIATES_ADMIN_AFFILIATES_NONCE], 'affiliates-edit')) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_table = _affiliates_get_tablename('affiliates');
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $affiliate_id = isset($_POST['affiliate-id-field']) ? $_POST['affiliate-id-field'] : null;
    $is_direct = false;
    $affiliate = null;
    if ($affiliate = $wpdb->get_row($wpdb->prepare("SELECT affiliate_id FROM {$affiliates_table} WHERE affiliate_id = %d", intval($affiliate_id)))) {
        $is_direct = isset($affiliate->type) && $affiliate->type == AFFILIATES_DIRECT_TYPE;
    }
    if (empty($affiliate)) {
        wp_die(__('No such affiliate.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $name = isset($_POST['name-field']) ? $_POST['name-field'] : null;
    // don't change the name of the pseudo-affiliate
    if ($is_direct) {
        $name = AFFILIATES_DIRECT_NAME;
    }
    if (!empty($name)) {
        // Note the trickery (*) that has to be used because wpdb::prepare() is not
        // able to handle null values.
        // @see http://core.trac.wordpress.org/ticket/11622
        // @see http://core.trac.wordpress.org/ticket/12819
        $data = array('name' => $name);
        $formats = array('%s');
        $email = trim($_POST['email-field']);
        if (is_email($email)) {
            $data['email'] = $email;
            $formats[] = '%s';
        } else {
            $data['email'] = null;
            // (*)
            $formats[] = 'NULL';
            // (*)
        }
        $from_date = $_POST['from-date-field'];
        if (empty($from_date)) {
            $from_date = date('Y-m-d', time());
        } else {
            $from_date = date('Y-m-d', strtotime($from_date));
        }
        $data['from_date'] = $from_date;
        $formats[] = '%s';
        $thru_date = $_POST['thru-date-field'];
        if (!empty($thru_date) && strtotime($thru_date) < strtotime($from_date)) {
            // thru_date is before from_date => set to null
            $thru_date = null;
        }
        if (!empty($thru_date)) {
            $thru_date = date('Y-m-d', strtotime($thru_date));
            $data['thru_date'] = $thru_date;
            $formats[] = '%s';
        } else {
            $data['thru_date'] = null;
            // (*)
            $formats[] = 'NULL';
            // (*)
        }
        $sets = array();
        $values = array();
        $j = 0;
        foreach ($data as $key => $value) {
            $sets[] = $key . ' = ' . $formats[$j];
            if ($value) {
                // (*)
                $values[] = $value;
            }
            $j++;
        }
        if (!empty($sets)) {
            $sets = implode(', ', $sets);
            $values[] = intval($affiliate_id);
            $query = $wpdb->prepare("UPDATE {$affiliates_table} SET {$sets} WHERE affiliate_id = %d", $values);
            $wpdb->query($query);
        }
        // user association
        // delete old association if necessary
        $current_associated_user = $wpdb->get_row($wpdb->prepare(" SELECT affiliate_id, user_id, user_login FROM {$affiliates_users_table} LEFT JOIN {$wpdb->users} ON {$affiliates_users_table}.user_id = {$wpdb->users}.ID WHERE affiliate_id = %d", intval($affiliate_id)));
        $new_associated_user_login = trim($_POST['user-field']);
        if (empty($new_associated_user_login) && !empty($current_associated_user) || !empty($current_associated_user) && strcmp($current_associated_user->user_login, $new_associated_user_login) !== 0) {
            $wpdb->query($wpdb->prepare("DELETE FROM {$affiliates_users_table} WHERE affiliate_id = %d", intval($affiliate_id)));
        }
        // new association
        if (!empty($affiliate_id) && !empty($new_associated_user_login) && (empty($current_associated_user) || !empty($current_associated_user) && strcmp($current_associated_user->user_login, $new_associated_user_login) !== 0)) {
            $new_associated_user = get_user_by('login', $new_associated_user_login);
            if (!empty($new_associated_user)) {
                if ($wpdb->query($wpdb->prepare("INSERT INTO {$affiliates_users_table} SET affiliate_id = %d, user_id = %d", intval($affiliate_id), intval($new_associated_user->ID)))) {
                    if (empty($email) && !empty($new_associated_user->user_email)) {
                        $wpdb->query($wpdb->prepare("UPDATE {$affiliates_table} SET email = %s WHERE affiliate_id = %d", $new_associated_user->user_email, $affiliate_id));
                    }
                }
            }
        }
        // hook
        if (!empty($affiliate_id)) {
            do_action('affiliates_updated_affiliate', intval($affiliate_id));
        }
    } else {
        $result = false;
    }
    return $result;
}