Получение общего количества шеров в соцсетях (Facebook, Twitter, Google+, Pinterest)

24 мая 2015 г., 21:10:11
Просмотры: 16.3K
Голосов: 2

Я получаю количество шеров для каждой социальной сети отдельно, используя следующий код в файле function.php своей темы:

$facebook_like_share_count = function ( $url ) {

    $api = file_get_contents( 'http://graph.facebook.com/?id=' . $url );

    $count = json_decode( $api );

    return $count->shares;
};

$twitter_tweet_count = function ( $url ) {

    $api = file_get_contents( 'https://cdn.api.twitter.com/1/urls/count.json?url=' . $url );

    $count = json_decode( $api );

    return $count->count;
};

$pinterest_pins = function ( $url ) {

    $api = file_get_contents( 'http://api.pinterest.com/v1/urls/count.json?callback%20&url=' . $url );

    $body = preg_replace( '/^receiveCount\((.*)\)$/', '\\1', $api );

    $count = json_decode( $body );

    return $count->count;

};

$google_plusones = function ( $url ) {
    $curl = curl_init();
    curl_setopt( $curl, CURLOPT_URL, "https://clients6.google.com/rpc" );
    curl_setopt( $curl, CURLOPT_POST, 1 );
    curl_setopt( $curl, CURLOPT_POSTFIELDS, '[{"method":"pos.plusones.get","id":"p","params":{"nolog":true,"id":"' . $url . '","source":"widget","userId":"@viewer","groupId":"@self"},"jsonrpc":"2.0","key":"p","apiVersion":"v1"}]' );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Content-type: application/json' ) );
    $curl_results = curl_exec( $curl );
    curl_close( $curl );
    $json = json_decode( $curl_results, true );

    return intval( $json[0]['result']['metadata']['globalCounts']['count'] );
};

Я вывожу их в single.php с помощью следующего кода:

<?php $url = get_permalink( $post_id ); echo $facebook_like_share_count ("$url");?>
<?php $url = get_permalink( $post_id ); echo $twitter_tweet_count ("$url");?>
<?php $url = get_permalink( $post_id ); echo $pinterest_pins ("$url");?>
<?php $url = get_permalink( $post_id ); echo $google_plusones ("$url");?>

Это работает нормально.

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

РЕДАКТИРОВАТЬ: У меня важный вопрос.

Возможно ли, что приведенный выше код замедляет работу моего блога?

Я уже связывался со своим хостинг-провайдером, и они сказали, что это может быть связано с плагинами или php-файлами. Я не обновлял плагины в последнее время, а P3 Profilier показывает только обычных "виновников". Но я заметил, что сразу после вызова этой функции в single.php мой сервер иногда грузится очень медленно - даже получает таймауты на сайтах проверки скорости. Есть идеи?

РЕДАКТИРОВАТЬ 2: После множества тестов действительно кажется, что именно этот код (при выводе) замедляет страницу. пожимает плечами Наверное, придется перестать его использовать?

Мне пока не удалось заставить это работать. Надеюсь, вы сможете мне помочь. Большое спасибо!

11
Комментарии

$total_count = $facebook_like_share_count + $twitter_tweet_count + $pinterest_pins + $google_plusones;

Nicolai Grossherr Nicolai Grossherr
26 мая 2015 г. 17:02:20

@ialocin Могу я просто скопировать и вставить это в function.php как есть и вывести в single.php? Спасибо. :)

japanworm japanworm
27 мая 2015 г. 00:15:24

Причина, по которой это замедляет вашу страницу, в том, что вы запрашиваете данные с 4 разных сайтов. Все они должны загрузиться, прежде чем ваш скрипт продолжит обработку. Это плохо. Добавьте cron, который будет делать это за вас, или кэшируйте страницу. Не загружайте это при каждой загрузке страницы.

Christine Cooper Christine Cooper
27 мая 2015 г. 02:47:31

@ChristineCooper Что такое cron? Извините, как я уже говорил, я не очень разбираюсь в кодах. Я думал, что страница кэшируется, так как использую плагин W3 Total Cache.

japanworm japanworm
27 мая 2015 г. 03:01:53

Посмотрите в сторону "WP Cron" - он запускается через заданные интервалы. Вы создаете функцию, которая проверяет количество расшариваний, сохраняет их через update_post_meta(), и используете это значение для отображения счетчика локально, вместо запроса внешних файлов при каждой загрузке страницы. Хотя я не уверен, что это правильный подход. Лично я бы сделал все это через jQuery, таким образом все действия происходят на стороне клиента, как и должно быть в таком случае.

Christine Cooper Christine Cooper
27 мая 2015 г. 03:07:03

@ChristineCooper Я видел решения с jQuery. К сожалению, мне пока не удалось заставить ни одно из них работать, поэтому я и спрашивал совета здесь. :)

japanworm japanworm
27 мая 2015 г. 03:10:10

Я предлагаю вам спросить решение на jQuery на stackoverflow, потому что это не специфичный для WordPress вопрос, и я сомневаюсь, что вы получите ответ здесь. Я бы всё же дал ещё один шанс поиску в Google, потому что это очень востребованная функция, и должно быть доступно много кода. =)

Christine Cooper Christine Cooper
27 мая 2015 г. 03:12:23

@ChristineCooper Я искал везде и перепробовал все сниппеты кода, которые смог найти. Ничего не сработало. Спасибо, так и сделаю. :)

japanworm japanworm
27 мая 2015 г. 11:00:07

Я иногда работаю с транзиентами для подсчёта социальных шарингов, то есть значения счётчиков обновляются с определённым интервалом, а не при каждой загрузке страницы. И нет, вы не можете просто скопировать и вставить это в свой single.php, потому что переменная не будет в области видимости.

Nicolai Grossherr Nicolai Grossherr
27 мая 2015 г. 11:48:32

@ialocin Транзиенты! Да! Теперь мне нужно обновить собственный код. OP, смотрите: https://codex.wordpress.org/Transients_API

Christine Cooper Christine Cooper
27 мая 2015 г. 18:38:16

@ialocin Я только что нашел ответ на этот вопрос с использованием транзиентов. Отличная идея.

Christine Cooper Christine Cooper
27 мая 2015 г. 19:18:30
Показать остальные 6 комментариев
Все ответы на вопрос 1
16

Хорошо. @ialocin оставил заметку о Транзиентах. По какой-то странной причине я еще не сталкивался с этим. Раньше я использовал следующие способы отображения счетчиков:

  • jQuery (загрузка на стороне клиента)
  • Кэширование страниц (при локальном хранении счетчиков)
  • Обновление значений счетчиков через Cron
  • И совсем недавно хранил все счетчики в метаданных записи и обновлял метаданные каждые 100 загрузок страницы... довольно дико.

Но нет, есть нечто лучшее. Намного лучше. Транзиенты. Транзиенты. Транзиенты... повторяйте это часами... После медитации и возвращения изучите следующий код, который я адаптировал для вас:

// Проверяем наличие транзиента. Если его нет, выполняем код
if ( false === ( $data = get_transient( 'trans_' . $post_id ) ) ) {

    /* действие */
    $facebook_like_share_count = function ( $url ) {

        $api = file_get_contents( 'http://graph.facebook.com/?id=' . $url );

        $count = json_decode( $api );

        return $count->shares;
    };

    $twitter_tweet_count = function ( $url ) {

        $api = file_get_contents( 'https://cdn.api.twitter.com/1/urls/count.json?url=' . $url );

        $count = json_decode( $api );

        return $count->count;
    };

    $pinterest_pins = function ( $url ) {

        $api = file_get_contents( 'http://api.pinterest.com/v1/urls/count.json?callback%20&url=' . $url );

        $body = preg_replace( '/^receiveCount\((.*)\)$/', '\\1', $api );

        $count = json_decode( $body );

        return $count->count;

    };

    $google_plusones = function ( $url ) {
        $curl = curl_init();
        curl_setopt( $curl, CURLOPT_URL, "https://clients6.google.com/rpc" );
        curl_setopt( $curl, CURLOPT_POST, 1 );
        curl_setopt( $curl, CURLOPT_POSTFIELDS, '[{"method":"pos.plusones.get","id":"p","params":{"nolog":true,"id":"' . $url . '","source":"widget","userId":"@viewer","groupId":"@self"},"jsonrpc":"2.0","key":"p","apiVersion":"v1"}]' );
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Content-type: application/json' ) );
        $curl_results = curl_exec( $curl );
        curl_close( $curl );
        $json = json_decode( $curl_results, true );

        return intval( $json[0]['result']['metadata']['globalCounts']['count'] );
    };

    // сохраняем данные в массив
    $data = array (
        $facebook_like_share_count,
        $twitter_tweet_count,
        $pinterest_pins,
        $google_plusones
    );

    // Сохраняем результаты в транзиент. Срок действия — 6 часов
    set_transient( 'trans_' . $post_id, $data, 6 * HOUR_IN_SECONDS  );
}

if (is_array($data)) {

    $facebook_like_share_count = $data[0];
    $twitter_tweet_count = $data[1];
    $pinterest_pins = $data[2];
    $google_plusones = $data[3];

}

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

Мы временно сохраняем кэшированные данные в базе данных, присваивая им уникальное имя и указывая срок, после которого они будут удалены.

Таким образом, каждые 6 часов массив обновляется. Это очень просто. Смотрите комментарии для уточнения.

РЕДАКТИРОВАНИЕ:

Согласно обсуждениям в комментариях, я изменил код. Во-первых, убедитесь, что у вас есть функции для подсчета шаринга в файле functions.php (я полагаю, что в вашей текущей настройке они уже есть), затем в файле single.php добавьте следующий код там, где вам нужно получить значения счетчиков.

// получаем ID записи
$post_id = get_the_ID();

// получаем постоянную ссылку для функций подсчета шаринга
$url = get_permalink( $post_id );

// Проверяем наличие транзиента. Если его нет, выполняем код
if ( false === ( $data = get_transient( 'trans_' . $post_id ) ) ) {

    /* действие */
    $facebook_like_share_count ("$url");
    $twitter_tweet_count ("$url");
    $pinterest_pins ("$url");
    $google_plusones ("$url");

    // сохраняем данные в массив
    $data = array (
        $facebook_like_share_count,
        $twitter_tweet_count,
        $pinterest_pins,
        $google_plusones
    );

    // Сохраняем результаты в транзиент. Срок действия — 6 часов
    set_transient( 'trans_' . $post_id, $data, 6 * HOUR_IN_SECONDS  );
}

if (is_array($data)) {

    // эти переменные содержат количество шарингов
    $facebook_like_share_count = $data[0];
    $twitter_tweet_count = $data[1];
    $pinterest_pins = $data[2];
    $google_plusones = $data[3];

}

Пожалуйста, ознакомьтесь с комментариями в коде для уточнения.

27 мая 2015 г. 19:18:10
Комментарии

Ты только что заставил меня улыбнуться от того, насколько сильно тебя радуют транзиенты :)

Nicolai Grossherr Nicolai Grossherr
27 мая 2015 г. 23:08:14

Привет. Большое спасибо за твою тяжёлую работу. Я попытался добавить твой код в function.php моей темы, но если я это делаю, моя страница перестаёт загружаться. Полагаю, там синтаксическая ошибка? :(

japanworm japanworm
28 мая 2015 г. 00:27:22

Что? Нет, этот код должен находиться там, откуда он был изначально взят. Полагаю, это single.php

Christine Cooper Christine Cooper
28 мая 2015 г. 00:29:20

@ChristineCooper У меня был код, который я изначально опубликовал в своем вопросе, в файле function.php, а затем вывел его в single.php. Я думал, что должен сделать то же самое с вашим фрагментом кода?! ^^;

japanworm japanworm
28 мая 2015 г. 11:52:38

Пожалуйста, обновите свой вопрос, добавив полный код, который вы используете в файле functions.php, и полный код, которым вы вызываете свои функции в файле single.php или loop-single.php. Таким образом, я смогу увидеть, что происходит, и адаптировать код для вас.

Christine Cooper Christine Cooper
28 мая 2015 г. 17:44:25

@ChristineCooper Спасибо. Я отредактировал свой вопрос. Дайте знать, если вам также нужно увидеть мой полный файл function.php — я загружу его на pastebin.

japanworm japanworm
28 мая 2015 г. 18:51:03

file_get_contents() не будет работать с URL на всех серверах. Вместо этого используйте HTTP API.

fuxia fuxia
30 мая 2015 г. 06:48:14

@toscho Как будет выглядеть этот код?

japanworm japanworm
31 мая 2015 г. 02:59:50

@japanworm Примерно так: $count = json_decode( wp_remote_retrieve_body( wp_safe_remote_get( 'http://graph.facebook.com/?id=' . $url ) ) );

fuxia fuxia
31 мая 2015 г. 03:15:25

Посмотрите мой обновленный код...

Christine Cooper Christine Cooper
1 июн. 2015 г. 18:08:02

@ChristineCooper Я попробовал снова. Кажется, вы не изменили фрагмент кода, который я должен вставить в свой function.php. Должна быть где-то синтаксическая ошибка. Так как я ужасно разбираюсь в коде, я не могу разобраться сам. Может быть, фрагмент кода в function.php не может начинаться с "if"?? Я не знаю.. :(

japanworm japanworm
2 июн. 2015 г. 19:21:51

Я не меняла код в вашем файле functions.php, это должен быть точно такой же код, который вы использовали ранее и который работал, по вашим словам? Так что в вашем файле functions.php не должно быть ошибки, если вы используете тот же самый рабочий код.

Christine Cooper Christine Cooper
2 июн. 2015 г. 19:23:18

@ChristineCooper Если я использую код из моего вопроса, я не получаю эту ошибку. Если я использую код из вашего ответа, то получаю.

japanworm japanworm
2 июн. 2015 г. 23:05:19

Вы размещаете мой код в вашем single.php файле? Также, пожалуйста, вставьте полное сообщение об ошибке в комментарии здесь и укажите часть кода, на которую ссылается сообщение об ошибке.

Christine Cooper Christine Cooper
3 июн. 2015 г. 00:29:21

@ChristineCooper Нет сообщения об ошибке. Мой блог перестает загружаться, как только я вставляю код в function.php, что обычно указывает на синтаксическую ошибку.

japanworm japanworm
3 июн. 2015 г. 01:12:22

@ChristineCooper Значит, если код по какой-то причине не работает в моем function.php, я должна просто сдаться? Спасибо. :)

japanworm japanworm
6 июн. 2015 г. 15:09:41
Показать остальные 11 комментариев