Бесплатный Instagram виджет для сайта (PHP+MySQL)

aik27

Новичок
Сделал Instagram виджет для сайта. Позволяет транслировать фотографии из вашего профиля в Instagram прямо на вашем сайте. Может кому-то пригодится. Официального виджета нет. В сети лишь сервисы различной степени бесплатности, да плагины для Wordpress.

Сайт виджета: http://inwidget.ru
Статья о виджете в песочнице Habrahabr: http://habrahabr.ru/sandbox/78178/
Прямая ссылка на архив с исходным кодом: http://inwidget.ru/widget.zip

Виджет реализован в виде PHP класса + MySQL для кэширования + файл шаблона.

Особенности вижета:
  • Множество настроек;
  • Произвольный заголовок;
  • Прямые ссылки на фотографии;
  • Кнопка перехода к странице профиля;
  • Фотография профиля;
  • Статистика профиля;
  • Вставка виджета одной строкой в HTML;
  • Без рекламы;
  • Для любого использования (коммерческого и не очень);
  • Открытый исходный код;
  • Подробная инструкция;
  • Можно модифицировать на свой вкус, включать в состав других продуктов.
Исходный код класса:
Код:
<?php
/**
* Project:    Inwidget: A PHP class showing images from Instagram.com<br />
* File:        inwidget.php<br />
*
* @link http://inwidget.ru
* @copyright 2014 Alexandr Kazarmshchikov
* @author Alexandr Kazarmshchikov
* @version 1.0 (January 2014)
* @package Inwidget
*
*/
class inWidget {
    public $config = array();
    public $profile = array();
    public $data = array();
    public $width = 260;
    public $inline = 4;
    public $view = 12;
    public $toolbar = true;
    public $preview = 'small';
    public $imgWidth = 0;
    protected $cacheId;
    public function __construct(){
        require_once 'config.php';
        $this->config = $CONFIG;
        @mysql_connect($this->config['dbHost'], $this->config['dbUser'], $this->config['dbPassword']) OR die('Can\'t connect to the database. Check settings.');
        @mysql_select_db($this->config['dbName']) OR die('Database doesn\'t exist.');
        mysql_query('SET NAMES utf8');
        mysql_query('SET time_zone = "Europe/Moscow"');
        $this->setOptions();
    }
    public function getData(){
        $cacheData = $this->getCache();
        if(empty($cacheData)){
            mysql_query('LOCK TABLES `inwidget` WRITE');
            $this->deleteCache();
            $this->createCache();
            $this->makeQuery();
            $this->updateCache();
            mysql_query('UNLOCK TABLES');
        }
        else {
            $this->data = json_decode($cacheData['data']);
            $this->profile = $cacheData;
            unset($this->profile['data']);
        }
    }
    public function makeQuery(){
        $user = $this->send('https://api.instagram.com/v1/users/search?q='.$this->config['LOGIN'].'&client_id='.$this->config['CLIENT_ID']);
        $user = json_decode($user);
        if(!empty($user)){
            if($user->meta->code == 200){
                $this->profile['userid'] = $user->data[0]->id;
                $this->profile['username'] = $user->data[0]->username;
                $this->profile['avatar'] = $user->data[0]->profile_picture;
                unset($user);
            }
            else die('User OR CLIENT_ID not found');
        }
        else die('Can\'t connect to Instagram API server.');
        $stats = $this->send('https://api.instagram.com/v1/users/'.$this->profile['userid'].'/?client_id='.$this->config['CLIENT_ID'].'');
        $stats = json_decode($stats);
        if(!empty($stats)){
            if($stats->meta->code == 200){
                $this->profile['posts']    = $stats->data->counts->media;
                $this->profile['followers'] = $stats->data->counts->followed_by;
                $this->profile['following'] = $stats->data->counts->follows;
                unset($stats);
            }
            else die('User OR CLIENT_ID not found');
        }
        else die('Can\'t connect to Instagram API server.');
        $images = $this->send('https://api.instagram.com/v1/users/'.$this->profile['userid'].'/media/recent/?client_id='.$this->config['CLIENT_ID'].'&count='.$this->config['imgCount']);
        $images = json_decode($images);
        if(!empty($images)){
            if($images->meta->code == 200){
                if(!empty($images->data)){
                    $this->data = $images->data;
                    mysql_query('UPDATE `inwidget` SET `data` = "'.addslashes(json_encode($images->data)).'" WHERE `id` = '.$this->cacheId);
                    unset($images);
                }
                else die('Empty data');
            }
            else die('CLIENT_ID not found');
        }
        else die('Can\'t connect to Instagram API server.');
    }
    public function createCache(){
        mysql_query('INSERT INTO `inwidget` SET `data` = ""');
        $this->cacheId = mysql_insert_id();
    }
    public function getCache(){
        $cacheData = mysql_query('SELECT * FROM `inwidget` WHERE `date` >= ADDDATE(NOW(), INTERVAL -'.$this->config['expiration'].' HOUR) LIMIT 1');
        $cacheData = mysql_fetch_array($cacheData);
        return $cacheData;
    }
    public function updateCache(){
        mysql_query('UPDATE `inwidget` SET
            `userid`    = '.$this->profile['userid'].',
            `username`    = "'.$this->profile['username'].'",
            `avatar`    = "'.$this->profile['avatar'].'",
            `posts`    = '.$this->profile['posts'].',
            `followers` = '.$this->profile['followers'].',
            `following` = '.$this->profile['following'].'
        WHERE `id` = '.$this->cacheId);
    }
    public function deleteCache(){
        mysql_query('DELETE FROM `inwidget` WHERE `date` < ADDDATE(NOW(), INTERVAL -'.$this->config['expiration'].' HOUR)');
    }
    public function send($url){
        if(extension_loaded('curl')){
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_HEADER, false);
            curl_setopt($ch, CURLOPT_POST, false);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_URL, $url);
            $answer = curl_exec($ch);
            curl_close($ch);
            return $answer;
        }
        elseif(ini_get('allow_url_fopen') AND extension_loaded('openssl')){
            $answer = file_get_contents($url);
            return $answer;
        }
        else die('Can\'t send request. You need the cURL extension OR set allow_url_fopen to "true" in php.ini and openssl extension');
    }
    public function setOptions(){
        $this->width -= 2;
        if(isset($_GET['width']))
            $this->width = (int)$_GET['width']-2;
        if(isset($_GET['inline']))
            $this->inline = (int)$_GET['inline'];
        if(isset($_GET['view']))
            $this->view = (int)$_GET['view'];
        if(isset($_GET['toolbar']) AND $_GET['toolbar'] == 'false')
            $this->toolbar = false;
        if(isset($_GET['preview']))
            $this->preview = $_GET['preview'];
        if($this->width>0)
            $this->imgWidth = round(($this->width-(17+(9*$this->inline)))/$this->inline);
    }
}
Примеры отображения на картинке:



Буду рад отзывам, комментариям и обратной связи.
 
Последнее редактирование:

Redjik

Джедай-мастер
Специально для таких виджетов придуман Гитхаб, никто твой архив качать тут не будет
 

Вурдалак

Продвинутый новичок
Особенности вижета:
  • Без вирусов;
Это как в продуктовом магазине нахваливать помидоры, приводя в качестве аргумента их качества отсутствие в них мышьяка. Видимо для этого человека это не является само собой разумеющимся, раньше он всегда вирусы и бекдоры пихал в свой код.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
aik27, молодец, что поделился. Не обращай внимания на тов. Вурдалак, он у нас известный ворчун)))

А замечание от Redjik в силе, на гитхабе оно выглядит солиднее
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Это как в продуктовом магазине нахваливать помидоры, приводя в качестве аргумента их качества отсутствие в них мышьяка.
Ты хотел сказать, растительное масло без холестерина... ))
 

aik27

Новичок
Спасибо, за отзыв. Создам аккаунт на github. Добавил исходный код в пост.
 

aik27

Новичок
Никогда не писал вирусов и бекдоров. Если аргумент показался из разряда россельхоз, простите. Понял, что это нужно убрать из описания =)
 

Redjik

Джедай-мастер
Код кончено ужасен, но молодец, что активно учишься, когда будет на гитхабе, попробую расписать ошибки, если не очень лень/загружен буду.
 

aik27

Новичок
Redjik, спасибо. Если у кого-то ещё есть желание раскритиковать код, буду признателен. Желательно, в стиле - вот это фигня, а нужно было так.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Учитывая целевую аудиторию, я бы посоветовал тебе собрать весь код виджета в 1 файл, кешировать запросы в файл, а не в базу, а идеальней всего - сделал бы сервис по вставке :)
 
  • Like
Реакции: Gas
Сверху