Distributor: Распространение постов с правильным автором

Созданный на 23 февр. 2018  ·  9Комментарии  ·  Источник: 10up/distributor

У нас довольно большая сеть сайтов. Все они должны показывать правильную информацию об авторе. Я вижу, что прямо сейчас распространитель установит автора распределенных сообщений на идентификатор аутентифицированного пользователя. Я хотел бы изменить это (и готов сделать работу сам). Вот два возможных решения:

  1. Самый простой способ — просто передать идентификатор пользователя исходного автора сообщения и предоставить администраторам возможность убедиться, что их идентификаторы пользователей синхронизированы на всех сайтах. Это становится немного проще, если вы используете какой-либо плагин SSO.
  2. Добавьте хук для создания сообщения (или используйте существующий dt_item_mapping для вытягивания или dt_push_post_args для push-фильтра), чтобы разрешить передачу «правильного» идентификатора автора на основе существующего идентификатора автора сообщения и того, какой сайт мы публикуем в. Для этого конечные пользователи должны иметь сопоставление или базу данных идентификатора текущего автора сайта с идентификатором автора внешнего сайта. Не самая сложная вещь в мире для большинства администраторов, но все же довольно высокая планка. Если люди думают, что это лучший маршрут, я, скорее всего, напишу свое собственное решение и задокументирую его в README.md . В конце концов, можно было бы создать пользовательский интерфейс в Distributor для управления этим.

В любом случае, ищу отзывы о том, по какому пути идти или по другому пути. Я хочу сделать это как можно скорее и, конечно же, отправлю любые изменения в плагин обратно.

Enterprise support enhancement

Все 9 Комментарий

Мы написали собственное приложение для синдикации и использовали адрес электронной почты автора для запроса идентификатора на принимающем сайте. Это предполагает, что авторы используют один и тот же адрес электронной почты на всех сайтах в сети.

Спасибо за совет @dleeward , я только что закончил собирать код, который может жить в вашей теме functions.php для синхронизации авторов во время отправки. Он попытается найти автора по переданному адресу электронной почты. Если существующего пользователя найти не удается, создается пользователь со свойствами из толкающего WP. Это еще не было хорошо протестировано и пока не должно использоваться в производстве.

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);

}

@ robbiet480 Вы не должны предполагать, что user_login и user_nicename исходного автора еще не используются. Мы создаем произвольное имя пользователя текущего времени unix с префиксом короткой текстовой строки, такой как ABC1519562843. Это предполагает, что вы не создаете более одного пользователя в секунду. Вместо этого вы можете использовать микротайм или добавить случайный суффикс.

Мы много обсуждали это.

Как правило, мы считаем, что размещение сообщений от имени аутентифицированного пользователя является наиболее безопасным и совместимым решением для всех. Мы определенно видим, что у разных издателей могут быть разные требования. Создание нового пользователя на удаленном сайте вызывает массу сложных вопросов. Какова роль новых пользователей? Должна ли эта учетная запись быть доступна первоначальному автору?

Конечно, это открыто для обсуждения, и мы хотели бы услышать другие мнения, но пока лучшее, что мы можем сделать, это добавить дополнительные крючки/фильтры, чтобы сделать то, что сделал @robbiet480, проще.

Следует отметить, что многие публикации нуждаются в поддержке нескольких авторов для контента, и в этих случаях «Пользователи» часто даже не используются для отношений автор <-> контент.

Когда я работал над синдикацией контента в DFM, мы использовали Co-Authors Plus, гибридное решение типа поста/таксономии для добавления множества авторов к посту, поэтому в нашем случае мы фактически _хотели_, чтобы аутентифицированный пользователь был подключен к сообщению как автор синдицированного контента, поэтому у нас был след того, какой пользователь инициировал синдикацию, и мы синдицировали дополнительные данные для обработки отношений авторы<->контент (что-то похожее на то, как обрабатываются отношения с медиа)

Спасибо за обратную связь, Джейсон!

Итак, я сделал еще один шаг вперед и фактически добавил поддержку Co-Authors Plus для Distributor через хуки. Вот мой код для всех, кто заинтересован в интеграции. Я спросил в № 131 о включении в 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);

Re: первоначальный вопрос о распространении с авторами, я бы сказал, что CAP может быть хорошим временным решением, позволяющим распространителю убедиться, что указан правильный автор, не беспокоясь о вещах, которые упомянул @tlovett1 , например, какая роль должна быть новой. у пользователей есть и такое. Кроме того, я думаю, что было бы разумно добавить больше тегов шаблона, чтобы отображать информацию, такую ​​​​как оригинальный автор, во внешнем интерфейсе, точно так же, как мы теперь можем отображать оригинальное имя сайта.

Я хотел бы заблокировать этот вопрос решением, которое будет принято в № 131. Если окажется, что это решение будет заключаться в том, что Distributor будет поддерживать внешние плагины больше, чем через хуки/фильтры, тогда мы можем продолжить изучение этой конкретной проблемы с помощью Co-Authors Plus и выяснить, как его лучше всего изящно включить вместе с Distributor. Если Distributor примет подход, основанный только на ловушках/фильтрах, то, скорее всего, мы закроем эту проблему (и, надеюсь, дадим ссылку на репозиторий с примерами для кода расширения Co-Authors Plus).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги