За последние 24 часа нас посетили 17423 программиста и 1601 робот. Сейчас ищет 941 программист ...

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

Тема в разделе "Решения, алгоритмы", создана пользователем aik27, 6 фев 2014.

  1. aik27

    aik27 Новичок

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

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

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

    Особенности вижета:

    • Множество настроек; [/*:m]
    • Произвольный заголовок;[/*:m]
    • Прямые ссылки на фотографии;[/*:m]
    • Кнопка перехода к странице профиля; [/*:m]
    • Фотография профиля;[/*:m]
    • Статистика профиля;[/*:m]
    • Вставка виджета одной строкой в HTML;[/*:m]
    • Без рекламы;[/*:m]
    • Для любого использования (коммерческого и не очень);[/*:m]
    • Открытый исходный код;[/*:m]
    • Подробная инструкция;[/*:m]
    • Можно модифицировать на свой вкус, включать в состав других продуктов.[/*:m][/list:u]

      Исходный код класса:
      Код (PHP):
      1. <?php
      2. /**
      3. * Project:    Inwidget: A PHP class showing images from Instagram.com<br />
      4. * File:        inwidget.php<br />
      5. *
      6. * @link http://inwidget.ru
      7. * @copyright 2014 Alexandr Kazarmshchikov
      8. * @author Alexandr Kazarmshchikov
      9. * @version 1.0 (January 2014)
      10. * @package Inwidget
      11. *
      12. */
      13. class inWidget {
      14.     public $config = array();
      15.     public $profile = array();
      16.     public $data = array();
      17.     public $width = 260;
      18.     public $inline = 4;
      19.     public $view = 12;
      20.     public $toolbar = true;
      21.     public $preview = 'small';
      22.     public $imgWidth = 0;
      23.     protected $cacheId;
      24.     public function __construct(){
      25.         require_once 'config.php';
      26.         $this->config = $CONFIG;
      27.         @mysql_connect($this->config['dbHost'], $this->config['dbUser'], $this->config['dbPassword']) OR die('Can\'t connect to the database. Check settings.');
      28.         @mysql_select_db($this->config['dbName']) OR die('Database doesn\'t exist.');
      29.         mysql_query('SET NAMES utf8');
      30.         mysql_query('SET time_zone = "Europe/Moscow"');
      31.         $this->setOptions();
      32.     }
      33.     public function getData(){
      34.         $cacheData = $this->getCache();
      35.         if(empty($cacheData)){
      36.             mysql_query('LOCK TABLES `inwidget` WRITE');
      37.             $this->deleteCache();
      38.             $this->createCache();
      39.             $this->makeQuery();
      40.             $this->updateCache();
      41.             mysql_query('UNLOCK TABLES');
      42.         }
      43.         else {
      44.             $this->data = json_decode($cacheData['data']);
      45.             $this->profile = $cacheData;
      46.             unset($this->profile['data']);
      47.         }
      48.     }
      49.     public function makeQuery(){
      50.         $user = $this->send('https://api.instagram.com/v1/users/search?q='.$this->config['LOGIN'].'&client_id='.$this->config['CLIENT_ID']);
      51.         $user = json_decode($user);
      52.         if(!empty($user)){
      53.             if($user->meta->code == 200){
      54.                 $this->profile['userid'] = $user->data[0]->id;
      55.                 $this->profile['username'] = $user->data[0]->username;
      56.                 $this->profile['avatar'] = $user->data[0]->profile_picture;
      57.                 unset($user);
      58.             }
      59.             else die('User OR CLIENT_ID not found');
      60.         }
      61.         else die('Can\'t connect to Instagram API server.');
      62.         $stats = $this->send('https://api.instagram.com/v1/users/'.$this->profile['userid'].'/?client_id='.$this->config['CLIENT_ID'].'');
      63.         $stats = json_decode($stats);
      64.         if(!empty($stats)){
      65.             if($stats->meta->code == 200){
      66.                 $this->profile['posts']    = $stats->data->counts->media;
      67.                 $this->profile['followers'] = $stats->data->counts->followed_by;
      68.                 $this->profile['following'] = $stats->data->counts->follows;
      69.                 unset($stats);
      70.             }
      71.             else die('User OR CLIENT_ID not found');
      72.         }
      73.         else die('Can\'t connect to Instagram API server.');
      74.         $images = $this->send('https://api.instagram.com/v1/users/'.$this->profile['userid'].'/media/recent/?client_id='.$this->config['CLIENT_ID'].'&count='.$this->config['imgCount']);
      75.         $images = json_decode($images);
      76.         if(!empty($images)){
      77.             if($images->meta->code == 200){
      78.                 if(!empty($images->data)){
      79.                     $this->data = $images->data;
      80.                     mysql_query('UPDATE `inwidget` SET `data` = "'.addslashes(json_encode($images->data)).'" WHERE `id` = '.$this->cacheId);
      81.                     unset($images);
      82.                 }
      83.                 else die('Empty data');
      84.             }
      85.             else die('CLIENT_ID not found');
      86.         }
      87.         else die('Can\'t connect to Instagram API server.');
      88.     }
      89.     public function createCache(){
      90.         mysql_query('INSERT INTO `inwidget` SET `data` = ""');
      91.         $this->cacheId = mysql_insert_id();
      92.     }
      93.     public function getCache(){
      94.         $cacheData = mysql_query('SELECT * FROM `inwidget` WHERE `date` >= ADDDATE(NOW(), INTERVAL -'.$this->config['expiration'].' HOUR) LIMIT 1');
      95.         $cacheData = mysql_fetch_array($cacheData);
      96.         return $cacheData;
      97.     }
      98.     public function updateCache(){
      99.         mysql_query('UPDATE `inwidget` SET
      100.             `userid`    = '.$this->profile['userid'].',
      101.             `username`    = "'.$this->profile['username'].'",
      102.             `avatar`    = "'.$this->profile['avatar'].'",
      103.             `posts`    = '.$this->profile['posts'].',
      104.             `followers` = '.$this->profile['followers'].',
      105.             `following` = '.$this->profile['following'].'
      106.         WHERE `id` = '.$this->cacheId);
      107.     }
      108.     public function deleteCache(){
      109.         mysql_query('DELETE FROM `inwidget` WHERE `date` < ADDDATE(NOW(), INTERVAL -'.$this->config['expiration'].' HOUR)');
      110.     }
      111.     public function send($url){
      112.         if(extension_loaded('curl')){
      113.             $ch = curl_init();
      114.             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      115.             curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
      116.             curl_setopt($ch, CURLOPT_HEADER, false);
      117.             curl_setopt($ch, CURLOPT_POST, false);
      118.             curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0');
      119.             curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      120.             curl_setopt($ch, CURLOPT_TIMEOUT, 10);
      121.             curl_setopt($ch, CURLOPT_URL, $url);
      122.             $answer = curl_exec($ch);
      123.             curl_close($ch);
      124.             return $answer;
      125.         }
      126.         elseif(ini_get('allow_url_fopen') AND extension_loaded('openssl')){
      127.             $answer = file_get_contents($url);
      128.             return $answer;
      129.         }
      130.         else die('Can\'t send request. You need the cURL extension OR set allow_url_fopen to "true" in php.ini and openssl extension');
      131.     }
      132.     public function setOptions(){
      133.         $this->width -= 2;
      134.         if(isset($_GET['width']))
      135.             $this->width = (int)$_GET['width']-2;
      136.         if(isset($_GET['inline']))
      137.             $this->inline = (int)$_GET['inline'];
      138.         if(isset($_GET['view']))
      139.             $this->view = (int)$_GET['view'];
      140.         if(isset($_GET['toolbar']) AND $_GET['toolbar'] == 'false')
      141.             $this->toolbar = false;
      142.         if(isset($_GET['preview']))
      143.             $this->preview = $_GET['preview'];
      144.         if($this->width>0)
      145.             $this->imgWidth = round(($this->width-(17+(9*$this->inline)))/$this->inline);
      146.     }
      147. } 
      Примеры отображения на картинке:

      [​IMG]

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

    aik27 Новичок

    С нами с:
    6 фев 2014
    Сообщения:
    2
    Симпатии:
    0
    Исходный код добавлен в пост. Если у кого-то есть желание раскритиковать код, буду признателен. Желательно, в стиле - вот это фигня, а нужно было так.
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Могу покритиковать:
    собаки - плохо
    mysql - плохо
    die - очень плохо-плохо капец как плохо =)
    Lock Tables - зачем?
     
  4. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    собаки и mysql почти не плохо...
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    почему?
     
  6. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    собаки - удобно
    mysql - по сути ничем не хуже mysqli, хотя для "новых" разработок и рекомендуется использовать второе. Вопрос нужно ли это в данном случае.
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    хуже =)
    собаки подавляют вывод ошибок.
     
  8. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    имею ввиду что гвозди можно разными способами забивать, в зависимости от необходимости.
    die() тоже есть применение, иногда удобно в ajax-бэкграунде например.
     
  9. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    1. Считаешь что
    это правильно?

    2.
    Тебя все устраивает?
     
  10. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    А как "правильно"? :D
    addslashes пропускает sql inj только при определенных кодировках, да и данные идут от API.
     
  11. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    HOROsho а ты случайно не новое воплощение aik27?

    mysql_set_charset

    Тогда расуждая как ты можно задать вопрос - зачем вообще здесь экранировать?
    Если и экранировать то давайте будем делать правильно.
     
  12. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    потому что json
    http://dev.mysql.com/doc/refman/5.7/en/charset-connection.html

    ты в туалет тоже только правильно ходишь? )))
     
  13. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Не уловил смысл, так ты за экранирование или нет?

    Юморист? Да в отличии от некоторых я ссу не на стены если ты об этом.

    Просвещаяся специалист с 6-летним опытом
    php.net/manual/en/mysqlinfo.concepts.charset.php
     
  14. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    json экранировать надо, потому что там есть кавычки )
    коды кавычек 0x22 и 0x27 везде.
     
  15. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Теперь ты начинаешь противоречить самому себе:)
    О чем ты думал когда писал
    Я поражен твоей эрудированностью.
     
  16. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    погугли разницу меджу real_escape_string и addslashes, я сразу сказал - в данном случае её нет. Чего ты не понимаешь, я не знаю...
    покажи мне, как тут выполнить sql inj? (пусть данные идут не от API)
     
  17. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Разницу я знаю.

    Даже если нельзя, уже 2 человек в этом топике пишут что код написан не лучшим образом. То что код работает это не означает что он написан качественно.
    Про данный код можно смело сказать - быдлокодство-говнокодство.

    Признайся ты и aik27 это один и тот же человек?
     
  18. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    что конкретно изменится если ты добавишь set_charset и real_escape_string?
    я не говорил что весь код качественный ) я сказал что собаки, mysql это не сильно плохо.
    нет

    вот скажи мне, как правильно ООП или процедурник? или DBSimple vs PDO? )))
    А вот так правильно?
    Код (PHP):
    1. <?php
    2. class Modules_Admin_Parser_Driver_SiteCom implements Modules_Admin_Parser_Interface {
    3. }
    4. ?>
     
  19. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Могу поспорить что ты думаешь что моим 1 постом я обращался к тебе:)
    Ты ошибаешься:)

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

    Я очень рад что ты не aik27 но ты рьяно защищаешь этот код и складывается противоположное мнение.

    1. Зависит от задачи. Если разрабатывается что то большое где работает группа разработчиков то тут без ООП будет крайне сложно.
    Если мелочь какая то, простая задача то можно не замарачиваться ООП. Но опять же все зависит от конкретной задачи!
    2. Ясное дело - PDO.

    Ты о чем? Что ты делаешь, какая задача?

    Отвечу вопросом на вопрос что лучше белый или серый?
     
  20. HOROsho

    HOROsho Новичок

    С нами с:
    16 фев 2014
    Сообщения:
    10
    Симпатии:
    0
    Я ещё php3 помню, так вот мне было проще тогда разбираться в исходниках, ибо в процедурнике все на виду, а сейчас голову сломаешь пока разберешься во всех связях...
    о неймспейсах...

    вобщем тут не в задаче дело, а в том как тебе нравится больше, при условии что в результате все будет работать в рамках ТЗ. :) Нравится ООП - пожалуйста, процедурник - пожалуйста, DBsimple - хочешь юзай и тд.