/**
 * Show edit affiliate form.
 * @param int $affiliate_id affiliate id
 */
function affiliates_admin_affiliates_edit($affiliate_id)
{
    global $wpdb;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliate = affiliates_get_affiliate(intval($affiliate_id));
    if (empty($affiliate)) {
        wp_die(__('No such affiliate.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $affiliate_user = null;
    $affiliate_user_edit = '';
    $affiliate_user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$affiliates_users_table} WHERE affiliate_id = %d", intval($affiliate_id)));
    if ($affiliate_user_id !== null) {
        $affiliate_user = get_user_by('id', intval($affiliate_user_id));
        if ($affiliate_user) {
            if (current_user_can('edit_user', $affiliate_user->ID)) {
                $affiliate_user_edit = sprintf(__('Edit %s', AFFILIATES_PLUGIN_DOMAIN), '<a target="_blank" href="' . esc_url("user-edit.php?user_id={$affiliate_user->ID}") . '">' . $affiliate_user->user_login . '</a>');
            }
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('action', $current_url);
    $current_url = remove_query_arg('affiliate_id', $current_url);
    $name = isset($_POST['name-field']) ? $_POST['name-field'] : $affiliate['name'];
    $email = isset($_POST['email-field']) ? $_POST['email-field'] : $affiliate['email'];
    $user_login = isset($_POST['user-field']) ? $_POST['user-field'] : ($affiliate_user != null ? $affiliate_user->user_login : '');
    $from_date = isset($_POST['from-date-field']) ? $_POST['from-date-field'] : $affiliate['from_date'];
    $thru_date = isset($_POST['thru-date-field']) ? $_POST['thru-date-field'] : $affiliate['thru_date'];
    $output = '<div class="manage-affiliates">' . '<div>' . '<h2>' . __('Edit an affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>' . '<form id="edit-affiliate" action="' . $current_url . '" method="post">' . '<div class="affiliate edit">' . '<input id="affiliate-id-field" name="affiliate-id-field" type="hidden" value="' . esc_attr(intval($affiliate_id)) . '"/>' . '<div class="field">' . '<label for="name-field" class="field-label first required">' . __('Name', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="name-field" name="name-field" class="namefield" type="text" value="' . esc_attr($name) . '"/>' . '</div>' . '<div class="field">' . '<label for="email-field" class="field-label">' . __('Email', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="email-field" name="email-field" class="emailfield" type="text" value="' . esc_attr($email) . '"/>' . '<span class="description">' . __("If a valid <strong>Username</strong> is specified and no email is given, the user's email address will be used automatically.", AFFILIATES_PLUGIN_DOMAIN) . '</span>' . '</div>' . '<div class="field">' . '<label for="user-field" class="field-label">' . __('Username', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="user-field" name="user-field" class="userfield" type="text" value="' . esc_attr($user_login) . '"/>' . $affiliate_user_edit . '</div>' . '<div class="field">' . '<label for="from-date-field" class="field-label first">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="from-date-field" name="from-date-field" class="datefield" type="text" value="' . esc_attr($from_date) . '"/>' . '</div>' . '<div class="field">' . '<label for="thru-date-field" class="field-label">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="thru-date-field" name="thru-date-field" class="datefield" type="text" value="' . esc_attr($thru_date) . '"/>' . '</div>' . '<div class="field">' . wp_nonce_field('affiliates-edit', AFFILIATES_ADMIN_AFFILIATES_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Save', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="edit" name="action"/>' . '<a class="cancel" href="' . $current_url . '">' . __('Cancel', AFFILIATES_PLUGIN_DOMAIN) . '</a>' . '</div>' . '</div>' . '</form>' . '</div>';
    // .manage-affiliates
    echo $output;
    affiliates_footer();
}
/**
 * Show form to remove an affiliate.
 * @param int $affiliate_id affiliate id
 */
function affiliates_admin_affiliates_remove($affiliate_id)
{
    global $wpdb;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliate = affiliates_get_affiliate(intval($affiliate_id));
    if (empty($affiliate)) {
        wp_die(__('No such affiliate.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $affiliate_user = null;
    $affiliate_user_edit = '';
    $affiliate_user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$affiliates_users_table} WHERE affiliate_id = %d", intval($affiliate_id)));
    if ($affiliate_user_id !== null) {
        $affiliate_user = get_user_by('id', intval($affiliate_user_id));
        if ($affiliate_user) {
            if (current_user_can('edit_user', $affiliate_user->ID)) {
                $affiliate_user_edit = sprintf(__('Edit %s', AFFILIATES_PLUGIN_DOMAIN), '<a target="_blank" href="' . esc_url("user-edit.php?user_id={$affiliate_user->ID}") . '">' . $affiliate_user->user_login . '</a>');
            } else {
                $affiliate_user_edit = $affiliate_user->user_login;
            }
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('action', $current_url);
    $current_url = remove_query_arg('affiliate_id', $current_url);
    $output = '<div class="manage-affiliates">' . '<div>' . '<h2>' . __('Remove an affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>' . '<form id="remove-affiliate" action="' . $current_url . '" method="post">' . '<div class="affiliate remove">' . '<input id="affiliate-id-field" name="affiliate-id-field" type="hidden" value="' . esc_attr(intval($affiliate_id)) . '"/>' . '<ul>' . '<li>' . sprintf(__('Name : %s', AFFILIATES_PLUGIN_DOMAIN), wp_filter_kses($affiliate['name'])) . '</li>' . '<li>' . sprintf(__('Email : %s', AFFILIATES_PLUGIN_DOMAIN), wp_filter_kses($affiliate['email'])) . '</li>' . '<li>' . sprintf(__('Username : %s', AFFILIATES_PLUGIN_DOMAIN), wp_filter_kses($affiliate_user_edit)) . '</li>' . '<li>' . sprintf(__('From : %s', AFFILIATES_PLUGIN_DOMAIN), wp_filter_kses($affiliate['from_date'])) . '</li>' . '<li>' . sprintf(__('Until : %s', AFFILIATES_PLUGIN_DOMAIN), wp_filter_kses($affiliate['from_date'])) . '</li>' . '</ul> ' . wp_nonce_field('affiliates-remove', AFFILIATES_ADMIN_AFFILIATES_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Remove', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="remove" name="action"/>' . '<a class="cancel" href="' . $current_url . '">' . __('Cancel', AFFILIATES_PLUGIN_DOMAIN) . '</a>' . '</div>' . '</div>' . '</form>' . '</div>';
    // .manage-affiliates
    echo $output;
    affiliates_footer();
}
 /**
  * Renders the referrals section.
  */
 public static function section()
 {
     if (isset($_POST['submit'])) {
         if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_SETTINGS_NONCE], 'admin')) {
             // timeout
             $timeout = intval($_POST['timeout']);
             if ($timeout < 0) {
                 $timeout = 0;
             }
             update_option('aff_cookie_timeout_days', $timeout);
             // 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');
             // auto
             delete_option('aff_allow_auto');
             add_option('aff_allow_auto', !empty($_POST['allow_auto']) ? 'yes' : 'no', '', 'no');
             delete_option('aff_allow_auto_coupons');
             add_option('aff_allow_auto_coupons', !empty($_POST['allow_auto_coupons']) ? 'yes' : 'no', '', 'no');
             self::settings_saved_notice();
         }
     }
     $timeout = get_option('aff_cookie_timeout_days', AFFILIATES_COOKIE_TIMEOUT_DAYS);
     $use_direct = get_option('aff_use_direct', false);
     $duplicates = get_option('aff_duplicates', false);
     $allow_auto = get_option('aff_allow_auto', 'no') == 'yes';
     $allow_auto_coupons = get_option('aff_allow_auto_coupons', 'no') == 'yes';
     $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>";
     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>' . sprintf(__('The default value is %d. In this case, if a visitor comes to your site via an affiliate link, a suggested referral will be valid until %d days after she or he clicked that affiliate link.', AFFILIATES_PLUGIN_DOMAIN), AFFILIATES_COOKIE_TIMEOUT_DAYS, AFFILIATES_COOKIE_TIMEOUT_DAYS) . '</p>';
     echo '<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>';
     echo '<h3>' . __('Default referral status', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . $status_select . '</p>';
     echo '<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>';
     echo '<h3>' . __('Auto-referrals', AFFILIATES_PLUGIN_DOMAIN) . '</h3>' . '<p>' . '<label>' . sprintf('<input type="checkbox" name="allow_auto" %s" />', $allow_auto == 'yes' ? ' checked="checked" ' : '') . ' ' . __('Allow auto-referrals', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('If this option is enabled, affiliates are allowed to refer themselves.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . __('This option allows an affiliate to earn a commission on a transaction that involves the affiliate as a customer or lead.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . __('Auto-referrals are identified as such, when a transaction is processed for the same user or user email as the affiliate’s, or when it involves the use of a coupon assigned to the affiliate.', AFFILIATES_PLUGIN_DOMAIN) . '</p>' . '<p>' . '<label>' . sprintf('<input type="checkbox" name="allow_auto_coupons" %s" />', $allow_auto_coupons ? ' checked="checked" ' : '') . ' ' . __('Allow auto-coupons', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '</p>' . '<p class="description">' . __('Allow affiliates to apply coupons that are assigned to them.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . __('Verification is supported for coupons managed through WooCommerce.', 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();
 }
/**
 * Show add affiliate form.
 */
function affiliates_admin_affiliates_add()
{
    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'];
    $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);
    $name = isset($_POST['name-field']) ? $_POST['name-field'] : '';
    $email = isset($_POST['email-field']) ? $_POST['email-field'] : '';
    $user_login = isset($_POST['user-field']) ? $_POST['user-field'] : '';
    $from_date = isset($_POST['from-date-field']) ? $_POST['from-date-field'] : '';
    $thru_date = isset($_POST['thru-date-field']) ? $_POST['thru-date-field'] : '';
    $output = '<div class="manage-affiliates">' . '<div>' . '<h2>' . __('Add a new affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</h2>' . '</div>' . '<form id="add-affiliate" action="' . $current_url . '" method="post">' . '<div class="affiliate new">' . '<div class="field">' . '<label for="name-field" class="field-label first required">' . __('Name', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="name-field" name="name-field" class="namefield" type="text" value="' . esc_attr($name) . '"/>' . '</div>' . '<div class="field">' . '<label for="email-field" class="field-label">' . __('Email', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="email-field" name="email-field" class="emailfield" type="text" value="' . esc_attr($email) . '"/>' . '<span class="description">' . __("If a valid <strong>Username</strong> is specified and no email is given, the user's email address will be used automatically.", AFFILIATES_PLUGIN_DOMAIN) . '</span>' . '</div>' . '<div class="field">' . '<label for="user-field" class="field-label">' . __('Username', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="user-field" name="user-field" class="userfield" type="text" value="' . esc_attr($user_login) . '"/>' . '</div>' . '<div class="field">' . '<label for="from-date-field" class="field-label first">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="from-date-field" name="from-date-field" class="datefield" type="text" value="' . esc_attr($from_date) . '"/>' . '</div>' . '<div class="field">' . '<label for="thru-date-field" class="field-label">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</label>' . '<input id="thru-date-field" name="thru-date-field" class="datefield" type="text" value="' . esc_attr($thru_date) . '"/>' . '</div>' . '<div class="field">' . wp_nonce_field('affiliates-add', AFFILIATES_ADMIN_AFFILIATES_NONCE, true, false) . '<input class="button" type="submit" value="' . __('Add', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="add" name="action"/>' . '<a class="cancel" href="' . $current_url . '">' . __('Cancel', AFFILIATES_PLUGIN_DOMAIN) . '</a>' . '</div>' . '</div>' . '</form>' . '</div>';
    // .manage-affiliates
    echo $output;
    affiliates_footer();
}
function affiliates_admin_user_registration()
{
    if (!current_user_can(AFFILIATES_ADMINISTER_OPTIONS)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    echo '<h1>';
    echo __('User Registration', AFFILIATES_PLUGIN_DOMAIN);
    echo '</h1>';
    echo '<p class="description">';
    echo __('Here you can enable the built-in User Registration integration which allows to grant commissions to affiliates when they refer new users.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</p>';
    // save
    if (isset($_POST['action']) && $_POST['action'] == 'save') {
        if (isset($_POST['affiliates-user-registraton-admin']) && wp_verify_nonce($_POST['affiliates-user-registraton-admin'], 'save')) {
            delete_option('aff_user_registration_enabled');
            if (!empty($_POST['enabled'])) {
                add_option('aff_user_registration_enabled', 'yes', '', 'no');
            }
            if (is_plugin_active('woocommerce/woocommerce.php')) {
                delete_option('aff_customer_registration_enabled');
                if (!empty($_POST['enabled'])) {
                    add_option('aff_customer_registration_enabled', 'yes', '', 'no');
                }
            }
            if (AFFILIATES_PLUGIN_NAME != 'affiliates') {
                delete_option('aff_user_registration_base_amount');
                if (!empty($_POST['base_amount'])) {
                    $base_amount = floatval($_POST['base_amount']);
                    if ($base_amount < 0) {
                        $base_amount = 0;
                    }
                    add_option('aff_user_registration_base_amount', $base_amount, '', 'no');
                }
            }
            delete_option('aff_user_registration_amount');
            if (!empty($_POST['amount'])) {
                $amount = floatval($_POST['amount']);
                if ($amount < 0) {
                    $amount = 0;
                }
                add_option('aff_user_registration_amount', $amount, '', 'no');
            }
            delete_option('aff_user_registration_currency');
            if (!empty($_POST['currency'])) {
                add_option('aff_user_registration_currency', $_POST['currency'], '', 'no');
            }
            delete_option('aff_user_registration_referral_status');
            if (!empty($_POST['status'])) {
                add_option('aff_user_registration_referral_status', $_POST['status'], '', 'no');
            }
        }
    }
    $user_registration_enabled = get_option('aff_user_registration_enabled', 'no');
    if (is_plugin_active('woocommerce/woocommerce.php')) {
        $customer_registration_enabled = get_option('aff_customer_registration_enabled', 'no');
    }
    if (AFFILIATES_PLUGIN_NAME != 'affiliates') {
        $user_registration_base_amount = get_option('aff_user_registration_base_amount', '');
    }
    $user_registration_amount = get_option('aff_user_registration_amount', '0');
    $user_registration_currency = get_option('aff_user_registration_currency', Affiliates::DEFAULT_CURRENCY);
    $user_registration_referral_status = get_option('aff_user_registration_referral_status', get_option('aff_default_referral_status', AFFILIATES_REFERRAL_STATUS_ACCEPTED));
    echo '<style type="text/css">';
    echo 'div.field { padding: 0 1em 1em 0; }';
    echo 'div.field.user-registration-base-amount input { width: 5em; text-align: right;}';
    echo 'div.field.user-registration-amount input { width: 5em; text-align: right;}';
    echo 'div.field span.label { display: inline-block; width: 20%; }';
    echo 'div.field span.description { display: block; }';
    echo 'div.buttons { padding-top: 1em; }';
    echo '</style>';
    echo '<form action="" name="user_registration" method="post">';
    echo '<div>';
    // enable
    echo '<div class="field user-registration-enabled">';
    echo '<label>';
    printf('<input type="checkbox" name="enabled" value="1" %s />', $user_registration_enabled == 'yes' ? ' checked="checked" ' : '');
    echo ' ';
    echo __('Enable the user registration integration', AFFILIATES_PLUGIN_DOMAIN);
    echo '</label>';
    echo '</div>';
    // enable customer
    if (is_plugin_active('woocommerce/woocommerce.php')) {
        echo '<div class="field customer-registration-enabled">';
        echo '<label>';
        printf('<input type="checkbox" name="enabled" value="1" %s />', $customer_registration_enabled == 'yes' ? ' checked="checked" ' : '');
        echo ' ';
        echo __('Enable the WooCommerce customer registration integration', AFFILIATES_PLUGIN_DOMAIN);
        echo '</label>';
        echo ' ';
        echo '<span class="description">';
        echo __('If the user registration integration should create referrals for new customers that register at checkout, this option should be enabled.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</span>';
        echo '</div>';
    }
    // base amount
    if (AFFILIATES_PLUGIN_NAME != 'affiliates') {
        echo '<div class="field user-registration-base-amount">';
        echo '<label>';
        echo '<span class="label">';
        echo __('Base Amount', AFFILIATES_PLUGIN_DOMAIN);
        echo '</span>';
        echo ' ';
        printf('<input type="text" name="base_amount" value="%s"/>', esc_attr($user_registration_base_amount));
        echo '</label>';
        echo '<span class="description">';
        echo __('When an affiliate refers a new user, a referral is recorded, granting the affiliate an amount in the chosen currency. The amount is calculated taking this base amount into account. For example, if a general referral rate is set, the referral amount equals this base amount multipied by the referral rate.', AFFILIATES_PLUGIN_DOMAIN);
        echo ' ';
        echo __('If set, this <strong>Base Amount</strong> takes precedence over the <strong>Amount</strong>.', AFFILIATES_PLUGIN_DOMAIN);
        if (AFFILIATES_PLUGIN_NAME == 'affiliates-enterprise') {
            echo ' ';
            echo __('If multi-tiered referrals are enabled and level rates are not relative, this <strong>Base Amount</strong> must be used instead of the <strong>Amount</strong>.', AFFILIATES_PLUGIN_DOMAIN);
        }
        echo '</span>';
        echo '</div>';
    }
    // amount
    echo '<div class="field user-registration-amount">';
    echo '<label>';
    echo '<span class="label">';
    echo __('Amount', AFFILIATES_PLUGIN_DOMAIN);
    echo '</span>';
    echo ' ';
    printf('<input type="text" name="amount" value="%s"/>', esc_attr($user_registration_amount));
    echo '</label>';
    echo '<span class="description">';
    echo __('When an affiliate refers a new user, a referral is recorded, granting the affiliate this amount in the chosen currency.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</span>';
    echo '</div>';
    // currency
    $currency_select = '<select name="currency">';
    foreach (apply_filters('affiliates_supported_currencies', Affiliates::$supported_currencies) as $cid) {
        $selected = $user_registration_currency == $cid ? ' selected="selected" ' : '';
        $currency_select .= '<option ' . $selected . ' value="' . esc_attr($cid) . '">' . $cid . '</option>';
    }
    $currency_select .= '</select>';
    echo '<div class="field user-registration-currency">';
    echo '<label>';
    echo '<span class="label">';
    echo __('Currency', AFFILIATES_PLUGIN_DOMAIN);
    echo '</span>';
    echo ' ';
    echo $currency_select;
    echo '</label>';
    echo '</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 = "<select name='status'>";
    foreach ($status_descriptions as $status_key => $status_value) {
        if ($status_key == $user_registration_referral_status) {
            $selected = "selected='selected'";
        } else {
            $selected = "";
        }
        $status_select .= "<option value='{$status_key}' {$selected}>{$status_value}</option>";
    }
    $status_select .= "</select>";
    echo '<div class="field user-registration-referral-status">';
    echo '<label>';
    echo '<span class="label">';
    echo __('Referral Status', AFFILIATES_PLUGIN_DOMAIN);
    echo '</span>';
    echo ' ';
    echo $status_select;
    echo '</label>';
    echo '<p class="description">';
    echo __('The status for referrals that record commissions when affiliates refer new users.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</p>';
    echo '</div>';
    echo '<p>';
    echo __('Recommended choices for the referral status are <em>Accepted</em> and <em>Pending</em>.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</p>';
    echo '<ul>';
    echo '<li>';
    echo __('<strong>Accepted</strong> if these referrals should grant payable commissions to affiliates without the need for further review.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</li>';
    echo '<li>';
    echo __('<strong>Pending</strong> if these referrals are to be reviewed before the commissions should be taken into account for affiliate payouts.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</li>';
    echo '</ul>';
    echo '<div class="buttons">';
    wp_nonce_field('save', 'affiliates-user-registraton-admin', true, true);
    echo '<input class="button button-primary" type="submit" name="submit" value="' . __('Save', AFFILIATES_PLUGIN_DOMAIN) . '"/>';
    echo '<input type="hidden" name="action" value="save"/>';
    echo '</div>';
    echo '</div>';
    echo '</form>';
    affiliates_footer();
}
/**
 * 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();
}
 /**
  * Registration settings.
  */
 public static function section()
 {
     if (isset($_POST['submit'])) {
         if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_SETTINGS_NONCE], 'admin')) {
             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');
             if (!get_option('aff_registration_fields')) {
                 add_option('aff_registration_fields', self::$default_fields, '', 'no');
             }
             $field_enabled = isset($_POST['field-enabled']) ? $_POST['field-enabled'] : array();
             $field_name = isset($_POST['field-name']) ? $_POST['field-name'] : array();
             $field_label = isset($_POST['field-label']) ? $_POST['field-label'] : array();
             $field_required = isset($_POST['field-required']) ? $_POST['field-required'] : array();
             $field_type = isset($_POST['field-type']) ? $_POST['field-type'] : array();
             $max_index = max(array(max(array_keys($field_enabled)), max(array_keys($field_name)), max(array_keys($field_label)), max(array_keys($field_required)), max(array_keys($field_type))));
             $fields = array();
             for ($i = 0; $i <= $max_index; $i++) {
                 if (!empty($field_name[$i])) {
                     $name = strip_tags($field_name[$i]);
                     $name = strtolower($name);
                     $name = preg_replace('/[^a-z0-9_]/', '_', $name);
                     $name = preg_replace('/[_]+/', '_', $name);
                     if (!empty($name) && !isset($fields[$name])) {
                         $fields[$name] = array('obligatory' => false || isset(self::$default_fields[$name]) && self::$default_fields[$name]['obligatory'], 'enabled' => !empty($field_enabled[$i]) || isset(self::$default_fields[$name]) && self::$default_fields[$name]['obligatory'], 'label' => !empty($field_label[$i]) ? strip_tags($field_label[$i]) : '', 'required' => !empty($field_required[$i]), 'is_default' => key_exists($field_name[$i], self::$default_fields), 'type' => !empty($field_type[$i]) ? $field_type[$i] : 'text');
                     }
                 }
             }
             update_option('aff_registration_fields', $fields);
             self::settings_saved_notice();
         }
     }
     $registration = get_option('aff_registration', get_option('users_can_register', false));
     $notify_admin = get_option('aff_notify_admin', get_option('aff_notify_admin', true));
     echo '<form action="" name="options" method="post">' . '<div>' . '<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>';
     echo '<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>';
     // registration fields
     echo '<h3>' . __('Affiliate Registration Form', AFFILIATES_PLUGIN_DOMAIN) . '</h3>';
     echo '<p class="description">';
     echo __('The following fields are provided on the affiliate registration form rendered by the <code>[affiliates_registration]</code> shortcode.', AFFILIATES_PLUGIN_DOMAIN);
     echo '</p>';
     $registration_fields = get_option('aff_registration_fields', self::$default_fields);
     echo '<div id="registration-fields">';
     echo '<table>';
     echo '<thead>';
     echo '</th>';
     echo '<th>';
     echo __('Enabled', AFFILIATES_PLUGIN_DOMAIN);
     echo '</th>';
     echo '<th>';
     echo __('Field Name', AFFILIATES_PLUGIN_DOMAIN);
     echo '</th>';
     echo '<th>';
     echo __('Field Label', AFFILIATES_PLUGIN_DOMAIN);
     echo '</th>';
     echo '<th>';
     echo __('Required', AFFILIATES_PLUGIN_DOMAIN);
     echo '</th>';
     echo '<tr>';
     echo '<th>';
     echo '</tr>';
     echo '</thead>';
     $i = 0;
     echo '<tbody>';
     foreach ($registration_fields as $name => $field) {
         echo '<tr>';
         echo '<td>';
         echo sprintf('<input type="checkbox" name="field-enabled[%d]" %s %s />', $i, $field['enabled'] ? ' checked="checked" ' : '', $field['obligatory'] ? ' readonly="readonly" disabled="disabled" ' : '');
         echo '</td>';
         echo '<td>';
         echo sprintf('<input type="text" name="field-name[%d]" value="%s" %s />', $i, esc_attr($name), $field['is_default'] ? ' readonly="readonly" ' : '');
         echo '</td>';
         echo '<td>';
         echo sprintf('<input type="text" name="field-label[%d]" value="%s" />', $i, esc_attr(stripslashes($field['label'])));
         echo '</td>';
         echo '<td>';
         echo sprintf('<input type="checkbox" name="field-required[%d]" %s />', $i, $field['required'] ? ' checked="checked" ' : '');
         echo '</td>';
         echo '<td>';
         echo sprintf('<input type="hidden" name="field-type[%d]" value="%s" />', $i, $field['type']);
         echo sprintf('<button class="field-up" type="button" value="%d">%s</button>', $i, esc_html(__('Up', AFFILIATES_PLUGIN_DOMAIN)));
         echo sprintf('<button class="field-down" type="button" value="%d">%s</button>', $i, esc_html(__('Down', AFFILIATES_PLUGIN_DOMAIN)));
         if (!$field['is_default']) {
             echo sprintf('<button class="field-remove" type="button" value="%d">%s</button>', $i, esc_html(__('Remove', AFFILIATES_PLUGIN_DOMAIN)));
         }
         echo '</td>';
         echo '</tr>';
         $i++;
     }
     echo '</tbody>';
     echo '</table>';
     echo '<p>';
     echo sprintf('<button class="field-add" type="button" value="%d">%s</button>', $i, esc_html(__('Add a field', AFFILIATES_PLUGIN_DOMAIN)));
     echo '</p>';
     echo '</div>';
     // #registration-fields
     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();
 }
/**
 * 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();
}
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();
}
 /**
  * Renders the integrations section.
  */
 public static function section()
 {
     $output = '';
     $output .= '<p class="description">';
     $output .= __('Integrations link the affiliate system to e-commerce plugins and other platforms.', AFFILIATES_PLUGIN_DOMAIN);
     $output .= ' ';
     $output .= __('The integrations are required to record referrals, as these award affiliates with commissions based on referred purchases or platform-specific actions.', AFFILIATES_PLUGIN_DOMAIN);
     $output .= '</p>';
     if (AFFILIATES_PLUGIN_NAME != 'affiliates') {
         $output .= '<p class="description">';
         $output .= __('You can manage available integrations here, this includes the installation and activation of integrations with e-commerce and other systems.', AFFILIATES_PLUGIN_DOMAIN);
         $output .= '</p>';
     } else {
         $output .= '<p class="description">';
         $output .= sprintf(__('You can install available integrations in the <a href="%s">Plugins</a> section.', AFFILIATES_PLUGIN_DOMAIN), esc_attr(admin_url('plugin-install.php?tab=search&type=author&s=itthinx')));
         $output .= '</p>';
     }
     $output .= '<p class="description">';
     $output .= __('You only need to install integrations with plugins that are actually used on the site.', AFFILIATES_PLUGIN_DOMAIN);
     $output .= '</p>';
     $output .= '<p class="description">';
     $output .= __('User registrations do not require a specific integration to be installed.', AFFILIATES_PLUGIN_DOMAIN);
     $output .= ' ';
     $output .= sprintf(__('Enable the built-in integration if the options provided under <a href="%s">User Registration</a> are sufficient.', AFFILIATES_PLUGIN_DOMAIN), esc_attr(admin_url('admin.php?page=affiliates-admin-user-registration')));
     $output .= '</p>';
     $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
     $all_plugins = get_plugins();
     $list = '<ul class="integrations">';
     foreach (self::$integrations as $key => $integration) {
         $install_url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $key), 'install-plugin_' . $key);
         $activate_url = 'plugins.php?action=activate&plugin=' . urlencode("{$key}/{$key}.php") . '&plugin_status=all&paged=1&s&_wpnonce=' . urlencode(wp_create_nonce("activate-plugin_{$key}/{$key}.php"));
         $deactivate_url = 'plugins.php?action=deactivate&plugin=' . urlencode("{$key}/{$key}.php") . '&plugin_status=all&paged=1&s&_wpnonce=' . urlencode(wp_create_nonce("deactivate-plugin_{$key}/{$key}.php"));
         $integration_class = isset($integration['class']) ? $integration['class'] : '';
         $action = '';
         $button = '';
         $explanation = '';
         if (!key_exists($integration['plugin_file'], $all_plugins)) {
             $action = 'install';
             $button = sprintf('<a class="button" href="%s">Install</a>', esc_url($install_url));
             $explanation = sprintf(__('The <a href="%s">%s</a> plugin is not installed.', AFFILIATES_PLUGIN_DOMAIN), esc_attr($integration['plugin_url']), esc_html($integration['plugin_title']));
         } else {
             if (is_plugin_inactive($integration['plugin_file'])) {
                 $action = 'activate';
                 $button = sprintf('<a class="button" href="%s">Activate</a>', esc_url($activate_url));
                 $explanation = sprintf(__('The <a href="%s">%s</a> plugin is installed but not activated.', AFFILIATES_PLUGIN_DOMAIN), esc_attr($integration['plugin_url']), esc_html($integration['plugin_title']));
                 $integration_class .= ' inactive';
             } else {
                 $action = 'deactivate';
                 $button = sprintf('<a class="button" href="%s">Deactivate</a>', esc_url($deactivate_url));
                 $explanation = sprintf(__('The <a href="%s">%s</a> plugin is installed and activated.', AFFILIATES_PLUGIN_DOMAIN), esc_attr($integration['plugin_url']), esc_html($integration['plugin_title']));
                 $integration_class .= ' active';
             }
         }
         if (AFFILIATES_PLUGIN_NAME == 'affiliates') {
             $button = '';
         }
         $button = apply_filters('affiliates_settings_integration_button', $button, $action, $key, $integration);
         $explanation = apply_filters('affiliates_settings_integration_explanation', $explanation, $action, $key, $integration);
         $list .= sprintf('<li id="integration-%s">', $key);
         $list .= sprintf('<div class="integration %s">', $integration_class);
         $list .= '<h3>' . $integration['title'] . '</h3>';
         $list .= '<p class="description">';
         $list .= $integration['description'];
         $list .= '</p>';
         if (!empty($integration['notes'])) {
             $list .= '<p class="notes">';
             $list .= $integration['notes'];
             $list .= '</p>';
         }
         if (!empty($explanation)) {
             $list .= '<p>';
             $list .= $explanation;
             $list .= '</p>';
         }
         if (!empty($button)) {
             $list .= '<p>';
             $list .= $button;
             $list .= '</p>';
         }
         $list .= '</div>';
         $list .= '</li>';
     }
     $list .= '</ul>';
     $output .= $list;
     echo $output;
     affiliates_footer();
 }
 /**
  * Affiliates WooCommerce Integration Light : admin section.
  */
 public static function affiliates_admin_woocommerce_light()
 {
     $output = '';
     if (!current_user_can(AFFILIATES_ADMINISTER_OPTIONS)) {
         wp_die(__('Access denied.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN));
     }
     $options = get_option(self::PLUGIN_OPTIONS, array());
     if (isset($_POST['submit'])) {
         if (wp_verify_nonce($_POST[self::NONCE], self::SET_ADMIN_OPTIONS)) {
             $options[self::REFERRAL_RATE] = floatval($_POST[self::REFERRAL_RATE]);
             if ($options[self::REFERRAL_RATE] > 1.0) {
                 $options[self::REFERRAL_RATE] = 1.0;
             } else {
                 if ($options[self::REFERRAL_RATE] < 0) {
                     $options[self::REFERRAL_RATE] = 0.0;
                 }
             }
             $options[self::USAGE_STATS] = !empty($_POST[self::USAGE_STATS]);
         }
         update_option(self::PLUGIN_OPTIONS, $options);
     }
     $referral_rate = isset($options[self::REFERRAL_RATE]) ? $options[self::REFERRAL_RATE] : self::REFERRAL_RATE_DEFAULT;
     $usage_stats = isset($options[self::USAGE_STATS]) ? $options[self::USAGE_STATS] : self::USAGE_STATS_DEFAULT;
     $output .= '<div>' . '<h2>' . __('Affiliates WooCommerce Integration Light', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</h2>' . '</div>';
     $output .= '<p class="manage" style="padding:1em;margin-right:1em;font-weight:bold;font-size:1em;line-height:1.62em">';
     $output .= __('You can support the development of the Affiliates plugin and get additional features with <a href="http://www.itthinx.com/shop/affiliates-pro/" target="_blank">Affiliates Pro</a> and <a href="http://www.itthinx.com/shop/affiliates-enterprise/" target="_blank">Affiliates Enterprise</a>.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN);
     $output .= '</p>';
     $output .= '<div class="manage" style="padding:2em;margin-right:1em;">';
     $output .= '<form action="" name="options" method="post">';
     $output .= '<div>';
     $output .= '<h3>' . __('Referral Rate', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</h3>';
     $output .= '<p>';
     $output .= '<label for="' . self::REFERRAL_RATE . '">' . __('Referral rate', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</label>';
     $output .= '&nbsp;';
     $output .= '<input name="' . self::REFERRAL_RATE . '" type="text" value="' . esc_attr($referral_rate) . '"/>';
     $output .= '</p>';
     $output .= '<p>';
     $output .= __('The referral rate determines the referral amount based on the net sale made.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN);
     $output .= '</p>';
     $output .= '<p class="description">';
     $output .= __('Example: Set the referral rate to <strong>0.1</strong> if you want your affiliates to get a <strong>10%</strong> commission on each sale.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN);
     $output .= '</p>';
     $output .= '<h3>' . __('Usage stats', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</h3>';
     $output .= '<p>';
     $output .= '<input name="' . self::USAGE_STATS . '" type="checkbox" ' . ($usage_stats ? ' checked="checked" ' : '') . '/>';
     $output .= ' ';
     $output .= '<label for="' . self::USAGE_STATS . '">' . __('Allow the plugin to provide usage stats.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</label>';
     $output .= '<br/>';
     $output .= '<span class="description">' . __('This will allow the plugin to help in computing how many installations are actually using it. No personal or site data is transmitted, this simply embeds an icon on the bottom of the Affiliates admin pages, so that the number of visits to these can be counted. This is useful to help prioritize development.', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '</span>';
     $output .= '</p>';
     $output .= '<p>';
     $output .= wp_nonce_field(self::SET_ADMIN_OPTIONS, self::NONCE, true, false);
     $output .= '<input class="button-primary" type="submit" name="submit" value="' . __('Save', AFF_WOOCOMMERCE_LIGHT_PLUGIN_DOMAIN) . '"/>';
     $output .= '</p>';
     $output .= '</div>';
     $output .= '</form>';
     $output .= '</div>';
     echo $output;
     affiliates_footer();
 }
/**
 * Show edit affiliate form.
 * @param int $affiliate_id affiliate id
 */
function affiliates_admin_affiliates_edit($affiliate_id)
{
    global $wpdb;
    if (!current_user_can(AFFILIATES_ADMINISTER_AFFILIATES)) {
        wp_die(__('Access denied.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliate = affiliates_get_affiliate(intval($affiliate_id));
    if (empty($affiliate)) {
        wp_die(__('No such affiliate.', AFFILIATES_PLUGIN_DOMAIN));
    }
    $affiliates_users_table = _affiliates_get_tablename('affiliates_users');
    $affiliate_user = null;
    $affiliate_user_edit = '';
    $affiliate_user_fields = '';
    $affiliate_user_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$affiliates_users_table} WHERE affiliate_id = %d", intval($affiliate_id)));
    if ($affiliate_user_id !== null) {
        $affiliate_user = get_user_by('id', intval($affiliate_user_id));
        if ($affiliate_user) {
            // user edit link
            if (current_user_can('edit_user', $affiliate_user->ID)) {
                $affiliate_user_edit = sprintf(__('Edit %s', AFFILIATES_PLUGIN_DOMAIN), '<a target="_blank" href="' . esc_url("user-edit.php?user_id={$affiliate_user->ID}") . '">' . $affiliate_user->user_login . '</a>');
            }
            // user meta fields
            require_once AFFILIATES_CORE_LIB . '/class-affiliates-settings.php';
            require_once AFFILIATES_CORE_LIB . '/class-affiliates-settings-registration.php';
            $registration_fields = Affiliates_Settings_Registration::get_fields();
            // remove fields not stored as user meta
            foreach (Affiliates_Registration::get_skip_meta_fields() as $key) {
                unset($registration_fields[$key]);
            }
            // render user meta
            foreach ($registration_fields as $name => $field) {
                if ($field['enabled']) {
                    $affiliate_user_fields .= '<div class="field">';
                    $affiliate_user_fields .= '<label>';
                    $affiliate_user_fields .= esc_html(stripslashes($field['label']));
                    // @todo i18n
                    $affiliate_user_fields .= ' ';
                    $type = isset($field['type']) ? $field['type'] : 'text';
                    $value = get_user_meta($affiliate_user->ID, $name, true);
                    $affiliate_user_fields .= sprintf('<input type="text" value="%s" readonly="readonly" />', esc_attr(stripslashes($value)));
                    $affiliate_user_fields .= '</label>';
                    $affiliate_user_fields .= '</div>';
                }
            }
        }
    }
    $current_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $current_url = remove_query_arg('action', $current_url);
    $current_url = remove_query_arg('affiliate_id', $current_url);
    $name = isset($_POST['name-field']) ? $_POST['name-field'] : $affiliate['name'];
    $email = isset($_POST['email-field']) ? $_POST['email-field'] : $affiliate['email'];
    $user_login = isset($_POST['user-field']) ? $_POST['user-field'] : ($affiliate_user != null ? $affiliate_user->user_login : '');
    $from_date = isset($_POST['from-date-field']) ? $_POST['from-date-field'] : $affiliate['from_date'];
    $thru_date = isset($_POST['thru-date-field']) ? $_POST['thru-date-field'] : $affiliate['thru_date'];
    $output = '<div class="manage-affiliates">' . '<div>' . '<h1>' . __('Edit an affiliate', AFFILIATES_PLUGIN_DOMAIN) . '</h1>' . '</div>' . '<form id="edit-affiliate" action="' . esc_url($current_url) . '" method="post">' . '<div class="affiliate edit">' . '<input id="affiliate-id-field" name="affiliate-id-field" type="hidden" value="' . esc_attr(intval($affiliate_id)) . '"/>' . '<div class="field">' . '<label class="field-label first required">' . '<span class="label">' . __('Name', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . '<input id="name-field" name="name-field" class="namefield" type="text" value="' . esc_attr(stripslashes($name)) . '"/>' . '</label>' . '</div>' . '<div class="field">' . '<label class="field-label">' . '<span class="label">' . __('Email', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . '<input id="email-field" name="email-field" class="emailfield" type="text" value="' . esc_attr($email) . '"/>' . '</label>' . ' ' . '<span class="description">' . __("If a valid <strong>Username</strong> is specified and no email is given, the user's email address will be used automatically.", AFFILIATES_PLUGIN_DOMAIN) . '</span>' . '</div>' . '<div class="field">' . '<label class="field-label">' . '<span class="label">' . __('Username', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . '<input id="user-field" name="user-field" class="userfield" type="text" autocomplete="off" value="' . esc_attr(stripslashes($user_login)) . '"/>' . '</label>' . ' ' . $affiliate_user_edit . '</div>' . $affiliate_user_fields . '<div class="field">' . '<label class="field-label">' . '<span class="label">' . __('From', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . '<input id="from-date-field" name="from-date-field" class="datefield" type="text" value="' . esc_attr($from_date) . '"/>' . '</label>' . '</div>' . '<div class="field">' . '<label class="field-label">' . '<span class="label">' . __('Until', AFFILIATES_PLUGIN_DOMAIN) . '</span>' . ' ' . '<input id="thru-date-field" name="thru-date-field" class="datefield" type="text" value="' . esc_attr($thru_date) . '"/>' . '</label>' . '</div>';
    $output .= '<div class="field">' . wp_nonce_field('affiliates-edit', AFFILIATES_ADMIN_AFFILIATES_NONCE, true, false) . '<input class="button button-primary" type="submit" value="' . __('Save', AFFILIATES_PLUGIN_DOMAIN) . '"/>' . '<input type="hidden" value="edit" name="action"/>' . ' ' . '<a class="cancel button" href="' . esc_url($current_url) . '">' . __('Cancel', AFFILIATES_PLUGIN_DOMAIN) . '</a>' . '</div>' . '</div>' . '</form>' . '</div>';
    // .manage-affiliates
    echo $output;
    affiliates_footer();
}
function affiliates_admin_add_ons()
{
    echo '<div class="affiliates-admin-add-ons add-ons">';
    echo '<h1>';
    echo __('Affiliates Extensions and Add-Ons', AFFILIATES_PLUGIN_DOMAIN);
    echo '</h1>';
    echo '<p>';
    echo __('Get additional features and access to premium support!', AFFILIATES_PLUGIN_DOMAIN);
    echo '</p>';
    echo '<h2>';
    echo __('Recommended plugins and extensions', AFFILIATES_PLUGIN_DOMAIN);
    echo '</h2>';
    $entries = array('affiliates-pro' => array('title' => 'Affiliates Pro', 'content' => 'Affiliates Pro is a powerful affiliate marketing and management system for sellers, shops and developers, who want to increase sales and foster growth with their own affiliate program.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-pro.png', 'url' => 'http://www.itthinx.com/shop/affiliates-pro/', 'index' => 10), 'affiliates-enterprise' => array('title' => 'Affiliates Enterprise', 'content' => 'Affiliates Enterprise is a powerful affiliate marketing and management system for active marketers, sellers, shops and developers. This growth-oriented business solution features affiliate campaigns, mulitple tiers and pixel tracking, in addition to all the powerful features included in Affiliates Pro.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-enterprise.png', 'url' => 'http://www.itthinx.com/shop/affiliates-enterprise/', 'index' => 10), 'affiliates-by-username' => array('title' => 'Affiliates by Username', 'content' => 'This extension allows affiliate links to indicate usernames in addition to the affiliate IDs used normally.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-by-username.png', 'url' => 'http://www.itthinx.com/shop/affiliates-by-username/', 'index' => 20), 'affiliates-coupons' => array('title' => 'Affiliates Coupons', 'content' => 'This extension requires Affiliates Pro or Affiliates Enterprise and WooCommerce. It allows to create coupons for affiliates automatically and in bulk.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-coupons.png', 'url' => 'http://www.itthinx.com/shop/affiliates-coupons/', 'index' => 100), 'affiliates-ms' => array('title' => 'Affiliates MS', 'content' => 'Affiliates MS is a solution to maintain a centralized affiliate program for a WordPress Network of sites.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-ms.png', 'url' => 'http://www.itthinx.com/shop/affiliates-ms/', 'index' => 100), 'affiliates-permanent' => array('title' => 'Affiliates Permanent', 'content' => 'New customers (or new users) are assigned to the referring affiliate. The affiliate will be credited with a referral on every purchase made by the customer from thereon. Assignments can be changed manually in user profiles.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-permanent.png', 'url' => 'http://www.itthinx.com/shop/affiliates-permanent/', 'index' => 100), 'affiliates-products' => array('title' => 'Affiliates Products', 'content' => 'This extension requires WooCommerce and provides product commissions for distribution and vendors. This extension automatically grants commissions for product partners or affiliates on specific product sales. It is suitable if you want to grant an affiliate a fixed commission on every sale of a product.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-products.png', 'url' => 'http://www.itthinx.com/shop/affiliates-products/', 'index' => 100), 'affiliates-users' => array('title' => 'Affiliates Users', 'content' => 'This extension automatically creates affiliate accounts for new users. It also allows to create affiliate accounts for all existing users.', 'image' => AFFILIATES_PLUGIN_URL . 'images/add-ons/affiliates-users.png', 'url' => 'http://www.itthinx.com/shop/affiliates-users/', 'index' => 20));
    usort($entries, 'affiliates_admin_add_ons_sort');
    echo '<ul class="add-ons">';
    foreach ($entries as $key => $entry) {
        echo '<li class="add-on">';
        echo sprintf('<a href="%s">', $entry['url']);
        echo '<h3>';
        echo sprintf('<img src="%s"/>', $entry['image']);
        echo $entry['title'];
        echo '</h3>';
        echo '<p>';
        echo $entry['content'];
        echo '</p>';
        echo '</a>';
        echo '</li>';
        // .add-on
    }
    echo '</ul>';
    // .add-ons
    if (AFFILIATES_PLUGIN_NAME == 'affiliates') {
        echo '<h2>';
        echo __('Affiliates Pro', AFFILIATES_PLUGIN_DOMAIN);
        echo '</h2>';
        echo sprintf('<img class="screenshot" alt="Affiliates Pro Menu" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Affiliates Pro Menu-small.png');
        echo sprintf('<img class="screenshot" alt="Banners" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Banners-small.png');
        echo sprintf('<img class="screenshot" alt="Notifications" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Notifications - Affiliate Registration-small.png');
        echo sprintf('<img class="screenshot" alt="Totals" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Totals-small.png');
        echo '<ul>';
        echo '<li>';
        echo __('Additional and advanced integrations accessible with Affiliates Pro and Affiliates Enterprise include social sharing integrations with AddToAny and AddThis, support for affiliate commissions based on Pay Per Click (PPC), Events Manager, Formidable Forms, Formidable Pro and Gravity Forms integrations.', AFFILIATES_PLUGIN_DOMAIN);
        echo ' ';
        echo __('Please consult the Shop pages for an updated list of included integrations.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Affiliate attributes for individual commission rates, coupons, ...', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Fixed, percentage or formula based commissions', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Extended totals report with additional filters', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Export Totals and Mass Payment File generation', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Advanced shortcodes including banners and graphs', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Banner management', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Customizable affiliate registration email', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Notifications including customizable messages', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Affiliate link generator form', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('The <a href="http://docs.itthinx.com/">Documentation</a> site also provides up-to-date information on the Affiliates, Affiliates Pro and Affiliates Enterprise plugin features.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '</ul>';
    }
    if (AFFILIATES_PLUGIN_NAME == 'affiliates' || AFFILIATES_PLUGIN_NAME == 'affiliates-pro') {
        echo '<h2>';
        echo __('Affiliates Enterprise', AFFILIATES_PLUGIN_DOMAIN);
        echo '</h2>';
        echo sprintf('<img class="screenshot enterprise" alt="Multiple Tiers" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Multi-tiered Referrals-small.png');
        echo sprintf('<img class="screenshot enterprise" alt="Banners" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Specific Level Rates-small.png');
        echo sprintf('<img class="screenshot enterprise" alt="Notifications" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/Tiers-small.png');
        echo sprintf('<img class="screenshot enterprise" alt="Campaigns" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/campaigns.png');
        echo sprintf('<img class="screenshot enterprise" alt="Campaigns Administration" src="%s"/>', AFFILIATES_PLUGIN_URL . 'images/add-ons/campaigns-admin.png');
        echo '<ul>';
        echo '<li>';
        echo __('Includes all additional features available in Affiliates Pro.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Affiliate campaign management and tracking.', AFFILIATES_PLUGIN_DOMAIN);
        echo ' ';
        echo __('This allows affiliates to distinguish between income they generate by placing affiliate links on Facebook, from that generated through Twitter and other sources.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Multi-tier capability with unlimited levels and rates.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '<li>';
        echo __('Pixel Tracking makes it even easier for Affiliates to refer customers, as they do not even need to click an affiliate link. Supported methods are image and iframe tracking pixels.', AFFILIATES_PLUGIN_DOMAIN);
        echo '</li>';
        echo '</ul>';
    }
    echo '<h2>';
    echo __('Add-Ons', AFFILIATES_PLUGIN_DOMAIN);
    echo '</h2>';
    echo '<p>';
    echo __('Free and premium extensions are listed on the <a href="http://www.itthinx.com/plugins-overview/">Overview</a> page and in the <a href="http://www.itthinx.com/shop/">Shop</a>.', AFFILIATES_PLUGIN_DOMAIN);
    echo '</p>';
    echo '</div>';
    affiliates_footer();
}
예제 #14
0
/**
 * 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();
}
/**
 * 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();
}
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();
}
/**
 * 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();
}
 /**
  * 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();
 }
        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 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();
}
 /**
  * Renders the generator form and handles page
  * generation form submission.
  */
 public static function section()
 {
     $pages_generated_info = '';
     //
     // handle page generation form submission
     //
     if (isset($_POST['generate'])) {
         if (wp_verify_nonce($_POST[AFFILIATES_ADMIN_SETTINGS_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>';
             }
         }
     }
     echo '<h3>' . __('Generator', AFFILIATES_PLUGIN_DOMAIN) . '</h3>';
     //
     // Generator form
     //
     echo '<form action="" name="options" method="post">' . '<div>' . '<p>' . __('Press the button to generate a default affiliate area.', AFFILIATES_PLUGIN_DOMAIN) . ' ' . '<input class="generate button" name="generate" type="submit" value="' . __('Generate', AFFILIATES_PLUGIN_DOMAIN) . '" />' . wp_nonce_field('admin', AFFILIATES_ADMIN_SETTINGS_GEN_NONCE, true, false) . '</p>' . $pages_generated_info . '</div>' . '</form>';
     echo '<p>';
     echo __('The generated page contains Affiliates shortcodes and can be used as an out-of-the-box affiliate area or as a framework for customized affiliate areas and pages.', AFFILIATES_PLUGIN_DOMAIN);
     echo '</p>';
     //
     // Pages containing affiliates shortcodes
     //
     echo '<h3>' . __('Pages', AFFILIATES_PLUGIN_DOMAIN) . '</h3>';
     global $wpdb;
     $post_options = '';
     $post_ids = array();
     // We also have [referrer_id] and [referrer_user] but these are not essential in
     // determining whether an affiliate page has been set up.
     $posts = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%[affiliates_%' AND post_status = 'publish'");
     foreach ($posts as $post) {
         $post_ids[] = $post->ID;
     }
     if (count($posts) == 0) {
         echo '<p>';
         echo __('It seems that you do not have any pages set up for your affiliates yet.', AFFILIATES_PLUGIN_DOMAIN);
         echo '</p>';
         echo '<p>';
         echo __('You can use the page generation option to create the default affiliate area for your affiliates.', AFFILIATES_PLUGIN_DOMAIN);
         echo '</p>';
     } else {
         echo '<p>';
         echo _n('This page containing Affiliates shortcodes has been detected :', 'These pages containing Affiliates shortcodes have been detected :', count($posts), AFFILIATES_PLUGIN_DOMAIN);
         echo '</p>';
         $post_list = '<ul>';
         foreach ($post_ids as $post_id) {
             $post_title = get_the_title($post_id);
             $post_list .= sprintf('<li><a href="%s">%s</a></li>', get_permalink($post_id), esc_html($post_title));
         }
         $post_list .= '</ul>';
         echo $post_list;
     }
     echo '<p>';
     _e('You can modify the default affiliate area and also create customized pages for your affiliates using shortcodes.', AFFILIATES_PLUGIN_DOMAIN);
     echo '</p>';
     echo '<p>';
     _e('Please refer to the <a href="http://docs.itthinx.com/document/affiliates/">Documentation</a> for more details.', AFFILIATES_PLUGIN_DOMAIN);
     echo '</p>';
     affiliates_footer();
 }