Сделал 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): <?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); } } Примеры отображения на картинке: Буду рад отзывам, комментариям и обратной связи.
Исходный код добавлен в пост. Если у кого-то есть желание раскритиковать код, буду признателен. Желательно, в стиле - вот это фигня, а нужно было так.
Могу покритиковать: собаки - плохо mysql - плохо die - очень плохо-плохо капец как плохо =) Lock Tables - зачем?
собаки - удобно mysql - по сути ничем не хуже mysqli, хотя для "новых" разработок и рекомендуется использовать второе. Вопрос нужно ли это в данном случае.
имею ввиду что гвозди можно разными способами забивать, в зависимости от необходимости. die() тоже есть применение, иногда удобно в ajax-бэкграунде например.
А как "правильно"? addslashes пропускает sql inj только при определенных кодировках, да и данные идут от API.
HOROsho а ты случайно не новое воплощение aik27? mysql_set_charset Тогда расуждая как ты можно задать вопрос - зачем вообще здесь экранировать? Если и экранировать то давайте будем делать правильно.
потому что json http://dev.mysql.com/doc/refman/5.7/en/charset-connection.html ты в туалет тоже только правильно ходишь? )))
Не уловил смысл, так ты за экранирование или нет? Юморист? Да в отличии от некоторых я ссу не на стены если ты об этом. Просвещаяся специалист с 6-летним опытом php.net/manual/en/mysqlinfo.concepts.charset.php
Теперь ты начинаешь противоречить самому себе О чем ты думал когда писал Я поражен твоей эрудированностью.
погугли разницу меджу real_escape_string и addslashes, я сразу сказал - в данном случае её нет. Чего ты не понимаешь, я не знаю... покажи мне, как тут выполнить sql inj? (пусть данные идут не от API)
Разницу я знаю. Даже если нельзя, уже 2 человек в этом топике пишут что код написан не лучшим образом. То что код работает это не означает что он написан качественно. Про данный код можно смело сказать - быдлокодство-говнокодство. Признайся ты и aik27 это один и тот же человек?
что конкретно изменится если ты добавишь set_charset и real_escape_string? я не говорил что весь код качественный ) я сказал что собаки, mysql это не сильно плохо. нет вот скажи мне, как правильно ООП или процедурник? или DBSimple vs PDO? ))) А вот так правильно? Код (PHP): <?php class Modules_Admin_Parser_Driver_SiteCom implements Modules_Admin_Parser_Interface { } ?>
Могу поспорить что ты думаешь что моим 1 постом я обращался к тебе Ты ошибаешься Есть определенные назовем их стандарты хорошего кода. Если тебе создатели языка говорят используй это, так правильно, но программист делает иначе говорит а какая разница ведь работает, то это называется идиотизм а не качаственно сделанная работа - работа высококвалифицированного специалиста. Я очень рад что ты не aik27 но ты рьяно защищаешь этот код и складывается противоположное мнение. 1. Зависит от задачи. Если разрабатывается что то большое где работает группа разработчиков то тут без ООП будет крайне сложно. Если мелочь какая то, простая задача то можно не замарачиваться ООП. Но опять же все зависит от конкретной задачи! 2. Ясное дело - PDO. Ты о чем? Что ты делаешь, какая задача? Отвечу вопросом на вопрос что лучше белый или серый?
Я ещё php3 помню, так вот мне было проще тогда разбираться в исходниках, ибо в процедурнике все на виду, а сейчас голову сломаешь пока разберешься во всех связях... о неймспейсах... вобщем тут не в задаче дело, а в том как тебе нравится больше, при условии что в результате все будет работать в рамках ТЗ. Нравится ООП - пожалуйста, процедурник - пожалуйста, DBsimple - хочешь юзай и тд.