Только для читателей Lifeexample возможно открыть интернет-магазин на Moguta.CMS со скидкой в 15%

<<< Пишем плагин WordPress || Пишем интернет магазин на php | php скрипт интернет магазина >>>

Счетчик скачиваний для WordPress

01.12.2011
Счетчик скачиваний для WordPress

Здравствуй уважаемый читатель блога LifeExample, опубликовав предыдущую статью о создании плагина для WordPress своими руками, и разместив в статье ссылку на скачивание итогового результата, у меня возникло желание выводить рядом со ссылкой счетчик количества скачиваний файла. Погуляв по интернету, нашел много плагинов для решения этой задачи, но все они были слишком навороченными для простого вывода счетчика. В итоге решил самостоятельно написать плагин для WordPress, который бы удовлетворял моей простой прихоти: вывода количества скачиваний файла рядом со ссылкой.

Сегодня я решил поделиться плагином выводящим счетчик скачивания для WordPress, рядом со ссылкой на файл:

Скачать плагин можете по этой

ссылке ( Скачали: 1615 чел. ) 

А также в качестве дополнения к предыдущей статье (Пишем плагин WordPress) хочу продемонстрировать процесс написания данного плагина, и поделиться полученным опытом с тобой уважаемый читатель.

Для того, чтобы было понято, что мы будем делать, давайте определимся с тем, что должно получиться:

Допустим, у нас есть ссылка вида:

1
<a href="/upload/count_download.zip" title="Счетчик скачиваний">Cчетчик скачиваний для WordPress своими руками </a>

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

1
<noindex><a rel='nofollow' href='/download_count.php?url=upload/catalog.zip' title='Счетчик скачиваний'>Счетчик скачиваний для WordPress своими руками</a></noindex> <strong>(Файл скачали: 5 человек)</strong>

Cуть работы плагина:

Исходную ссылку мы оформляем в соответствии с требованием плагина т.е. если у нас было:

1
<a href="/upload/countdownload.zip" title="Счетчик скачиваний">Cчетчик скачиваний для WordPress своими руками</a>

то с помощью панели администратора, в форме редактирования страниц, вводим шорткод следующего вида:

1
2
3
[download_file url="upload/countdownload.zip" title="Счетчик скачиваний"]
счетчик скачиваний для WordPress своими руками
[/download_file]

Плагин обрабатывает данный шорткод и заменяет его более понятной формой для браузеров, дописывая количество скачавших человек рядом с ссылкой.

С принципом работы плагина вроде все понятно, кроме того как ведется подсчет скачиваний. Сейчас я и об этом расскажу.

При нажатии на преобразованную ссылку, как видите мы попадаем на скрипт /download_count.php, который отдает пользователю запрашиваемый файл, предварительно обновляя счетчик скачиваний в базе данных соответствующий этому файлу.

Все ясно? Правильно не все! Что за скрипт такой download_count.php и откуда он в корневой дирректории сайта?

Все дело в том, что скрипт счетчика скачиваний, не должен находиться в папке с файлами плагина, т.к. тогда и в ссылке придется указывать весь путь до него, а это не есть гуд. Поэтому, плагин принудительно создает этот скрипт в корневой директории, каждый раз когда при обработке шорткода не обнаруживает наличие download_count.php.

Заметьте, что если download_count.php был создан один раз, и не удалялся до следующего обращения к нему, то плагин не будет его создавать каждый раз.

С теорией разобрались, перейдем к написанию кода:

При активации плагина счетчика в админке WordPress, сразу создаем таблицу в базе в которую будем сохранять данные.

1
2
3
4
5
6
7
8
function install_download_file() { //при активации плагина создаем необходимую таблицу
    global $wpdb;
        $wpdb->query('CREATE TABLE IF NOT EXISTS `download_file` (
          `url` varchar(254) NOT NULL,
          `count` int(9) NOT NULL
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8;'
);
}
register_activation_hook(__FILE__,'install_download_file');

Далее пишем функцию, которая будет заменять шорткод на нужную ссылку

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function count_download_file ($atts, $content = null) //Выводим счетчик скачиваний, рядом с ссылкой
{
// считываем данные из таблицы плагина о количестве скачиваний  данного файла
global $wpdb;
        $result = $wpdb->get_results("SELECT * FROM  `download_file` WHERE  `url` LIKE  '".$atts["url"]."'", ARRAY_A);
       
        if(!isset($atts["title"]))$atts["title"]=$content;
       
        if($result[0]['url']) //если в таблицы существует информация о количестве нажатий, то выводим ее
                return "<p><noindex> <a rel='nofollow' title='".$atts["title"]."' href='/download_count.php?url=".$atts["url"]."'>".$content."</a></noindex> <span style='font-style: italic; font-size:7pt;'>( Скачали: ".$result[0]['count']." чел. )</span>&nbsp;</p>";
        else{ // если ссылка только появилась, то заносим ее в базу, и присваиваем количество нажатий = 0
            $wpdb->query("INSERT INTO download_file VALUES ('".$atts["url"]."', '0')");
            return "<p><noindex> <a rel='nofollow' title='".$atts["title"]."' href='/download_count.php?url=".$atts["url"]."'>".$content."</a></noindex> <span style='font-style: italic; font-size:7pt;'>( Скачали: 0 чел. )</span>&nbsp;</p>";     
            }
}

И вешаем ее в качестве обрабатывающей функции на шорткод download_file.

1
add_shortcode('download_file', 'count_download_file');

Вот и написали плагин счетчика скачиваний для WordPress

Стоп, а где в коде происходит генерация файла download_count.php? Чуть не забыл важный момент.

Добавим следующий код в начало функции function count_download_file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (!file_exists("download_count.php")){
        $text='<?
        if($_SERVER["HTTP_REFERER"]){
            define("DB_NAME", "'.DB_NAME.'");
            define("DB_USER", "'.DB_USER.'");
            define("DB_PASSWORD", "'.DB_PASSWORD.'");
            define("DB_HOST", "'.DB_HOST.'");
            $connect = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
            mysql_select_db(DB_NAME, $connect);
            if(mysql_query("UPDATE download_file SET count=(count + 1) WHERE url=\'{$_GET["url"]}\'")){    
                    header("Content-Length: " . filesize($_GET["url"]));           
                    header("Content-type: application/octed-stream");
                    header("Content-Disposition: attachment; filename=".basename($_GET["url"]));
                    readfile($_GET["url"]);
               }
            else echo "К сожалению файл удален. Вернуться <a href=".$_SERVER["HTTP_REFERER"].">назад</a>.";
        }
        else echo "Пожалуйста не открывайте этот фаил напрямую, у него другие функции.";
   
        ?>';
            $fp = fopen ("download_count.php", "w");
            fwrite($fp,$text);
            fclose($fp);   
        }

После активации плагина, и обновлении в браузере страницы с шорткодом, в корне сайта появится скрипт download_count.php.

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

В общем и целом получился легковесный плагин: Cчетчик скачиваний для WordPress, для использования которого нужно лишь активировать его, и правильно составить шорткод. Инструкция по составлению шорткода находится прям в описании плагина.

Скачать плагин можете по этой

ссылке ( Скачали: 1615 чел. ) 

Спасибо за внимание, пишите комменты.

Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.

Нравится

Комментарии

  • Большое спасибо!!! Именно то, что было нужно!

  • leito25

    Спасибо за труды, то что надо, с одним но, это даже не но, а пожелание. Если использовать к фото, хотелось бы возможность видеть размер это фото!

  • Дмитрий

    Вот этот код:

    1
    2
    3
    4
    5
    6
    7
    if($_SERVER["HTTP_REFERER"]){
                define("DB_NAME", "'.DB_NAME.'");
                define("DB_USER", "'.DB_USER.'");
                define("DB_PASSWORD", "'.DB_PASSWORD.'");
                define("DB_HOST", "'.DB_HOST.'");
                $connect = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
                mysql_select_db(DB_NAME, $connect);

    Не может привести к тому, что пароль от БД может быть раскрыт и попасть в сеть!?

    • Mark

      Он не очень рационален, но за безопасность можете не бояться. Это всего лишь дерективы. Даже если бы он был в таком виде:

      1
      2
      3
      4
      5
      6
      7
      if($_SERVER["HTTP_REFERER"]){
                  define("DB_NAME", "myBse");
                  define("DB_USER", "youlogin");
                  define("DB_PASSWORD", "123456");
                  define("DB_HOST", "192.168.0.1");
                  $connect = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
                  mysql_select_db(DB_NAME, $connect);

      Он бы все равно не представлял опасности.Для наглядности можете ассоциировать данный скрипт с config.php в wordpress, там ведь хранятся все пароли.

  • Дмитрий

    Большое спасибо за Ваш труд! Это именно то, что я искал!

    А Вы бы могли доработать Ваш плагин таким образом, что бы ввести тег title? Ведь для индексации сайта это очень важный тег, в ссылке.

    Сейчас работает так: [download_file url=Моя ссылка]Описание моей ссылки[/download_file]

    А хотелось бы так: [download_file url=Моя ссылка title=Описание моей ссылки]Описание моей ссылки[/download_file]

  • Дмитрий

    и еще, слишком большие файлы, более 200 Мб, не могут быть обработаны данным плагином. Проверял на нескольких расширениях (zip, iso, rar) Либо ошибка, либо просто не скачивается.

  • Mark

    По поводу ограничения в 200 Мб — интересное наблюдение, надо разбираться с мат частью. Наверное это связанно с работой протокола HTTP, либо с настройками хостинг-сервера. Доработать скрипт можно, пишите на e-mail обсудим.

  • Вадим

    Здравствуйте, поставил Ваш плагин, прописал шорт-код:

    1
    [download_file url=download/MenuButton.crx]Установить расширение с этого сайта[/download_file]

    Но вот незадача: 1. Перестал автоматически запускаться файл установки (такое ощущение, что Chrome не распознает его как crx-файл). 2. Файл сохраняется под именем download_MenuButton.crx
    Проясните, пожалуйста, что не так делаю?

    • Плагин работает правильно, т.е. сохраняет ваш файл при нажатии на ссылку.
      Это происходит из-за передаваемого заголовка

      1
      Content-Disposition: attachment;

      Если вам не нужно чтобы файл сохранялся, а автоматически запускался, попробуйте поэксперементироваться с заголовком, либо уберите его полностью
      Content-Disposition
      Либо, возможно это решит проблему:

      1
      Content-Disposition: inline
  • Вадим

    Большое спасибо, за быстрый ответ. Пробую варианты, что-то пока никак… 🙁 А по поводу второго вопроса: так и задумано изменять имя?

  • Если честно, то я уже не помню, как это было задумано :-), но я пользуюсь этим плагином в таком виде в котором он есть. Да действительно к файлам добавляется лишняя информация, но мне она сильно не мешает. 🙂
    Для индивидуальных целей, его нужно хорошо подточить напильником.

  • Вадим

    Как мне не лениво было разбираться в php, но пришлось…
    Проблема с названием решилась очень просто — достаточно применить функцию basename

    1
    header("Content-Disposition: inline; filename=".basename($_GET["url"]));

    А вот заставить браузер сам распознавать тип файла у меня не получилось. 🙁
    Пришлось довольствоваться прямым указанием типа:

    1
    header("Content-type: application/x-chrome-extension");

    Коряво, но ничего пока лучше не придумал… Может быть все дело в X-Content-Type-Options: no sniff ? Как ее отключить?

  • Вадим

    После некоторого времени мытарств, пришел к выводу, что заставить браузер сам разбираться с расширениями файлов я не могу, поэтому решил обработать расширение .CRX как отдельный случай. Вот что в конечном итоге получилось:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if(mysql_query("UPDATE download_file SET count=(count + 1) WHERE url=\'{$_GET["url"]}\'")){
        $file_extension = strtolower(end(explode(".", $_GET["url"])));
        if ($file_extension=="crx") {
            header("Content-type: application/x-chrome-extension");
            header("Content-Disposition: inline; filename=".basename($_GET["url"]));
        }
        else {
            header("Content-type: application/octed-stream");
            header("Content-Disposition: attachment; filename=".basename($_GET["url"]));
        }
        readfile($_GET["url"]);
        exit;
    }

    — файлы с расширением .CRX выполняются браузером, все остальные загружаются, причем под своим родным именем.
    Марк, большое спасибо за легковесный плагин. Обожаю минимализм!
    Офтоп: почитал Ваш блог — довольно интересно пишите, буде заглядывать. 🙂

    • Вадим, вы молодец. Все бы были такими энтузиастами 😉

  • Вадим

    Спасибо за комплимент. Охота — пуще неволи. А вот basename($_GET[«url»]) в описании заголовка я бы Вам рекомендовал поправить в исходнике. Представьте, как в Вашем случае будет выглядеть имя файла, если его упрятать куда-нибудь глубоко в папки:
    download/folder1/folder12/folder125/folder1253/myfile.ext 🙂

    • Хорошо, постараюсь не забыть подправить. Пока некогда.

  • Дмитрий

    Mark Здравствуйте!

    Использую Ваш плагин и он мне очень нравится. Но есть одно существенное но!

    При скачивании больших файлов, файл не удается открыть у себя на компе :(((

    http://handbookhmm.ru/library

    Скачайте ~ 43 МБт Легкая версия справочника 4.0,
    или
    ~ 37 МБт Журнал «Магазин игрушек» за 1996 г.
    Если скачивать напрямую, то файлы открываются и ОТКРЫВАЮТСЯ на ура!

    Очень прошу помочь откорректировать плагин в этой части.
    Не хотелось бы от него отказываться.

  • Дмитрий

    Пока вывесил на своем сайте объявление:

    ***
    Внимание — файлы размером более 20 МБт, качаются битыми. Поэтому просьба их не качать. Ведутся работы! Приносим Вам извинения за временные неудобства.
    ***

    Конкретный пример:

    1
    ~ 43 МБт [download_file url=http://handbookhmm.ru/download/Handbookhmm1_v4.0_lite.chm]Легкая версия справочника 4.0[/download_file]

    — качается, но файл битый.

    1
    ~ 43 МБт [download_file url=download/Handbookhmm1_v4.0_lite.chm]Легкая версия справочника 4.0[/download_file]

    — качается, но файл битый.

    1
    ~ 43 МБт <a href="url=download/Handbookhmm1_v4.0_lite.chm" rel="nofollow">Легкая версия справочника 4.0</a>

    — качается, файл открывается.
    Тоже самое и с другими, большими файлами.

    Очень надеюсь на Вашу помощь, Mark

    • Дима, я протестировал плагин, с разными размерами файлов. У меня не получилось воспроизвести вашу проблему. Тестировал скачивание архивов размерами 15МБ , 20МБ, 130МБ, и 206МБ. Все успешно скачивалось и открывалось.
      Может действительно на вашем хостинге такая проблема? Вы пробовали на локальном хосте потестить?

      Тем не менее я внес некоторые изменения, как в код счетчика скачиваний так и в статью.

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

      *Изменения*

      В новой версии, исправлен баг с длинными именами скачиваемых файлов, а также добавлен атрибут title. Теперь можно использовать шорт код вида:

      1
      [download_file url="test.zip" title="Тестовый архив"]

      Допускается отсутствие атрибута title, в этом случае в title ссылки будет вставлен текст анкора.

  • Дмитрий

    Mark, прошу скачать следующий файл (Handbookhmm1_v4.0_lite.chm) расположенный здесь:
    _http://handbookhmm.ru/library

    Легкая offline версия справочника 4.0 (на прямую с сайта) и
    Не качать! Проверка! (с установленным плагином).

    Не думаю, что виноват хостинг. Я ставил другой плагин Kama’s Click Counter и с него большие файлы качались и открывались нормально. Но у него, тоже оказались проблемы (другого плана) и я его снес. :(((

    Ваш плагин мне нравится больше, но скачиваемые файлы не удается открыть (проверено не только мной. Пошли жалобы со стороны пользователей)

  • Дмитрий, сейчас на вашем ресурсе действует обновленная версия плагина? или старая? И еще вопрос относительно расширений, вы не пробовали те же справочники запаковывать в zip? и отдавать в виде архива? Понимаю, что это не решение , просто хочу понять все нюансы проблемы.

  • Дмитрий

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

    Плагин полностью переустановил в соответствии с Вашими рекомендациями, теперь плагин на моем сайте обновленный.

    Я более подробно попытался объяснить суть проблемы, на примерах:

    С уважением, Дмитрий

  • Виктор

    Подскажите,такая проблема, не знаете ли,почему у меня файлы скачиваются, но весят все они 0 байт? Файлы не большие zip.

    • Неа, не знаю 🙂

      Однажды столкнулся тоже с таким багом, но потом исправил его, как уже не помню…

  • Илья

    Здравствуйте
    Агава чтото ругается, пишет такую фигню:

    Ошибка исполнения CGI приложения
    CGI приложение доступно на запись другим пользователям. Для выполнения оно должно иметь права 0755 или 0711.

    English description
    File is writable by others. CGI must has a permission mask to 0755

    • Илья

      Ссори, вопрос не к Вам, а к хостеру

  • Beriya

    Здравствуйте. У меня такая же проблемма, как и у Виктора… файлы весят 0 байт.

    • Здравствуйте, я пользуюсь данной версией этого плагина и такой проблемы не возникает. Возможно у вас плагин конфликтует с настройками хостинга или с другими плагинами. Попробуйте потестировать на локальном хостинге, отключив другие плагины. К сожалению, другим советом не помогу.

  • Beriya

    Понятно… буду дальше плясать вокруг компа… Если что-то получится, то сообщу.

  • Beriya

    Проблема решена. Всё дело в моей криворукости. Нужно было правильно указывать путь к файлу.
    Пример:
    НЕ ПРАВИЛЬНО — url=»06/имя файла.zip»
    url=»/06/имя файла.zip»
    ПРАВИЛЬНО — url=»wp-content/uploads/2012/06/имя файла.zip»
    Плагин хорош. Буду пользовать. )) Спасибо!

  • Нашел решение к проблемам передачи больших объемов файлов.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    function file_force_download($file) {
      if (file_exists($file)) {
        // сбрасываем буфер вывода PHP, чтобы избежать переполнения памяти выделенной под скрипт
        // если этого не сделать файл будет читаться в память полностью!
        if (ob_get_level()) {
          ob_end_clean();
        }
        // заставляем браузер показать окно сохранения файла
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename=' . basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        // читаем файл и отправляем его пользователю
        if ($fd = fopen($file, 'rb')) {
          while (!feof($fd)) {
            print fread($fd, 1024);
          }
          fclose($fd);
        }
        exit;
      }
    }
  • А вобще, вот тут очень полезные для данной проблемы вещи описаны _http://habrahabr.ru/post/151795/#habracut

  • VDV_forever

    Mark приветствую!

    А будет ли обновлен плагин с учетом решения проблемы передачи больших объемов файлов? 🙂

    P.S. Хотелось бы вновь его потестировать и в случае успеха, внедрить на сайте.

    • К сожалению я не планировал обновлять данный плагин, поскольку для моих надобностей его вполне хватает. Предлагаю заняться этим энтузиастам. И в случае успешного исправления бага, прошу рассказать как его исправить.
      Сам я на сегодняшний день, не знаю в чем причина, проблем с передачей большого объема данных. А вобще насколько я помню при тестировании у меня успешно передавалось от 50 до 200 мб.

  • Geleosan

    Здравствуйте! А не подскажете, можно ли ваш плагин использовать просто как счетчик нажатий на ссылку? То есть чтобы по ссылке не скачка файла происходила, а просто страница еще одна открывалась в соседней вкладке браузера?
    При этом чтобы ссылку оформить как кнопку…Но последнее можно и с помощью css сделать.

    • Если переписать немного, то можно.

  • Анастасия

    Здравствуйте!
    У меня вопрос. Как сделать так, чтобы при нажатии на ссылку сразу выпадало окно скачивания файла, как у вас в данной статье с ссылкой на скачивание плагина. Заранее спасибо!

  • Катерина

    Здравствуйте! Подскажите, пожалуйста, что я сделала не так? Установила Ваш плагин, но подсчет голосов не отображается((( Вот ссылка на мою страничку в блоге. _http://wordru.ru/volshebnoe-slovo-zato/

  • Riminy

    А можно сделать, чтобы автоматом добавлялся счетчик, а то на сайте больше 1000 файлов, к каждому трудно добавлять и нуторно кадждый раз.

  • Alex

    При скачке файлов (.rar, 190 и около того мб) браузер не понимает его размер, моргает всякими цифрами и в итоге прекращает загрузку в разных местах. Файлы остаются недокачанными! Неужели нет готового простого бесплатного и рабочего метода реализации простого счётчика скачиваний файлов? (для WP, если что).

  • Egor

    Не думал, что напишу в этой теме, но после 4х часов бесплодных попыток близок к тому, что бы сдаться 🙂
    Немного предыстории: работая администратором в компании, которая делает сайты «под ключ» решил поднять свой блог, и как логическое продолжение этого увлечения, решил написать свой первый плагин. Так как задача со счетчиком вполне осязаемая и практическая, решил потренироваться на ней.
    Собственно проблема: при попытке скачать файл получаем:
    _http://joxi.ru/5mdWDbJsaJ33r1
    Траблшутинг:
    — по прямому линку файл скачивается (URL вида: _http://sitename.ru/wp-content/uploads/2015/03/test.doc)
    — файл download_count.php в корне файла создается, с корректными параметрами подключения к базе
    — в базе создается табличка download_file
    — шорткод пробовал и с абсолютными URL (_http://sitename.ru/wp-content/uploads/2015/03/test.doc) и с относительными (wp-content/uploads/2015/03/test.doc)
    — сначала имя файла было кирилицей, думал из-за этого, поменял на латиницу

    Сейчас шорткод имеет вид:
    [download_file url="wp-content/uploads/2015/03/test.doc" title="Тестовый архив"]Тест[/download_file]

    Было подозрение, что что-то поменялось в синтаксисе между 3й и 4й версиями wp, но отбросил этот вариант, когда понял, что на Вашем сайте всё работает.
    P.S. Хотя попытавшись скопировать ссылку и вставив в браузер получил:
    _http://joxi.ru/Q2KxwKNUygLvAj
    тем не менее по клику в посте файл скачивается.

  • Владимир

    У меня файл 131 мб не хочет скачиваться. Код function file_force_download($file… не помог.

  • Валерий

    Спасибо за плагин. Всё получилось. Но. Придется от него отказаться. Проблема — при обновлении страницы счетчик скачиваний обнуляется. Или это можно как-то исправить?

  • Оставить комментарий

    Подписаться на комментарии к этой статье по RSS

    Яндекс.Метрика