如何存储岗位独立的岗位评级系统数据?

时间:2013-11-01 作者:th3rion

下面是简单的后评价系统的代码(本网站的教程TUTORIAL ) - 它工作得很好,但我需要改变一下。现在,在用户投票的地方,他不能再以$timebeforevote(1440分钟)为同一帖子投票。我想阻止所有帖子的用户投票,而不仅仅是这个帖子。

我认为问题是函数正在使用以下代码在当前post meta字段中查找用户ip:

$meta_IP = get_post_meta($post_id, "voted_IP");
$voted_IP = $meta_IP[0];
退货$voted_IP 并将其与$ip = $_SERVER[\'REMOTE_ADDR\']; 我试着用query来修改它(query在meta字段中查找所有帖子的ip),这样它就可以在所有帖子中搜索ip,但它不起作用。我试着让它工作两天,但什么都不起作用。

评级系统代码:

$timebeforerevote = 1440;

add_action(\'wp_ajax_nopriv_post-like\', \'post_like\');
add_action(\'wp_ajax_post-like\', \'post_like\');

wp_enqueue_script(\'like_post\', get_template_directory_uri().\'/js/post-like.js\', array(\'jquery\'), \'1.0\', 1 );
wp_localize_script(\'like_post\', \'ajax_var\', array(
    \'url\' => admin_url(\'admin-ajax.php\'),
    \'nonce\' => wp_create_nonce(\'ajax-nonce\')
));

function post_like()
{
    $nonce = $_POST[\'nonce\'];

    if ( ! wp_verify_nonce( $nonce, \'ajax-nonce\' ) )
        die ( \'Busted!\');

    if(isset($_POST[\'post_like\']))
    {
        $ip = $_SERVER[\'REMOTE_ADDR\'];
        $post_id = $_POST[\'post_id\'];

        $meta_IP = get_post_meta($post_id, "voted_IP");

        $voted_IP = $meta_IP[0];
        if(!is_array($voted_IP))
            $voted_IP = array();

        $meta_count = get_post_meta($post_id, "votes_count", true);

        if(!hasAlreadyVoted($post_id))
        {
            $voted_IP[$ip] = time();

            update_post_meta($post_id, "voted_IP", $voted_IP);
            update_post_meta($post_id, "votes_count", ++$meta_count);

            echo $meta_count;
        }
        else
            echo "already";
    }
    exit;
}

function hasAlreadyVoted($post_id)
{
    global $timebeforerevote;

    $meta_IP = get_post_meta($post_id, "voted_IP");
    $voted_IP = $meta_IP[0];
    if(!is_array($voted_IP))
        $voted_IP = array();
    $ip = $_SERVER[\'REMOTE_ADDR\'];

    if(in_array($ip, array_keys($voted_IP)))
    {
        $time = $voted_IP[$ip];
        $now = time();

        if(round(($now - $time) / 60) > $timebeforerevote)
            return false;

        return true;
    }

    return false;
}

function getPostLikeLink($post_id)
{
    $themename = "twentyeleven";

    $vote_count = get_post_meta($post_id, "votes_count", true);

    $output = \'<p class="post-like">\';

    if ($vote_count == 0)
        $output .= \'<span class="count">0<span class="glosow"><br>głosów w rankingu</span></span>\';
    else
        $output .= \'<span class="count">\'.$vote_count.\'<span class="glosow"><br>głosów w rankingu</span></span>\';

    if(hasAlreadyVoted($post_id))
        $output .= \'<span title="Już głosowałeś" class="qtip alreadyvoted"></span>\';
    else
        $output .= \'<a href="#" data-post_id="\'.$post_id.\'">
                    <span  title="\'.__(\'Głosuj\', $themename).\'"class="qtip like"></span></a>\';
    $output .= \'</p>\';

    return $output;
}

1 个回复
最合适的回答,由SO网友:Nicolai Grossherr 整理而成

你想要的其实很容易实现。您使用的教程中的代码通过以下方式保存和获取数据update_post_meta()get_post_meta(), 这不适合您的用例。

你只需要存储你的数据post independent. 这种思想与您所实现的投票系统的定时限制所需的IP密钥和时间值数组有关。您可以而且可能应该保持投票计数的保存方式不变,因为保存此信息是合乎逻辑的。

可能是实现保存[IP]=>;[时间]«阵列后独立是通过使用Options API. 因此,可以使用API提供的函数替换代码现在使用的post meta函数。您需要的功能包括:update_option()get_option().

下面我将概述如何使用它们:

//option name
$opt_nam = \'def_opt_nam\';

//get IP and TIME
$ip = $_SERVER[\'REMOTE_ADDR\'];
$time = time();
//current visitor key:IP => value:TIME pair
$cvi_ipt = array (
    $ip => $time
);

//get the data array
$opt_arr = get_option( $opt_nam );

//update data array
//merge current visitor array with the data array from the options table
//if the key doesn\'t exist the a new pair is created, if a key exists the value gets updated
$upd_opt = array_merge( $opt_arr, $cvi_ipt );
//actually do the update
update_option( $opt_nam, $upd_opt );
当然,上面的代码是示例性的。您必须使用post-meta替换依赖于post的方法,使用建议的和概述的独立于post的方法,并自己使用Options-API。但现在这应该不难做到了。

更新:

function post_like()
{
    $nonce = $_POST[\'nonce\'];

    if ( ! wp_verify_nonce( $nonce, \'ajax-nonce\' ) )
        die ( \'Busted!\');

    if(isset($_POST[\'post_like\']))
    {
        $ip = $_SERVER[\'REMOTE_ADDR\'];
        $post_id = $_POST[\'post_id\'];

        $voted_IP = get_option( "voted_IP" );

        if(!is_array($voted_IP))
            $voted_IP = array();

        $meta_count = get_post_meta($post_id, "votes_count", true);

        if(!hasAlreadyVoted())
        {

            $ip = $_SERVER[\'REMOTE_ADDR\'];
            $time = time();
            $cvi_ipt = array (
                $ip => $time
            );
            $upd_opt = array_merge( $voted_IP, $cvi_ipt );

            update_option( "voted_IP", $upd_opt );
            update_post_meta($post_id, "votes_count", ++$meta_count);

            echo $meta_count;
        }
        else
            echo "already";
    }
    exit;
}

function hasAlreadyVoted()
{
    global $timebeforerevote;

    $voted_IP = get_option( "voted_IP" );

    if(!is_array($voted_IP))
        $voted_IP = array();

    $ip = $_SERVER[\'REMOTE_ADDR\'];

    if(in_array($ip, array_keys($voted_IP)))
    {
        $time = $voted_IP[$ip];
        $now = time();

        if(round(($now - $time) / 60) > $timebeforerevote)
            return false;

        return true;
    }

    return false;
}
我将我的建议实现到您在问题中发布的代码中,但它未经测试。

编辑:回应评论。正如我之前所说,唯一要做的就是更改数据存储的位置。详细说明一下:Post meta取决于Post-您可以通过使用Post id保存和获取wp\\u postmeta表中的元数据来认识到这一点。相反,选项api将数据存储在wp\\U选项表中。我建议的代码是独立于post的,因为有一个选项用于存储所有数据-键:ip=>;值:时间对-来自所有帖子。关于这件事,只言片语。

结束