没有插件学习方法的Wordpress收藏系统

鲨鱼

下午好,我使用Wordpress和php开发了一个收藏夹系统,它的工作原理如下:单击添加收藏夹图标,然后向aphp发送一个带有收藏夹ID和已登录用户ID的ajax请求。带有收藏夹用户数的信息,并在登录的用户中包含收藏夹ID的数组。无论如何,问题是,系统正在运行,但是每当我开发某些东西时,我总是在想是否有办法改进代码,是否有办法以更好的方式来做,我将把代码留在这里。

所有这些都可以学习好吗?

的HTML

<div class="stats -favorites">
    <a class="icon -click <?php echo is_favorite(get_current_user_id(), $user_ID) ? 'fa' : 'far' ?> fa-heart" data-js="favorite" data-favorite="<?php echo $user_ID; ?>" data-user="<?php echo get_current_user_id(); ?>"></a>
    <span class="label" data-js="favorite_label">
        <?php echo get_favorites_num( $user_ID ); ?>
    </span>
    <span class="value">favoritos</span>
</div>

JS

 function setFavorite(userid, favoriteid) {

    var favorite_field = $('[data-js="favorite"]');
    var favorite_label = $('[data-js="favorite_label"]');

    $.ajax({
        url        : appmeninas_ajax_params.ajaxurl,
        data       : {
                        'action'     : 'setfavorite',
                        'userid'     : userid,
                        'favoriteid' : favoriteid,
                    },
        dataType   : 'json',
        type       : 'POST',
        cache      : false,

        beforeSend : function( xhr ) {
            favorite_field.removeClass('far fa fa-heart').addClass('fas fa-circle-notch fa-spin');
        },

        success : function( data ) {

            var icon = (data.is_favorite) ? 'fa fa-heart' : 'far fa-heart';

            favorite_field.removeClass('fas fa-circle-notch fa-spin');
            favorite_field.addClass(icon);

            favorite_label.html('');
            favorite_label.append(data.favorites_num);

        }
    });

};

$('[data-js=favorite]').click(function() {
    var favoriteid = $(this).data('favorite');
    var userid = $(this).data('user');
    setFavorite(userid, favoriteid);
});

的PHP

function setfavorite() {

    $userid = $_POST['userid'];
    $favoriteid = $_POST['favoriteid'];

    // user require favorite
    $favorites_list = get_field( 'favorites_list', 'user_' .$userid );
    $favorites_num = get_field( 'favorites', 'user_' .$favoriteid );

    if ( !$favorites_list ) {
        $favorites_list = [];
    }

    // profile favorite
    if ( in_array( $favoriteid, $favorites_list ) ) {

        $favorites_num--;
        $tmp = array_search( $userid, $favorites_list );
        array_splice( $favorites_list, $tmp, 1 );
        $is_favorite = false;

    } else {

        $favorites_num++;
        $favorites_list[] = $favoriteid;
        $is_favorite = true;

    }


    // set favorite counter
    update_user_meta( $favoriteid, 'favorites', $favorites_num );

    // set favorite list
    update_user_meta( $userid, 'favorites_list', $favorites_list );


    echo json_encode( array(
        'favorites_num'  => $favorites_num,
        'favorites_list' => $favorites_list,
        'is_favorite'    => $is_favorite,
    ) );

    die();

}

function is_favorite($userid, $favoriteid) {
    $favorites_list = get_field( 'favorites_list', 'user_' .$userid );
    return in_array( $favoriteid, $favorites_list );
}
function get_favorites_num( $userid ) {
    if ( get_field( 'favorites', 'user_' .$userid ) ) {
        return get_field( 'favorites', 'user_' .$userid );
    } else {
        return '0';
    }
}


add_action('wp_ajax_setfavorite', 'setfavorite');
add_action('wp_ajax_nopriv_setfavorite', 'setfavorite');
托马斯·费林格

我可能会在未来2个月内实现相同的功能。我已经开始研究插件,但是正如您的问题所指出的那样,这似乎并不难。

我尝试再回来,但首先我需要一个前端个人资料页面,我可以在其中列出我的最爱。

到目前为止,第一印象还不错,但首先,我会关注$_POST数组并清理和验证值,因为有时不仅您的ajax会调用。

if ( isset($_POST['userid']) && isset($_POST['favoriteid']) ) { // Both $_POST values exist

  $userid = filter_var($_POST['userid'], FILTER_SANITIZE_NUMBER_INT);
  $favoriteid = filter_var($_POST['favoriteid'], FILTER_SANITIZE_NUMBER_INT);

  if ( filter_var($userid, FILTER_VALIDATE_INT) && filter_var($favoriteid, FILTER_VALIDATE_INT) ) {
    // $_POST was save, both values are Integers
  }
}

第二个与get_field有关的是ACF插件提供的功能。因此,在停用它或将其替换为JCF时,可能会导致错误。

您可以使用来避免这种情况if ( function_exists('get_field') ) {然后,只有在停用ACF时,您的代码才会停止工作。

否则,似乎不需要使用ACF函数,而可以使用WP本机函数get_user_meta

function is_favorite($userid, $favoriteid){
  $favorites_list = get_user_meta($userid, 'favorites_list', true);
  // check the new output instead of get_field
  return in_array( $favoriteid, $favorites_list );
}

get_field('favorites', 'user_' .$favoriteid)那时所有的电话似乎都是错误的。ACF文档说get_fieldist的第二个参数是帖子ID,因此我不知道“ user_”的含义。我会打电话给:

function get_favorites_num($favoriteid){
  return get_user_meta($favoriteid, 'favorites', true) || 0;
}

我现在准备好了自己喜欢的系统,用户可以在其中收藏特定post_type中的帖子

的HTML

    <?php while ( have_posts() ) : the_post() ?>
      <?php 

        $customPostsMeta = get_post_custom();
        $favorite_class = 'favorite-me disabled';
        $fav_count = isset($customPostsMeta['_favorites']) ? intval($customPostsMeta['_favorites'][0]) : 0;
        $fav_count_text = $fav_count > 0 ? '(' . $fav_count . ')' : '';
        $fav_count = ' <span class="fav-count clearfix">' . $fav_count_text . '</span>';
        $favorite_title = '';

        if ( is_user_logged_in() ) {
          $user = wp_get_current_user();
          $favorites = get_user_meta($user->ID, '_favorite_posts', true);
          $fav_key = array_search($post_id, $favorites);
          $is_favorite = ( $fav_key !== false );
          if ( $is_favorite ) {
            $favorite_class .= ' is-favorite';
            $favorite_title = ' title="' . get_the_title() . ' ' . __('favorisieren', 'myTheme') . '"';
          } else {
            $favorite_title = ' title="' . get_the_title() . ' ' . __('nicht mehr favorisieren', 'myTheme') . '"';
          }
        }
    ?>
    <a class="<?php echo $favorite_class; ?>" href="#post-<?php the_ID() ?>"<?php echo $favorite_title; ?>><?php echo __('Favorit', 'myTheme')?><?php echo $fav_count; ?></a>
  <?php endwhile; ?>

JS

// i use a small self written JS module frame where this is included as module
// favorite.setup() is fired imediatly, favorite.ready() fires on document ready
// you can see a full version here: https://dev.alphabetisierung.at/wp-content/themes/sandbox_2017/js/actions.js
// line 732

    /**
     * Favorites ajax system
     * =====================
     * https://stackoverflow.com/questions/60468237
     */
    favorite: {
      options: {
        selectors: {
          link: '.favorite-me',
          fav_count: '.fav-count'
        },
        classNames: {
          disabled: 'disabled',
          is_favorite: 'is-favorite',
        }
      },
      events: function(){
        var options = this.options,
            selectors = options.selectors,
            classNames = options.classNames,
            info = this.info;

        this.$favorites.on('click', function(event){
          var post_id = this.hash.replace('#post-', ''),
              $favorite_link = $(this).addClass(classNames.disabled),
              $fav_count = $favorite_link.children(selectors.fav_count),
              $favorite = $.ajax({
                url: myTheme.page.urls.ajax,
                type: 'post',
                data: {
                  action: info.name, // derived from the module name "favorite"
                  verify: myTheme.page.verify, // https://developer.wordpress.org/reference/functions/check_ajax_referer/
                  post_id: post_id
                  // user_id of user who takes the action is not necessary
                }
              });

          $favorite.done(function(data){
            var fav_count = data.hasOwnProperty('fav_count') ? parseInt(data.fav_count) : 0,
                fav_count_text = '',
                is_favorite = data.hasOwnProperty('is_favorite') ? data.is_favorite : false;

            if ( fav_count > 0 ) {
              fav_count_text = '(' + fav_count + ')';
            }
            $fav_count.html(fav_count_text);

            if ( is_favorite && !$favorite_link.is('.' + classNames.is_favorite) ) {
              $favorite_link.addClass(classNames.is_favorite);
            } else {
              $favorite_link.removeClass(classNames.is_favorite);
            }
            $favorite_link.removeClass(classNames.disabled);
          });
          event.preventDefault();
        });
      },
      ready: function ready(){
        var selectors = this.options.selectors,
            classNames = this.options.classNames;

        this.$favorites = $(selectors.link).removeClass(classNames.disabled);
        this.events();
      },
      setup: function setup(){
        var setup = myTheme.info.is_user_logged_in && myTheme.info.post_type === 'my_custom_post_type';
        return setup; // only for my post_type
      }

的PHP

add_action('wp_enqueue_scripts', 'myTheme_enqueue_scripts');
add_action('wp_ajax_favorite', 'myTheme_set_favorite');
// wp_ajax_nopriv_{action} is not necessary when feature is only for logged in users


  function myTheme_enqueue_scripts(){
    $data = array(
      'id' => get_the_ID(),
      'urls' => array(
        'ajax' => admin_url('admin-ajax.php'),
        'template' => get_stylesheet_directory_uri(),
      ),
      'verify' => wp_create_nonce('myThemeOrAction_ajax_call'), // used for check_ajax_referer()
      // ...
      'info' => array(
        // ...
        'is_user_logged_in' => is_user_logged_in(),
        'post_type' => get_post_type(),
      ),
    );
    // ...
    wp_localize_script('actions', 'myTheme_data', $data );
  }


function myTheme_set_favorite(){
  check_ajax_referer('myThemeOrAction_ajax_call', 'verify');

  if ( isset($_POST['post_id']) ) {
    $user = wp_get_current_user(); // here we get the user ID of the current user
    $post_id = filter_var($_POST['post_id'], FILTER_SANITIZE_NUMBER_INT);
    $post = get_post($post_id);
    // $fav_id = filter_var($_POST['fav_id'], FILTER_SANITIZE_NUMBER_INT);
    // $fav_user = get_userdata($fav_id); // WP_User
    $is_favorite = false;

    if ( $post instanceof WP_Post ) { // post ID is valid
// for user favorites it would be
//  if ( $fav_user instanceof WP_User ) {
      $fav_count = intval(get_post_meta($post->ID, '_favorites', true));
      $favorites = get_user_meta($user->ID, '_favorite_posts', true);
      if ( !filter_var($fav_count, FILTER_VALIDATE_INT) ) {
        $fav_count = 0;
      }
      if ( !is_array($favorites) || empty($favorites) ) {
        $favorites = array();
      }
      $fav_key = array_search($post->ID, $favorites);

      if ( $fav_key !== false ) { // is favorite, remove it
        $fav_count--;
        unset($favorites[$fav_key]);
      } else { // is no favorite, add it
        $fav_count++;
        $favorites[] = $post->ID;
        $is_favorite = true;
      }

      // set favorite counter
      update_post_meta($post->ID, '_favorites', $fav_count);

      // set favorite list
      update_user_meta($user->ID, '_favorite_posts', $favorites);

      // Output
      $json = array(
        'fav_count'  => $fav_count,
        'favorites' => $favorites,
        'error' => false,
        'is_favorite' => $is_favorite,
      );
    } else {
      $json = array('is_favorite' => $is_favorite, 'error' => true, 'message' => 'Invalid Post ID');
    }
  } else {
    $json = array('is_favorite' => $is_favorite, 'error' => true, 'message' => 'No post_id Post ID sent');
  }
  // wp_send_json sets the http header and ends the request
  wp_send_json($json);
}

这是我在途中注意到的事情:

  • 使用wp_create_nonce()验证引荐来源check_ajax_referer()
  • 检查JSON结果数据键是否存在,data.hasOwnProperty('key')以避免可能的JS错误
  • 检查有效WP_UserWP_Post对象
  • 无需通过POST发送当前的用户ID
  • wp_ajax_nopriv_{action} 仅适用于已登录用户的功能时不需要
  • 使用wp_send_json()结束的响应

亲切的汤姆

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

VLSM:任何简单的学习方法

来自分类Dev

机器翻译中有字符串相似度的深度学习方法吗?

来自分类Dev

Java-在文本挖掘中实现机器学习方法

来自分类Dev

文本生成的深度学习方法 (PyTorch)

来自分类Dev

WordPress插件中没有AdminMenu

来自分类Dev

Wordpress 插件没有异常行为

来自分类Dev

在没有任何插件的WordPress中添加滑块

来自分类Dev

if 语句在函数内部没有找到变量(Wordpress 插件)

来自分类Dev

Composer 没有通过 dockerfile 安装 wordpress 插件

来自分类Dev

如何使用适用于变体输入维度的监督式机器学习方法?

来自分类Dev

有没有添加书签/收藏夹表单的方法?

来自分类Dev

编写 Wordpress 插件时没有错误没有执行

来自分类Dev

WordPress管理员端没有插件,但在plugins /文件夹中没有插件

来自分类Dev

有没有在Eclipse中安装插件的首选方法?

来自分类Dev

哪个是最好的 WordPress 测试系统插件,每个测试都有单独的价格

来自分类Dev

修改WordPress插件中的现有类方法/函数

来自分类Dev

带有Infusionsoft付款网关的Wordpress wpmember插件付款方法

来自分类Dev

修改WordPress插件中的现有类方法/函数

来自分类Dev

新的Rebus和插件中没有方法

来自分类Dev

在SSMS 2012中,有没有一种方法可以收藏或加注常用表?

来自分类Dev

没有Websockets的即时消息传递系统的最佳方法

来自分类Dev

如何使用没有插件的WordPress导航菜单创建面包屑?

来自分类Dev

JPA双向OneToMany没有给我想要的收藏

来自分类Dev

没有Wordpress样式

来自分类Dev

具有JS库依赖项的Wordpress插件开发?有资源管理的最佳长期方法?

来自分类Dev

没有文件系统与没有操作系统相同?

来自分类Dev

如何在没有插件的自定义wordpress主题中添加带有图标的搜索框

来自分类Dev

没有系统调用的API

来自分类Dev

系统参考没有显示?

Related 相关文章

  1. 1

    VLSM:任何简单的学习方法

  2. 2

    机器翻译中有字符串相似度的深度学习方法吗?

  3. 3

    Java-在文本挖掘中实现机器学习方法

  4. 4

    文本生成的深度学习方法 (PyTorch)

  5. 5

    WordPress插件中没有AdminMenu

  6. 6

    Wordpress 插件没有异常行为

  7. 7

    在没有任何插件的WordPress中添加滑块

  8. 8

    if 语句在函数内部没有找到变量(Wordpress 插件)

  9. 9

    Composer 没有通过 dockerfile 安装 wordpress 插件

  10. 10

    如何使用适用于变体输入维度的监督式机器学习方法?

  11. 11

    有没有添加书签/收藏夹表单的方法?

  12. 12

    编写 Wordpress 插件时没有错误没有执行

  13. 13

    WordPress管理员端没有插件,但在plugins /文件夹中没有插件

  14. 14

    有没有在Eclipse中安装插件的首选方法?

  15. 15

    哪个是最好的 WordPress 测试系统插件,每个测试都有单独的价格

  16. 16

    修改WordPress插件中的现有类方法/函数

  17. 17

    带有Infusionsoft付款网关的Wordpress wpmember插件付款方法

  18. 18

    修改WordPress插件中的现有类方法/函数

  19. 19

    新的Rebus和插件中没有方法

  20. 20

    在SSMS 2012中,有没有一种方法可以收藏或加注常用表?

  21. 21

    没有Websockets的即时消息传递系统的最佳方法

  22. 22

    如何使用没有插件的WordPress导航菜单创建面包屑?

  23. 23

    JPA双向OneToMany没有给我想要的收藏

  24. 24

    没有Wordpress样式

  25. 25

    具有JS库依赖项的Wordpress插件开发?有资源管理的最佳长期方法?

  26. 26

    没有文件系统与没有操作系统相同?

  27. 27

    如何在没有插件的自定义wordpress主题中添加带有图标的搜索框

  28. 28

    没有系统调用的API

  29. 29

    系统参考没有显示?

热门标签

归档