Giter Club home page Giter Club logo

Comments (9)

dleeward avatar dleeward commented on May 14, 2024 1

We wrote our own syndication application and used the author's email address to query the receiving site for the ID. This assumes authors use the same email address on all sites in the network.

from distributor.

dleeward avatar dleeward commented on May 14, 2024 1

@robbiet480 You shouldn't assume that the original author's user_login and user_nicename aren't already being used. We create an arbitrary username of the current unix time prefixed with a short text string such as ABC1519562843. This does assume you aren't creating more than one user per second. You could use microtime or add a random suffix instead .

from distributor.

jasonbahl avatar jasonbahl commented on May 14, 2024 1

One thing to note, is that many publications have the need to support multiple authors for content, and in those cases, "Users" are often not even used for the author <-> content relationship.

When I was working on syndicating content at DFM, we used Co-Authors Plus which was a hybrid post-type/taxonomy solution for adding many authors to posts, so in our case we actually wanted the authenticated user to be connected to the post as the author of the syndicated content, so we had a trail of what user triggered the syndication, and we syndicated additional data to handle the authors<->content relationship (somewhat similar to how relationships to media is handled)

from distributor.

robbiet480 avatar robbiet480 commented on May 14, 2024 1

So i've taken this a step further now and actually added support for Co-Authors Plus to Distributor via hooks. Here's my code for anyone else interested in the integration. I've inquired in #131 about inclusion in Distributor.

<?php

function handle_dt_process_distributor_attributes( $post, $request, $update ) {
  if ( empty( $post ) || is_wp_error( $post ) ) {
    return;
  }

  if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) && ! empty( $request['distributor_coauthors'] ) ) {
    global $coauthors_plus;

    $author_logins = array();

    foreach ( $request['distributor_coauthors'] as $coauthor ) {

      $existing_guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'user_login', $coauthor['user_login'] );

      if ( ! $existing_guest_author ) {
        $guest_author_id = $coauthors_plus->guest_authors->create( array(
          'display_name' => $coauthor['display_name'],
          'first_name' => $coauthor['first_name'],
          'last_name' => $coauthor['last_name'],
          'user_login' => $coauthor['user_login'],
          'user_nicename' => $coauthor['user_nicename']
        ) );

        if ( is_wp_error( $guest_author_id ) ) {
          error_log("Error creating co-author during Distributor push ".$guest_author_id->get_error_message());
          return;
        }

        if ( !$guest_author_id ) {
          error_log( '-- Failed to create guest author.' );
        }

        if ( ! empty($coauthor['avatar_url']) ) {
          require_once(ABSPATH . 'wp-admin/includes/media.php');
          require_once(ABSPATH . 'wp-admin/includes/file.php');
          require_once(ABSPATH . 'wp-admin/includes/image.php');

          $thumbnail_id = media_sideload_image($coauthor['avatar_url'], $guest_author_id, null, 'id');
          set_post_thumbnail($guest_author_id, $thumbnail_id);
        }

        $guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'ID', $guest_author_id );
        array_push($author_logins, $guest_author->user_login);
      } else {
        array_push($author_logins, $existing_guest_author->user_login);
      }
    }
    clean_post_cache($post->ID);
    $coauthors_plus->guest_authors->delete_guest_author_cache($author_logins[0]);
  }
}

add_action( 'dt_process_distributor_attributes', 'handle_dt_process_distributor_attributes', 10, 3 );

if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) ) {
  function distributor_coauthors_get_avatar_url( $coauthor ) {
    global $coauthors_plus;
    if ( ! is_object( $coauthor ) ) {
      return '';
    }

    if ( isset( $coauthor->type ) && 'guest-author' == $coauthor->type ) {
      if ( ! has_post_thumbnail( $coauthor->ID ) ) {
        return '';
      }

      $large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $coauthor->ID ), 'large' );

      return $large_image_url[0];
    }

    // Make sure we're dealing with an object for which we can retrieve an email
    if ( isset( $coauthor->user_email ) ) {
      return get_avatar( $coauthor->user_email, $size, $default, $alt );
    }

    // Nothing matched, an invalid object was passed.
    return '';
  }
}

function add_dt_push_post_args($post_body, $post, $that) {
  if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) ) {
    $post_body['distributor_coauthors'] = array();

    foreach ( $coauthors as $coauthor ) {
      if( array_key_exists("data", $coauthor) ) {
        // Don't include real WP_Users
        continue;
      }
      $coauthor_arr = (array) $coauthor;
      $coauthor_arr['avatar_url'] = distributor_coauthors_get_avatar_url($coauthor);
      array_push($post_body['distributor_coauthors'], $coauthor_arr);
    }
  }

  return $post_body;
}

add_filter('dt_push_post_args', 'add_dt_push_post_args', 1, 3);

add_filter('dt_push_post_timeout', function($default_timeout, $post) {
  return 30;
}, 1, 2);

from distributor.

robbiet480 avatar robbiet480 commented on May 14, 2024

Thanks for the tip @dleeward, I just finished hacking together some code that can live in your theme functions.php to sync authors during a push. It will attempt to find the author by the passed email address. If an existing user can not be found, a user is created with the properties from the pushing WP. This hasn't been well tested yet and should not yet be used in production.

if ( defined( 'DT_VERSION' ) ) {
  function setup_distributor_replacements() {
    $post_types = get_post_types(array('show_in_rest' => true));
    foreach ( $post_types as $post_type ) {
      add_action( "rest_insert_{$post_type}", 'process_original_author', 10, 3 );
    }
  }

  function process_original_author( $post, $request, $update ) {
    if ( empty( $post ) || is_wp_error( $post ) ) {
      return;
    }
    if ( ! empty( $request['distributor_original_author'] ) ) {
      $author_obj = $request['distributor_original_author'];
      $new_author = get_user_by( 'email', $author_obj['email'] );
      $author_id = 0;
      if ( ! empty( $new_author ) && ! is_wp_error( $new_author ) ) {
        $author_id = $new_author->ID;
      } else {
        $create_user = wp_insert_user(array(
          'display_name'      => $author_obj['display_name'],
          'first_name'        => $author_obj['first_name'],
          'last_name'         => $author_obj['last_name'],
          'nickname'          => $author_obj['nickname'],
          'user_displayname'  => $author_obj['user_displayname'],
          'user_email'        => $author_obj['user_email'],
          'user_login'        => $author_obj['user_login'],
          'user_nicename'     => $author_obj['user_nicename'],
          'user_pass'         => NULL
        ));
        if ( is_wp_error( $create_user ) ) {
          error_log("Error creating user during Distributor push ".$create_user->get_error_message());
          return;
        }
        $author_id = $create_user;
      }
      wp_update_post( array( 'ID' => $post->ID, 'post_author' => $author_id ) );
    }
  }

  add_action('init', 'setup_distributor_replacements');

  function add_original_author($post_body, $post, $that) {
    $post_author = get_user_by( 'id', $post->post_author );
    $author_obj = array(
      'display_name'  => $post_author->display_name,
      'first_name'    => get_user_meta($post->post_author, 'first_name', true),
      'first_name'    => get_user_meta($post->post_author, 'first_name', true),
      'last_name'     => get_user_meta($post->post_author, 'last_name', true),
      'user_email'    => $post_author->user_email,
      'user_login'    => $post_author->user_login,
      'user_nicename' => $post_author->user_nicename,
    );
    $post_body['distributor_original_author'] = $author_obj;
    return $post_body;
  }

  add_filter('dt_push_post_args', 'add_original_author', 1, 3);

}

from distributor.

tlovett1 avatar tlovett1 commented on May 14, 2024

We'd discussed this one a lot.

Generally, we believe posting as the authenticated user is the safest most compatible solution for everyone. We definitely see different publishers may have different requirements. Creating a new user on the remote site opens up a ton of hard questions. What is the new users role? Should that account be accessible by the original author?

Of course this is open for discussion, and we'd love to hear other opinions, but for now the best we can do is to add additional hooks/filters to make what @robbiet480 accomplished easier.

from distributor.

tlovett1 avatar tlovett1 commented on May 14, 2024

Appreciate the feedback, Jason!

from distributor.

robbiet480 avatar robbiet480 commented on May 14, 2024

Re: the original query about distributing with authors, I'd say that CAP could be a good stop gap solution to allow for Distributor to ensure the proper author is credited while not having to worry about things that @tlovett1 mentioned like what role should new users have and such. Furthermore, I think it would make a lot of sense to add more template tags to expose information like original author to the frontend just like how we are now able to expose original site name.

from distributor.

jeffpaul avatar jeffpaul commented on May 14, 2024

I'd like to block this issue by the decision-to-be-made in #131. If that decision turns out to be that Distributor will support external plugins more than via hooks/filters, then we can continue investigating this specific issue with Co-Authors Plus and how it can best be gracefully included with/alongside Distributor. If Distributor takes the hooks/filters-only approach, then its likely we'll close this issue (and hopefully link out to an example repo for the Co-Authors Plus extension code).

from distributor.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.