├── MIT-license.txt ├── README.md ├── cache └── readme.txt ├── classes ├── Autoload.php ├── InWidget.php ├── InWidget │ ├── Api │ │ ├── ApiModel.php │ │ ├── ApiOfficial.php │ │ └── ApiScraper.php │ ├── Core.php │ └── Exception │ │ └── InWidgetException.php ├── InstagramScraper.php ├── InstagramScraper │ ├── Endpoints.php │ ├── Exception │ │ ├── InstagramAuthException.php │ │ ├── InstagramException.php │ │ └── InstagramNotFoundException.php │ ├── Instagram.php │ ├── InstagramQueryId.php │ ├── LICENSE │ ├── Model │ │ ├── AbstractModel.php │ │ ├── Account.php │ │ ├── CarouselMedia.php │ │ ├── Comment.php │ │ ├── Like.php │ │ ├── Location.php │ │ ├── Media.php │ │ ├── Story.php │ │ ├── Tag.php │ │ └── UserStories.php │ └── Traits │ │ ├── ArrayLikeTrait.php │ │ └── InitializerTrait.php ├── Unirest.php └── Unirest │ ├── Exception.php │ ├── LICENSE │ ├── Method.php │ ├── README.md │ ├── Request.php │ ├── Request │ └── Body.php │ └── Response.php ├── composer.json ├── config.php ├── index.php ├── langs ├── en.php ├── ru.php └── ua.php ├── plugins └── adaptive.php ├── readme_ru.txt ├── skins ├── default.css ├── i │ ├── icon.png │ └── icon_modern.png ├── js │ └── jquery-3.2.1.min.js ├── modern-black.css ├── modern-blue.css ├── modern-green.css ├── modern-grey.css ├── modern-orange.css ├── modern-red.css ├── modern-violet.css └── modern-yellow.css └── template.php /MIT-license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2020 Alexandr Kazarmshchikov 4 | Site: https://inwidget.ru 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | Copyright (c) 2014-2020 Александр Казармщиков 25 | Сайт: https://inwidget.ru 26 | 27 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения 28 | и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), 29 | безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, 30 | копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий 31 | Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, 32 | при соблюдении следующих условий: 33 | 34 | Указанное выше уведомление об авторском праве и данные условия должны 35 | быть включены во все копии или значимые части данного Программного Обеспечения. 36 | 37 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, 38 | ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ 39 | ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ 40 | НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ 41 | ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ 42 | КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ 43 | С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ 44 | ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. 45 | 46 | Перевод лицензии на русском языке взят с сайта: 47 | http://ru.wikipedia.org/wiki/Лицензия_MIT -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # inWidget - free Instagram widget for your website 2 | 3 | This library is based on PHP and allows you to show photos from an Instagram account on your website. 4 | 5 | [Demonstration >>](https://inwidget.ru/en/demo.php) 6 | 7 | ![demo](https://inwidget.ru/i/demo_en_2.jpg) 8 | 9 | ### Features: 10 | 11 | + Many settings 12 | + Direct links to photos 13 | + Profile stats 14 | + Adaptive, responsive template 15 | + Support of several hashtags 16 | + Language auto detection 17 | + Works without ACCESS_TOKEN 18 | + Inserting with one line in HTML 19 | + Many skins 20 | + Without advertising 21 | + For any use 22 | + Detailed instructions 23 | 24 | ## System requirements 25 | 26 | PHP >= 5.4.0 with cURL extension 27 | 28 | ## Installation 29 | 30 | ### 1. Upload source code to the root folder of your website 31 | 32 | [Download](https://github.com/aik27/inwidget/releases) source code. Extract /inwidget folder. 33 | Upload /inwidget folder to website with all files inside. 34 | 35 | Or use composer 36 | 37 | ```sh 38 | composer.phar require aik27/inwidget 39 | ``` 40 | 41 | ```sh 42 | composer require aik27/inwidget 43 | ``` 44 | 45 | **Note**. inWidget using relative paths, so you can upload it to any folder. After that do not forget change URL in IFRAME tag. 46 | 47 | ### 2. Set write permissions to the folder: /inwidget/cache 48 | 49 | inWidget will store cached data in /inwidget/cache folder. 50 | If this directory does not have write permissions you will see ERROR #101. 51 | 52 | ### 3. Configuration 53 | 54 | Modify /inwidget/config.php 55 | You will need to specify Instagram login and other params 56 | 57 | List of parameters: 58 | 59 | + **LOGIN** - Instagram login 60 | + **HASHTAG** - hashtags separated by a comma (for example: girl, man). Selection will be made from around the world in the order that photos were marked with desired tags 61 | + **ACCESS_TOKEN** - a hashkey granted to you by an Instagram app. This option is NOT required. If you use it, the widget will start sending requests through the official endpoints API (https://www.instagram.com/developer/). In this case, the widget will have only those rights and limits that the application itself possesses. For more information about, please, use this link: https://inwidget.ru/#token 62 | + **authLogin and authPassword** - login and password of an account for authorization. This options are NOT required. Authorization is necessary for alternative methods of obtaining data and provides more stability when you using the undocumented API. I advise you to create a separate account for this with disabled two-step authentication. Authorization data is not transferred to third parties and author of the widget 63 | + **loginAvailable** - If you need to separate logins on diffent website pages, just add possible logins to the array below. After that you can send login to the widget by GET variable. It workds only with the undocumented API. Example: /inwidget/index.php?login=fotokto_ru 64 | + **tagsAvailable** - Same option for tagged media. Add possible tags to the array below. Then you can use GET variable for tags. Example: /inwidget/index.php?tag=photography. You can mix this option with "loginAvailable" and "tagsFromAccountOnly" 65 | + **tagsBannedLogins** - Specify here list of banned logins. Photos of these users will not be display in the widget. Separate usernames by a comma. For example: mark18, kitty45 66 | + **tagsFromAccountOnly** - Search tagged media from your account only [ true / false ]. To improve search increase value of "imgCount" option 67 | + **imgRandom** - Random order of pictures [ true / false ] 68 | + **imgCount** - How many pictures the widget will get from Instagram? 69 | + **cacheExpiration** - Cache expiration time (hours) 70 | + **cacheSkip** - Skip cache data [ true / false ]. So mean, requests to Instagram API will be sending every time. Warning! Use true value only for debug 71 | + **cachePath** - Full path to the cache directory 72 | + **skinDefault** - Default skin. Possible values: *default, modern-blue, modern-green, modern-red, modern-orange, modern-grey, modern-black, modern-violet, modern-yellow*. This option may no effect if you set a skin by $_GET variable 73 | + **skinPath** - Path to the skins directory 74 | + **langDefault** - Default language [ ru / en / ua ] or something else from the langs directory 75 | + **langPath** - Full path to the langs directory 76 | + **langAuto** - Language auto-detection [ true / false ]. This option may no effect if you set a language by $_GET variable 77 | 78 | ### 4. Paste this code into your html template 79 | 80 | ``` 81 | 82 | 83 | ``` 84 | 85 | Or use another examples with different display type: 86 | 87 | ``` 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | ``` 103 | 104 | ## Fine-tune widget display 105 | 106 | Parameters are passed as GET variables when accessing to the widget script. For that you must change the URL in IFRAME tag. For example, to set the widget width to 600px and display five photos per a single row, you need to add appropriate parameters in the URL. 107 | 108 | ``` 109 | /inwidget/index.php?width=600&inline=5 110 | ``` 111 | 112 | List of parameters: 113 | 114 | + **width** - the widget width (default: 260px) 115 | + **inline** - number of photos per line (default: 4 pcs.) 116 | + **view** - how many photos can be displayed in the widget (default: 12 pcs, max.: 30 pcs, you can change it in config.php) 117 | + **toolbar** - display toolbar with avatar and statistics ( true / false, default: true) 118 | + **preview** - size and quality of images (small - 320px, large - 640px, fullsize - maximum avalible size, default: large) 119 | + **lang** - the widget language (ru / en / ua, default settings are taken from config.php ). Priority of this parameter is higher than for settings in config.php 120 | + **skin** - the widget skin (default / modern-blue / modern-green / modern-red / modern-orange / modern-gray / modern-black / modern-violet / modern-yellow). Default value: default. Priority of this parameter is higher than for settings in config.php 121 | + **adaptive** - adaptive, responsive mode (true / false, by default: false). Widget will automatically adjust to dimensions of html container or browser window 122 | 123 | When you changing width or number of photos, do not forget to change IFRAME tag size. 124 | 125 | 126 | ## How to make the widget adaptive / responsive? [(example)](https://inwidget.ru/adaptive.php) 127 | 128 | Add GET variable "adaptive" in the URL of IFRAME tag. 129 | 130 | ``` 131 | /inwidget/index.php?adaptive=true 132 | ``` 133 | 134 | The value must be set to true. After that, the widget will automatically adjust to the dimensions of html container or browser window. In this case, the GET parameter "width" will be ignored, the "inline" parameter will have an effect when the widget width of more than 400px. 135 | 136 | Please, see demonstration of adaptive mode: https://inwidget.ru/adaptive.php 137 | 138 | ## Video instruction how to get ACCESS TOKEN 139 | 140 | https://www.youtube.com/watch?v=_O669Dx3djw 141 | 142 | The URL to generate ACCESS TOKEN: 143 | 144 | ``` 145 | https://www.instagram.com/oauth/authorize/?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=token&scope=basic 146 | ``` 147 | 148 | The widget can work with two kinds of API (undocumented and endpoints). Default API is undocumented. Access token is not required for it. Specifying ACCESS TOKEN in the widget's settings takes it to Endpoints API mode (https://www.instagram.com/developer/). If you want to create your own application in Instagram, then use video instruction above. Keep in mind that your application will first get into "sandbox" with following limits: 149 | 150 | + **20** - maximum number of photos that can be obtained per one request. 151 | + **500** - maximum number of requests per hour. 152 | + ***And most importantly*** - photos can be obtained from your account only. Same goes for selection by tags. 153 | 154 | **Keep in mind that Instagram has announced the end of support for endpoint API by 2020**. 155 | More information: https://developers.facebook.com/blog/post/2018/01/30/instagram-graph-api-updates/ 156 | 157 | ## For developers 158 | 159 | You can include inWidget library in your application and set parameters through the class constructor. Be careful with the file paths when using example below. The classes support autoloading. 160 | 161 | By default the widget use undocumented API that provided by [instagram-php-scraper](https://github.com/postaddictme/instagram-php-scraper) library. To switch to the endpoint API, you need to specify ACCESS_TOKEN. 162 | 163 | ```php 164 | #require_once 'inwidget/classes/Autoload.php'; 165 | require_once 'inwidget/classes/InstagramScraper.php'; 166 | require_once 'inwidget/classes/Unirest.php'; 167 | require_once 'inwidget/classes/InWidget.php'; 168 | 169 | try { 170 | 171 | // Options may change through the class constructor. For example: 172 | 173 | $config = array( 174 | 'LOGIN' => 'fotokto_ru', 175 | 'HASHTAG' => '', 176 | 'ACCESS_TOKEN' => '', 177 | 'authLogin' => '', 178 | 'authPassword' => '', 179 | 'tagsBannedLogins' => '', 180 | 'tagsFromAccountOnly' => false, 181 | 'imgRandom' => true, 182 | 'imgCount' => 30, 183 | 'cacheExpiration' => 6, 184 | 'cacheSkip' => false, 185 | 'cachePath' => $_SERVER['DOCUMENT_ROOT'].'/inwidget/cache/', 186 | 'skinDefault' => 'default', 187 | 'skinPath'=> '/inwidget/skins/', 188 | 'langDefault' => 'ru', 189 | 'langAuto' => false, 190 | 'langPath' => $_SERVER['DOCUMENT_ROOT'].'/inwidget/langs/', 191 | ); 192 | 193 | $inWidget = new \InWidget\Core($config); 194 | 195 | // Also, you may change default values of properties 196 | 197 | /* 198 | $inWidget->width = 800; // widget width in pixels 199 | $inWidget->inline = 6; // number of images in single line 200 | $inWidget->view = 18; // number of images in widget 201 | $inWidget->toolbar = false; // show profile avatar, statistic and action button 202 | $inWidget->preview = 'large'; // quality of images: small, large, fullsize 203 | $inWidget->adaptive = false; // enable adaptive mode 204 | $inWidget->skipGET = true; // skip GET variables to avoid name conflicts 205 | $inWidget->setOptions(); // apply new values 206 | */ 207 | 208 | $inWidget->getData(); 209 | include 'inwidget/template.php'; 210 | 211 | } 212 | catch (\Exception $e) { 213 | echo $e->getMessage(); 214 | } 215 | ``` 216 | 217 | ## Error codes 218 | 219 | **ERROR #101** - can not access to the cached file. You need to change permissions for directory: /inwidget/cache 220 | 221 | If cached file does not exist, the widget will try to create it. Then the widget will try to open it for reading and writing. Incorrect rights provide this error. If you already had some files in the cache directory, just delete them, because they also may has incorrect rights. 222 | 223 | **ERROR #102** - can not get the last modification time of the cached file. 224 | 225 | Perhaps, this function is limited or not supported by your server's file system. If the widget can not determine the time, cache will always be irrelevant, which will result in permanent requests to Instagram API. 226 | 227 | **ERROR #500** - unknown error 228 | 229 | Please, see what exactly was written into the cached file. This error is generated by the official API or instagram-php-scraper library. In most cases, it means a problem when sending or receiving data from Instagram server. Delete the cached file and refresh a page (on which the widget is displayed) to try send request again. 230 | 231 | ## Feedback, questions and suggestions 232 | 233 | + Visit website: https://inwidget.ru 234 | + Write to: aik@inwidget.ru 235 | + Join to development on GitHub: https://github.com/aik27/inwidget 236 | + Article about inWidget on Habrahabr: http://habrahabr.ru/post/223739/ 237 | 238 | ## Donate 239 | 240 | inWidget is a non-profit library that exists on bare enthusiasm. Your support are welcome! 241 | 242 | PayPal: aik@inwidget.ru 243 | 244 | Thank you! 245 | 246 | ## Copyrights 247 | 248 | + Author: Alexandr Kazarmshchikov 249 | + E-mail: aik@inwidget.ru 250 | + Site: https://inwidget.ru 251 | 252 | ## License 253 | 254 | This library is free software; you can redistribute it and/or modify it under the terms of MIT license: https://inwidget.ru/MIT-license.txt -------------------------------------------------------------------------------- /cache/readme.txt: -------------------------------------------------------------------------------- 1 | This directory contains cached files -------------------------------------------------------------------------------- /classes/Autoload.php: -------------------------------------------------------------------------------- 1 | account) && $this->account['username'] === $login) { 38 | return $this->account; 39 | } 40 | $account = ''; 41 | $answer = Request::get('https://api.instagram.com/v1/users/self/?access_token=' . $token); 42 | $this->checkAnswer($answer, 'getAccountByLogin'); 43 | $this->account = $this->prepareAccountData($answer->body->data); 44 | return $this->account; 45 | } 46 | 47 | /** 48 | * Get media data by login 49 | * 50 | * @param string $login 51 | * @param string $token - access token 52 | * @param int $count - maximum medias per page [optional] 53 | * @param int $maxId - return media earlier than this max_id [optional] 54 | * @return array 55 | * @throws \Exception 56 | */ 57 | public function getMediasByLogin($login, $token, $count = 30, $maxId = '') 58 | { 59 | $index = 0; 60 | $medias = []; 61 | $isMoreAvailable = true; 62 | while ($index < $count && $isMoreAvailable) { 63 | $answer = Request::get( 64 | 'https://api.instagram.com/v1/users/self/media/recent/?access_token=' . $token . '&max_id=' . $maxId 65 | ); 66 | $this->checkAnswer($answer); 67 | $nodes = $answer->body->data; 68 | if (empty($nodes)) { 69 | return []; 70 | } 71 | foreach ($nodes as $item) { 72 | if ($index === $count) { 73 | return $this->prepareMediasData($medias); 74 | } 75 | $medias[] = $item; 76 | $index++; 77 | } 78 | $maxId = $nodes[count($nodes) - 1]->id; 79 | if (!isset($answer->body->pagination->next_url)) { 80 | $isMoreAvailable = false; 81 | } 82 | } 83 | return $this->prepareMediasData($medias); 84 | } 85 | 86 | /** 87 | * Get tagged media 88 | * 89 | * @param string $tag 90 | * @param string $token - access token 91 | * @param int $count - maximum medias per page [optional] 92 | * @param string $maxId - return media earlier than this max_tag_id [optional] 93 | * @return array 94 | * @throws \Exception 95 | */ 96 | public function getMediasByTag($tag, $token, $count = 30, $maxId = '') 97 | { 98 | $index = 0; 99 | $medias = []; 100 | $isMoreAvailable = true; 101 | $tag = parent::prepareTag($tag); 102 | while ($index < $count && $isMoreAvailable) { 103 | $answer = Request::get( 104 | 'https://api.instagram.com/v1/tags/' . urlencode( 105 | $tag 106 | ) . '/media/recent/?access_token=' . $token . '&max_tag_id=' . $maxId 107 | ); 108 | $this->checkAnswer($answer); 109 | $nodes = $answer->body->data; 110 | if (empty($nodes)) { 111 | return $this->prepareMediasData($medias); 112 | } 113 | foreach ($nodes as $item) { 114 | if ($index === $count) { 115 | return $this->prepareMediasData($medias); 116 | } 117 | $medias[] = $item; 118 | $index++; 119 | } 120 | $maxId = $answer->body->pagination->next_max_tag_id; 121 | if (!isset($answer->body->pagination->next_url)) { 122 | $isMoreAvailable = false; 123 | } 124 | } 125 | return $this->prepareMediasData($medias); 126 | } 127 | 128 | /** 129 | * Get tagged media from account 130 | * 131 | * @param string $tag 132 | * @param string $login 133 | * @param string $token - access token 134 | * @param int $count - maximum medias per page [optional] 135 | * @param string $maxId - return media earlier than this max_tag_id [optional] 136 | * @return array 137 | * @throws \Exception 138 | */ 139 | public function getMediasByTagFromAccount($tag, $login, $token = '', $count = 30, $maxId = '') 140 | { 141 | $tag = parent::prepareTag($tag); 142 | $medias = $this->getMediasByLogin($login, $token, $count, $maxId); 143 | $result = []; 144 | foreach ($medias as $key => $item) { 145 | if (preg_match("/#" . $tag . "/is", $item['text'])) { 146 | $result[] = $item; 147 | } 148 | } 149 | return $result; 150 | } 151 | 152 | /** 153 | * Get account data independent of API names policy 154 | * 155 | * @param object $account 156 | * @return array 157 | */ 158 | protected function prepareAccountData($account) 159 | { 160 | $data = []; 161 | $data['userid'] = $account->id; 162 | $data['username'] = $account->username; 163 | $data['avatar'] = $account->profile_picture; 164 | $data['full_name'] = $account->full_name; 165 | $data['bio'] = $account->bio; 166 | $data['website'] = $account->website; 167 | $data['posts'] = $account->counts->media; 168 | $data['followers'] = $account->counts->followed_by; 169 | $data['following'] = $account->counts->follows; 170 | return $data; 171 | } 172 | 173 | /** 174 | * Get media data independent of API names policy 175 | * 176 | * @param object $medias 177 | * @return array 178 | */ 179 | protected function prepareMediasData($medias) 180 | { 181 | $data = []; 182 | foreach ($medias as $key => $item) { 183 | $data[$key]['id'] = $this->ejectMediaId($item->id); 184 | $data[$key]['code'] = $this->getCodeFromUrl($item->link); 185 | $data[$key]['created'] = $item->created_time; 186 | $data[$key]['text'] = $item->caption->text; 187 | $data[$key]['link'] = $item->link; 188 | $data[$key]['type'] = $item->type; 189 | $data[$key]['fullsize'] = $item->images->standard_resolution->url; 190 | $data[$key]['large'] = $item->images->low_resolution->url; 191 | $data[$key]['small'] = $item->images->thumbnail->url; 192 | $data[$key]['likesCount'] = $item->likes->count; 193 | $data[$key]['commentsCount'] = $item->comments->count; 194 | $data[$key]['authorId'] = $item->user->id; 195 | } 196 | return $data; 197 | } 198 | 199 | /** 200 | * Get media ID from combinated data returned by API 201 | * 202 | * @param string $id 203 | * @return string 204 | */ 205 | private function ejectMediaId($id) 206 | { 207 | $id = explode('_', $id); 208 | return $id[0]; 209 | } 210 | 211 | /** 212 | * Get media code from URL 213 | * 214 | * @param string $url 215 | * @return string 216 | */ 217 | private function getCodeFromUrl($url) 218 | { 219 | preg_match('#.*\/p\/(.*)/#i', $url, $matches); 220 | return $matches[1]; 221 | } 222 | 223 | /** 224 | * Check server response 225 | * 226 | * @param object $answer - returned by unirest-php library 227 | * @param string $from - expected content type [to specify check] 228 | * @return null 229 | * @throws \Exception 230 | */ 231 | public function checkAnswer($answer, $from = '') 232 | { 233 | if (!is_object($answer)) { 234 | throw new \Exception('Unknown error. Server answer: ' . $answer); 235 | } 236 | if ($answer->code == 400) { 237 | throw new \Exception('Invalid ACCESS TOKEN. Server answer: ' . $answer->raw_body); 238 | } 239 | if ($answer->code == 429) { 240 | throw new \Exception('The maximum number of requests per hour has been exceeded.'); 241 | } 242 | if ($answer->code !== 200) { 243 | throw new \Exception('Unknown error. Server answer: ' . $answer->raw_body); 244 | } 245 | if ($from === 'getAccountByLogin') { 246 | if (empty($answer->body->data)) { 247 | throw new \Exception('Account with given username does not exist or not available in sandbox mode.'); 248 | } 249 | } 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /classes/InWidget/Api/ApiScraper.php: -------------------------------------------------------------------------------- 1 | api = new \InstagramScraper\Instagram(); 27 | if (!empty($login) and !empty($password)) { 28 | $api = $this->api->withCredentials($login, $password); 29 | $api->login(); 30 | $this->api = $api; 31 | } 32 | } 33 | 34 | /** 35 | * Get account data by login 36 | * 37 | * @param string $login 38 | * @param string $token - fake param, not needed to this API driver 39 | * @return array 40 | * @throws \Exception 41 | */ 42 | public function getAccountByLogin($login, $token = '') 43 | { 44 | $account = $this->api->getAccount($login); 45 | if ($account->isPrivate()) { 46 | throw new \Exception('Requested profile is private'); 47 | } 48 | return $this->prepareAccountData($account); 49 | } 50 | 51 | /** 52 | * Get media data by login 53 | * 54 | * @param string $login 55 | * @param string $token - fake param, not needed to this API driver 56 | * @param int $count - maximum medias per page [optional] 57 | * @param int $maxId - return media earlier than this max_id [optional] 58 | * @return array 59 | * @throws \Exception 60 | */ 61 | public function getMediasByLogin($login, $token = '', $count = 30, $maxId = '') 62 | { 63 | $medias = $this->api->getMedias($login, $count, $maxId); 64 | return $this->prepareMediasData($medias); 65 | } 66 | 67 | /** 68 | * Get tagged media 69 | * 70 | * @param string $tag 71 | * @param string $token - fake param, not needed to this API driver 72 | * @param int $count - maximum medias per page [optional] 73 | * @param string $maxId - return media earlier than this max_tag_id [optional] 74 | * @return array 75 | * @throws \Exception 76 | */ 77 | public function getMediasByTag($tag, $token = '', $count = 30, $maxId = '') 78 | { 79 | $tag = parent::prepareTag($tag); 80 | $medias = $this->api->getMediasByTag($tag, $count, $maxId); 81 | return $this->prepareMediasData($medias); 82 | } 83 | 84 | /** 85 | * Get tagged media from account 86 | * 87 | * @param string $tag 88 | * @param string $login 89 | * @param string $token - fake param, not needed to this API driver 90 | * @param int $count - maximum medias per page [optional] 91 | * @param string $maxId - return media earlier than this max_id [optional] 92 | * @return array 93 | * @throws \Exception 94 | */ 95 | public function getMediasByTagFromAccount($tag, $login, $token = '', $count = 30, $maxId = '') 96 | { 97 | $tag = parent::prepareTag($tag); 98 | $medias = $this->getMediasByLogin($login, $token, $count, $maxId); 99 | $result = []; 100 | foreach ($medias as $key => $item) { 101 | if (preg_match("/#" . $tag . "/is", $item['text'])) { 102 | $result[] = $item; 103 | } 104 | } 105 | return $result; 106 | } 107 | 108 | /** 109 | * Get account data independent of API names policy 110 | * 111 | * @param object $account 112 | * @return array 113 | */ 114 | protected function prepareAccountData($account) 115 | { 116 | $data = []; 117 | $data['userid'] = $account->getId(); 118 | $data['username'] = $account->getUsername(); 119 | $data['avatar'] = $account->getProfilePicUrl(); 120 | $data['full_name'] = $account->getFullName(); 121 | $data['bio'] = $account->getBiography(); 122 | $data['website'] = $account->getExternalUrl(); 123 | $data['posts'] = $account->getMediaCount(); 124 | $data['followers'] = $account->getFollowedByCount(); 125 | $data['following'] = $account->getFollowsCount(); 126 | return $data; 127 | } 128 | 129 | /** 130 | * Get media data independent of API names policy 131 | * 132 | * @param object $medias 133 | * @return array 134 | */ 135 | protected function prepareMediasData($medias) 136 | { 137 | $data = []; 138 | foreach ($medias as $key => $item) { 139 | $data[$key]['id'] = $item->getId(); 140 | $data[$key]['code'] = $item->getShortCode(); 141 | $data[$key]['created'] = $item->getCreatedTime(); 142 | $data[$key]['text'] = $item->getCaption(); 143 | $data[$key]['link'] = $item->getLink(); 144 | $data[$key]['type'] = $item->getType(); 145 | $data[$key]['fullsize'] = $item->getImageHighResolutionUrl(); 146 | $data[$key]['large'] = $item->getImageStandardResolutionUrl(); 147 | $data[$key]['small'] = $item->getImageLowResolutionUrl(); 148 | $data[$key]['likesCount'] = $item->getLikesCount(); 149 | $data[$key]['commentsCount'] = $item->getCommentsCount(); 150 | $data[$key]['authorId'] = $item->getOwnerId(); 151 | if (empty($data[$key]['type'])) { 152 | $data[$key]['type'] = "image"; 153 | } 154 | } 155 | return $data; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /classes/InWidget/Core.php: -------------------------------------------------------------------------------- 1 | config = $config; 70 | } else { 71 | require_once 'config.php'; 72 | $this->config = $CONFIG; 73 | } 74 | $this->checkConfig(); 75 | $this->checkCacheRights(); 76 | $this->setLang(); 77 | $this->setSkin(); 78 | $this->setOptions(); 79 | try { 80 | if (!empty($this->config['ACCESS_TOKEN'])) { 81 | $this->api = ApiModel::getInstance('official'); 82 | } else { 83 | $this->api = ApiModel::getInstance('', $config['authLogin'], $config['authPassword']); 84 | } 85 | } catch (\Exception $e) { 86 | throw new InWidgetException($e->getMessage(), 500, $this->getCacheFilePath()); 87 | } 88 | } 89 | 90 | /** 91 | * Send request to Instagram 92 | * 93 | * @return null 94 | * @throws InWidgetException 95 | */ 96 | private function apiQuery() 97 | { 98 | try { 99 | $this->account = $this->api->getAccountByLogin($this->config['LOGIN'], $this->config['ACCESS_TOKEN']); 100 | // by hashtag 101 | if (!empty($this->config['HASHTAG'])) { 102 | $mediaArray = []; 103 | $tags = explode(',', $this->config['HASHTAG']); 104 | if (!empty($tags)) { 105 | foreach ($tags as $key => $item) { 106 | if (!empty($item)) { 107 | if ($this->config['tagsFromAccountOnly'] === true) { 108 | $mediaArray[] = $this->api->getMediasByTagFromAccount( 109 | $item, 110 | $this->config['LOGIN'], 111 | $this->config['ACCESS_TOKEN'], 112 | $this->config['imgCount'] 113 | ); 114 | } else { 115 | $mediaArray[] = $this->api->getMediasByTag( 116 | $item, 117 | $this->config['ACCESS_TOKEN'], 118 | $this->config['imgCount'] 119 | ); 120 | } 121 | } 122 | } 123 | } 124 | $medias = []; 125 | if (!empty($mediaArray)) { 126 | foreach ($mediaArray as $key => $item) { 127 | $medias = array_merge($medias, $item); 128 | } 129 | } 130 | $this->medias = $medias; 131 | unset($mediaArray, $medias); 132 | } else { 133 | $this->medias = $this->api->getMediasByLogin( 134 | $this->config['LOGIN'], 135 | $this->config['ACCESS_TOKEN'], 136 | $this->config['imgCount'] 137 | ); 138 | } 139 | } catch (\Exception $e) { 140 | throw new InWidgetException($e->getMessage(), 500, $this->getCacheFilePath()); 141 | } 142 | // Get banned ids. Ignore any errors 143 | if (!empty($this->config['tagsBannedLogins'])) { 144 | foreach ($this->config['tagsBannedLogins'] as $key => $item) { 145 | try { 146 | $banned = $this->api->getAccountByLogin($item['login'], $this->config['ACCESS_TOKEN']); 147 | $this->config['tagsBannedLogins'][$key]['id'] = $banned['userid']; 148 | } catch (\Exception $e) { 149 | } 150 | } 151 | $this->banned = $this->config['tagsBannedLogins']; 152 | } 153 | } 154 | 155 | /** 156 | * Get data from Instagram (or actual cache) 157 | * 158 | * @return object 159 | * @throws \Exception 160 | * @throws InWidgetException 161 | */ 162 | public function getData() 163 | { 164 | $this->data = $this->getCache(); 165 | if (empty($this->data)) { 166 | $this->apiQuery(); 167 | $this->createCache(); 168 | $this->data = json_decode(file_get_contents($this->getCacheFilePath())); 169 | } 170 | if (!is_object($this->data)) { 171 | $this->data = $this->getBackup(); 172 | if (!is_object($this->data)) { 173 | $this->data = $this->getCache(); 174 | throw new \Exception('Cache file contains plain text:
' . $this->data); 175 | } else { 176 | $this->data->isBackup = true; 177 | } 178 | } 179 | return $this->data; 180 | } 181 | 182 | /** 183 | * Get data independent of API names policy 184 | * @return array 185 | */ 186 | private function prepareData() 187 | { 188 | $data = $this->account; 189 | $data['banned'] = $this->banned; 190 | $data['tags'] = $this->config['HASHTAG']; 191 | $data['images'] = $this->medias; 192 | $data['lastupdate'] = time(); 193 | return $data; 194 | } 195 | 196 | /** 197 | * @return mixed 198 | * @throws InWidgetException 199 | */ 200 | private function getCache() 201 | { 202 | if ($this->config['cacheSkip'] === true) { 203 | return false; 204 | } 205 | $mtime = @filemtime($this->getCacheFilePath()); 206 | if ($mtime <= 0) { 207 | throw new InWidgetException( 208 | 'Can\'t get modification time of {$cacheFile}. Cache always be expired.', 209 | 102, 210 | $this->getCacheFilePath() 211 | ); 212 | } 213 | $cacheExpTime = $mtime + ($this->config['cacheExpiration'] * 60 * 60); 214 | if (time() > $cacheExpTime) { 215 | return false; 216 | } else { 217 | $rawData = file_get_contents($this->getCacheFilePath()); 218 | $cacheData = json_decode($rawData); 219 | if (!is_object($cacheData)) { 220 | return $rawData; 221 | } 222 | unset($rawData); 223 | } 224 | return $cacheData; 225 | } 226 | 227 | /** 228 | * @return mixed 229 | */ 230 | private function getBackup() 231 | { 232 | $file = $this->getCacheFilePath() . '_backup'; 233 | if (file_exists($file)) { 234 | $rawData = file_get_contents($file); 235 | $cacheData = json_decode($rawData); 236 | if (!is_object($cacheData)) { 237 | return $rawData; 238 | } else { 239 | return $cacheData; 240 | } 241 | } 242 | } 243 | 244 | /** 245 | * @return null 246 | */ 247 | private function createCache() 248 | { 249 | $data = json_encode($this->prepareData()); 250 | file_put_contents($this->getCacheFilePath(), $data, LOCK_EX); 251 | file_put_contents($this->getCacheFilePath() . '_backup', $data, LOCK_EX); 252 | } 253 | 254 | /** 255 | * @return string 256 | */ 257 | public function getCacheFilePath() 258 | { 259 | return $this->cachePath . '' . $this->cacheFile; 260 | } 261 | 262 | /** 263 | * Check important values and prepare to work 264 | * 265 | * @return null 266 | * @throws \Exception 267 | */ 268 | private function checkConfig() 269 | { 270 | if (!empty($this->config['skinAvailable'])) { 271 | $this->skinAvailable = $this->config['skinAvailable']; 272 | } 273 | if (!empty($this->config['langAvailable'])) { 274 | $this->langAvailable = $this->config['langAvailable']; 275 | } 276 | if (!empty($this->config['loginAvailable'])) { 277 | $this->loginAvailable = $this->config['loginAvailable']; 278 | } 279 | if (!empty($this->config['tagsAvailable'])) { 280 | $this->tagsAvailable = $this->config['tagsAvailable']; 281 | } 282 | if (empty($this->config['LOGIN'])) { 283 | throw new \Exception(__CLASS__ . ': LOGIN required in config.php'); 284 | } 285 | if (!in_array($this->config['langDefault'], $this->langAvailable, true)) { 286 | throw new \Exception(__CLASS__ . ': default language does not present in "langAvailable" config property'); 287 | } 288 | if (!in_array($this->config['skinDefault'], $this->skinAvailable, true)) { 289 | throw new \Exception(__CLASS__ . ': default skin does not present in "skinAvailable" config property'); 290 | } 291 | // prepare paths 292 | $this->langPath = __DIR__ . '/' . $this->langPath; // PHP < 5.6 fix 293 | $this->cachePath = __DIR__ . '/' . $this->cachePath; // PHP < 5.6 fix 294 | // prepare login 295 | if ($this->skipGET === false) { 296 | if (isset($_GET['login'])) { 297 | if (in_array($_GET['login'], $this->loginAvailable)) { 298 | $this->config['LOGIN'] = $_GET['login']; 299 | // login priority by default tags 300 | $this->config['HASHTAG'] = ""; 301 | } else { 302 | throw new \Exception(__CLASS__ . ': login does not present in "loginAvailable" config property'); 303 | } 304 | } 305 | } 306 | $this->config['LOGIN'] = strtolower(trim($this->config['LOGIN'])); 307 | $cacheFileName = md5($this->config['LOGIN']); 308 | // prepare hashtags 309 | if ($this->skipGET === false) { 310 | if (isset($_GET['tag'])) { 311 | if (in_array($_GET['tag'], $this->tagsAvailable)) { 312 | $this->config['HASHTAG'] = urldecode($_GET['tag']); 313 | } else { 314 | throw new \Exception(__CLASS__ . ': tag does not present in "tagsAvailable" config property'); 315 | } 316 | } 317 | } 318 | if (!empty($this->config['HASHTAG'])) { 319 | $this->config['HASHTAG'] = trim($this->config['HASHTAG']); 320 | $this->config['HASHTAG'] = str_replace('#', '', $this->config['HASHTAG']); 321 | $cacheFileName = md5($cacheFileName . $this->config['HASHTAG'] . '_tags'); 322 | } 323 | if (!empty($this->config['skinPath'])) { 324 | $this->skinPath = $this->config['skinPath']; 325 | } 326 | if (!empty($this->config['cachePath'])) { 327 | $this->cachePath = $this->config['cachePath']; 328 | } 329 | if (!empty($this->config['langPath'])) { 330 | $this->langPath = $this->config['langPath']; 331 | } 332 | $this->cacheFile = str_replace('{$fileName}', $cacheFileName, $this->cacheFile); 333 | if (!empty($this->config['tagsBannedLogins'])) { 334 | $logins = explode(',', $this->config['tagsBannedLogins']); 335 | if (!empty($logins)) { 336 | $this->config['tagsBannedLogins'] = []; 337 | foreach ($logins as $key => $item) { 338 | $item = strtolower(trim($item)); 339 | $this->config['tagsBannedLogins'][$key]['login'] = $item; 340 | } 341 | } 342 | } else { 343 | $this->config['tagsBannedLogins'] = []; 344 | } 345 | } 346 | 347 | /** 348 | * Let me know if cache file not writable 349 | * 350 | * @return null 351 | * @throws InWidgetException 352 | */ 353 | private function checkCacheRights() 354 | { 355 | $cacheFile = @fopen($this->getCacheFilePath(), 'a+b'); 356 | if (!is_resource($cacheFile)) { 357 | throw new InWidgetException( 358 | 'Can\'t get access to file {$cacheFile}. Check file path or permissions.', 359 | 101, 360 | $this->getCacheFilePath() 361 | ); 362 | } 363 | fclose($cacheFile); 364 | } 365 | 366 | /** 367 | * Set widget lang 368 | * New value must be present in langAvailable property necessary 369 | * 370 | * @param string $name [optional] 371 | * @return null 372 | */ 373 | public function setLang($name = '') 374 | { 375 | if (empty($name) and $this->config['langAuto'] === true and !empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { 376 | $name = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); 377 | } 378 | if (!empty($name) and in_array($name, $this->langAvailable, true)) { 379 | $name = strtolower($name); 380 | if (file_exists($this->langPath . $name . '.php')) { 381 | $this->langName = $name; 382 | require $this->langPath . $name . '.php'; 383 | } 384 | } 385 | if (empty($LANG)) { 386 | $this->langName = $this->config['langDefault']; 387 | require $this->langPath . $this->config['langDefault'] . '.php'; 388 | } 389 | $this->lang = $LANG; 390 | } 391 | 392 | /** 393 | * Set widget skin 394 | * New value must be present in skinAvailable property necessary 395 | * 396 | * @param string $name [optional] 397 | * @return null 398 | */ 399 | public function setSkin($name = '') 400 | { 401 | if (!empty($name) and in_array($name, $this->skinAvailable, true)) { 402 | $this->skinName = $name; 403 | } else { 404 | $this->skinName = $this->config['skinDefault']; 405 | } 406 | } 407 | 408 | /** 409 | * Set new values of properties through the $_GET 410 | * 411 | * @return null 412 | */ 413 | public function setOptions() 414 | { 415 | $this->width -= 2; 416 | if ($this->skipGET === false) { 417 | if (isset($_GET['width']) and (int)$_GET['width'] > 0) { 418 | $this->width = $_GET['width'] - 2; 419 | } 420 | if (isset($_GET['inline']) and (int)$_GET['inline'] > 0) { 421 | $this->inline = $_GET['inline']; 422 | } 423 | if (isset($_GET['view']) and (int)$_GET['view'] > 0) { 424 | $this->view = $_GET['view']; 425 | } 426 | if (isset($_GET['toolbar']) and $_GET['toolbar'] == 'false' or !empty($this->config['HASHTAG'])) { 427 | $this->toolbar = false; 428 | } 429 | if (isset($_GET['adaptive']) and $_GET['adaptive'] == 'true') { 430 | $this->adaptive = true; 431 | } 432 | if (isset($_GET['preview'])) { 433 | $this->preview = $_GET['preview']; 434 | } 435 | if (isset($_GET['lang'])) { 436 | $this->setLang($_GET['lang']); 437 | } 438 | if (isset($_GET['skin'])) { 439 | $this->setSkin($_GET['skin']); 440 | } 441 | } 442 | if ($this->width > 0) { 443 | $this->imgWidth = round(($this->width - (17 + (9 * $this->inline))) / $this->inline); 444 | } 445 | } 446 | 447 | /** 448 | * Let me know if this user was banned 449 | * 450 | * @param int $id 451 | * @return bool 452 | */ 453 | public function isBannedUserId($id) 454 | { 455 | if (!empty($this->data->banned)) { 456 | foreach ($this->data->banned as $key1 => $cacheValue) { 457 | if (!empty($cacheValue->id) and $cacheValue->id === $id) { 458 | if (!empty($this->config['tagsBannedLogins'])) { 459 | foreach ($this->config['tagsBannedLogins'] as $key2 => $configValue) { 460 | if ($configValue['login'] === $cacheValue->login) { 461 | return true; 462 | } 463 | } 464 | } 465 | } 466 | } 467 | } 468 | return false; 469 | } 470 | 471 | /** 472 | * Get number of images without images of banned users 473 | * 474 | * @param object $images 475 | * @return int 476 | */ 477 | public function countAvailableImages($images) 478 | { 479 | $count = 0; 480 | if (!empty($images)) { 481 | foreach ($images as $key => $item) { 482 | if ($this->isBannedUserId($item->authorId) == true) { 483 | continue; 484 | } 485 | $count++; 486 | } 487 | } 488 | return $count; 489 | } 490 | } 491 | -------------------------------------------------------------------------------- /classes/InWidget/Exception/InWidgetException.php: -------------------------------------------------------------------------------- 1 | ERROR #' . $code . ': ' . $text; 27 | if ($code >= 401) { 28 | file_put_contents($cacheFile, $result, LOCK_EX); 29 | } 30 | \Exception::__construct($result, $code); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /classes/InstagramScraper.php: -------------------------------------------------------------------------------- 1 | json_encode([])]); 196 | return $url; 197 | } 198 | 199 | public static function getStoriesLink($variables) 200 | { 201 | $url = self::getGraphQlUrl(InstagramQueryId::STORIES, ['variables' => json_encode($variables)]); 202 | return $url; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /classes/InstagramScraper/Exception/InstagramAuthException.php: -------------------------------------------------------------------------------- 1 | isLoaded; 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | public function getUsername() 100 | { 101 | return $this->username; 102 | } 103 | 104 | /** 105 | * @return int 106 | */ 107 | public function getId() 108 | { 109 | if (PHP_INT_SIZE > 4) { 110 | $this->id = (int)$this->id; 111 | } 112 | 113 | return $this->id; 114 | } 115 | 116 | /** 117 | * @return string 118 | */ 119 | public function getFullName() 120 | { 121 | return $this->fullName; 122 | } 123 | 124 | /** 125 | * @return string 126 | */ 127 | public function getProfilePicUrl() 128 | { 129 | return $this->profilePicUrl; 130 | } 131 | 132 | /** 133 | * @return string 134 | */ 135 | public function getProfilePicUrlHd() 136 | { 137 | $toReturn = $this->profilePicUrl; 138 | 139 | if ($this->profilePicUrlHd !== '') { 140 | $toReturn = $this->profilePicUrlHd; 141 | } 142 | 143 | return $toReturn; 144 | } 145 | 146 | /** 147 | * @return string 148 | */ 149 | public function getBiography() 150 | { 151 | return $this->biography; 152 | } 153 | 154 | /** 155 | * @return string 156 | */ 157 | public function getExternalUrl() 158 | { 159 | return $this->externalUrl; 160 | } 161 | 162 | /** 163 | * @return int 164 | */ 165 | public function getFollowsCount() 166 | { 167 | return $this->followsCount; 168 | } 169 | 170 | /** 171 | * @return int 172 | */ 173 | public function getFollowedByCount() 174 | { 175 | return $this->followedByCount; 176 | } 177 | 178 | /** 179 | * @return int 180 | */ 181 | public function getMediaCount() 182 | { 183 | return $this->mediaCount; 184 | } 185 | 186 | /** 187 | * @return bool 188 | */ 189 | public function isPrivate() 190 | { 191 | return $this->isPrivate; 192 | } 193 | 194 | /** 195 | * @return bool 196 | */ 197 | public function isVerified() 198 | { 199 | return $this->isVerified; 200 | } 201 | 202 | /** 203 | * @param $value 204 | * @param $prop 205 | * @param $array 206 | */ 207 | protected function initPropertiesCustom($value, $prop, $array) 208 | { 209 | switch ($prop) { 210 | case 'id': 211 | case 'pk': 212 | $this->id = $value; 213 | break; 214 | case 'username': 215 | $this->username = $value; 216 | break; 217 | case 'full_name': 218 | $this->fullName = $value; 219 | break; 220 | case 'profile_pic_url': 221 | $this->profilePicUrl = $value; 222 | break; 223 | case 'profile_pic_url_hd': 224 | $this->profilePicUrlHd = $value; 225 | break; 226 | case 'biography': 227 | $this->biography = $value; 228 | break; 229 | case 'external_url': 230 | $this->externalUrl = $value; 231 | break; 232 | case 'edge_follow': 233 | $this->followsCount = !empty($array[$prop]['count']) ? (int)$array[$prop]['count'] : 0; 234 | break; 235 | case 'edge_followed_by': 236 | $this->followedByCount = !empty($array[$prop]['count']) ? (int)$array[$prop]['count'] : 0; 237 | break; 238 | case 'edge_owner_to_timeline_media': 239 | $this->mediaCount = !empty($array[$prop]['count']) ? $array[$prop]['count'] : 0; 240 | break; 241 | case 'mediaCount': 242 | $this->mediaCount = $value; 243 | break; 244 | case 'followsCount': 245 | $this->followsCount = $value; 246 | break; 247 | case 'followedByCount': 248 | $this->followedByCount = $value; 249 | break; 250 | case 'is_private': 251 | $this->isPrivate = (bool)$value; 252 | break; 253 | case 'is_verified': 254 | $this->isVerified = (bool)$value; 255 | break; 256 | } 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/CarouselMedia.php: -------------------------------------------------------------------------------- 1 | type; 70 | } 71 | 72 | /** 73 | * @param mixed $type 74 | * 75 | * @return $this 76 | */ 77 | public function setType($type) 78 | { 79 | $this->type = $type; 80 | return $this; 81 | } 82 | 83 | /** 84 | * @return mixed 85 | */ 86 | public function getImageLowResolutionUrl() 87 | { 88 | return $this->imageLowResolutionUrl; 89 | } 90 | 91 | /** 92 | * @param mixed $imageLowResolutionUrl 93 | * 94 | * @return CarouselMedia 95 | */ 96 | public function setImageLowResolutionUrl($imageLowResolutionUrl) 97 | { 98 | $this->imageLowResolutionUrl = $imageLowResolutionUrl; 99 | return $this; 100 | } 101 | 102 | /** 103 | * @return mixed 104 | */ 105 | public function getImageThumbnailUrl() 106 | { 107 | return $this->imageThumbnailUrl; 108 | } 109 | 110 | /** 111 | * @param mixed $imageThumbnailUrl 112 | * 113 | * @return CarouselMedia 114 | */ 115 | public function setImageThumbnailUrl($imageThumbnailUrl) 116 | { 117 | $this->imageThumbnailUrl = $imageThumbnailUrl; 118 | return $this; 119 | } 120 | 121 | /** 122 | * @return mixed 123 | */ 124 | public function getImageStandardResolutionUrl() 125 | { 126 | return $this->imageStandardResolutionUrl; 127 | } 128 | 129 | /** 130 | * @param mixed $imageStandardResolutionUrl 131 | * 132 | * @return CarouselMedia 133 | */ 134 | public function setImageStandardResolutionUrl($imageStandardResolutionUrl) 135 | { 136 | $this->imageStandardResolutionUrl = $imageStandardResolutionUrl; 137 | return $this; 138 | } 139 | 140 | /** 141 | * @return mixed 142 | */ 143 | public function getImageHighResolutionUrl() 144 | { 145 | return $this->imageHighResolutionUrl; 146 | } 147 | 148 | /** 149 | * @param mixed $imageHighResolutionUrl 150 | * 151 | * @return CarouselMedia 152 | */ 153 | public function setImageHighResolutionUrl($imageHighResolutionUrl) 154 | { 155 | $this->imageHighResolutionUrl = $imageHighResolutionUrl; 156 | return $this; 157 | } 158 | 159 | /** 160 | * @return mixed 161 | */ 162 | public function getVideoLowResolutionUrl() 163 | { 164 | return $this->videoLowResolutionUrl; 165 | } 166 | 167 | /** 168 | * @param mixed $videoLowResolutionUrl 169 | * 170 | * @return CarouselMedia 171 | */ 172 | public function setVideoLowResolutionUrl($videoLowResolutionUrl) 173 | { 174 | $this->videoLowResolutionUrl = $videoLowResolutionUrl; 175 | return $this; 176 | } 177 | 178 | /** 179 | * @return mixed 180 | */ 181 | public function getVideoStandardResolutionUrl() 182 | { 183 | return $this->videoStandardResolutionUrl; 184 | } 185 | 186 | /** 187 | * @param mixed $videoStandardResolutionUrl 188 | * 189 | * @return CarouselMedia 190 | */ 191 | public function setVideoStandardResolutionUrl($videoStandardResolutionUrl) 192 | { 193 | $this->videoStandardResolutionUrl = $videoStandardResolutionUrl; 194 | return $this; 195 | } 196 | 197 | /** 198 | * @return mixed 199 | */ 200 | public function getVideoLowBandwidthUrl() 201 | { 202 | return $this->videoLowBandwidthUrl; 203 | } 204 | 205 | /** 206 | * @param mixed $videoLowBandwidthUrl 207 | * 208 | * @return CarouselMedia 209 | */ 210 | public function setVideoLowBandwidthUrl($videoLowBandwidthUrl) 211 | { 212 | $this->videoLowBandwidthUrl = $videoLowBandwidthUrl; 213 | return $this; 214 | } 215 | 216 | /** 217 | * @return mixed 218 | */ 219 | public function getVideoViews() 220 | { 221 | return $this->videoViews; 222 | } 223 | 224 | /** 225 | * @param mixed $videoViews 226 | * 227 | * @return CarouselMedia 228 | */ 229 | public function setVideoViews($videoViews) 230 | { 231 | $this->videoViews = $videoViews; 232 | return $this; 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/Comment.php: -------------------------------------------------------------------------------- 1 | id; 39 | } 40 | 41 | /** 42 | * @return mixed 43 | */ 44 | public function getText() 45 | { 46 | return $this->text; 47 | } 48 | 49 | /** 50 | * @return mixed 51 | */ 52 | public function getCreatedAt() 53 | { 54 | return $this->createdAt; 55 | } 56 | 57 | /** 58 | * @return Account 59 | */ 60 | public function getOwner() 61 | { 62 | return $this->owner; 63 | } 64 | 65 | /** 66 | * @param $value 67 | * @param $prop 68 | */ 69 | protected function initPropertiesCustom($value, $prop) 70 | { 71 | switch ($prop) { 72 | case 'id': 73 | $this->id = $value; 74 | break; 75 | case 'created_at': 76 | $this->createdAt = $value; 77 | break; 78 | case 'text': 79 | $this->text = $value; 80 | break; 81 | case 'owner': 82 | $this->owner = Account::create($value); 83 | break; 84 | } 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/Like.php: -------------------------------------------------------------------------------- 1 | id; 24 | } 25 | 26 | /** 27 | * @return mixed 28 | */ 29 | public function getUserName() 30 | { 31 | return $this->username; 32 | } 33 | 34 | /** 35 | * @param $value 36 | * @param $prop 37 | */ 38 | protected function initPropertiesCustom($value, $prop) 39 | { 40 | switch ($prop) { 41 | case 'id': 42 | $this->id = $value; 43 | break; 44 | case 'username': 45 | $this->username = $value; 46 | break; 47 | } 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/Location.php: -------------------------------------------------------------------------------- 1 | 'id', 13 | 'has_public_page' => 'hasPublicPage', 14 | 'name' => 'name', 15 | 'slug' => 'slug', 16 | 'lat' => 'lat', 17 | 'lng' => 'lng', 18 | 'modified' => 'modified' 19 | ]; 20 | /** 21 | * @var 22 | */ 23 | protected $id; 24 | /** 25 | * @var 26 | */ 27 | protected $hasPublicPage; 28 | /** 29 | * @var 30 | */ 31 | protected $name; 32 | /** 33 | * @var 34 | */ 35 | protected $slug; 36 | /** 37 | * @var 38 | */ 39 | protected $lng; 40 | /** 41 | * @var 42 | */ 43 | protected $lat; 44 | /** 45 | * @var bool 46 | */ 47 | protected $isLoaded = false; 48 | 49 | /** 50 | * @var 51 | */ 52 | protected $modified; 53 | 54 | /** 55 | * @return mixed 56 | */ 57 | public function getId() 58 | { 59 | return $this->id; 60 | } 61 | 62 | /** 63 | * @return mixed 64 | */ 65 | public function getHasPublicPage() 66 | { 67 | return $this->hasPublicPage; 68 | } 69 | 70 | /** 71 | * @return mixed 72 | */ 73 | public function getName() 74 | { 75 | return $this->name; 76 | } 77 | 78 | /** 79 | * @return mixed 80 | */ 81 | public function getSlug() 82 | { 83 | return $this->slug; 84 | } 85 | 86 | /** 87 | * @return mixed 88 | */ 89 | public function getLng() 90 | { 91 | return $this->lng; 92 | } 93 | 94 | /** 95 | * @return mixed 96 | */ 97 | public function getLat() 98 | { 99 | return $this->lat; 100 | } 101 | 102 | /** 103 | * @return mixed 104 | */ 105 | public function getModified() 106 | { 107 | return $this->modified; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/Story.php: -------------------------------------------------------------------------------- 1 | true, 13 | ]; 14 | 15 | /*** 16 | * We do not need some values - do not parse it for Story, 17 | * for example - we do not need owner object inside story 18 | * 19 | * @param $value 20 | * @param $prop 21 | * @param $arr 22 | */ 23 | protected function initPropertiesCustom($value, $prop, $arr) 24 | { 25 | if (!empty($this->skip_prop[$prop])) { 26 | return; 27 | } 28 | parent::initPropertiesCustom($value, $prop, $arr); 29 | } 30 | } -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/Tag.php: -------------------------------------------------------------------------------- 1 | 'mediaCount', 16 | 'name' => 'name', 17 | 'id' => 'initInt', 18 | ]; 19 | /** 20 | * @var int 21 | */ 22 | protected $mediaCount = 0; 23 | /** 24 | * @var string 25 | */ 26 | protected $name; 27 | /** 28 | * @var int 29 | */ 30 | protected $id; 31 | 32 | /** 33 | * @return int 34 | */ 35 | public function getMediaCount() 36 | { 37 | return $this->mediaCount; 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getName() 44 | { 45 | return $this->name; 46 | } 47 | 48 | /** 49 | * @return int 50 | */ 51 | public function getId() 52 | { 53 | return $this->id; 54 | } 55 | } -------------------------------------------------------------------------------- /classes/InstagramScraper/Model/UserStories.php: -------------------------------------------------------------------------------- 1 | owner = $owner; 20 | } 21 | 22 | public function getOwner() 23 | { 24 | return $this->owner; 25 | } 26 | 27 | public function addStory($story) 28 | { 29 | $this->stories[] = $story; 30 | } 31 | 32 | public function setStories($stories) 33 | { 34 | $this->stories = $stories; 35 | } 36 | 37 | public function getStories() 38 | { 39 | return $this->stories; 40 | } 41 | } -------------------------------------------------------------------------------- /classes/InstagramScraper/Traits/ArrayLikeTrait.php: -------------------------------------------------------------------------------- 1 | isMethod($offset, 'get') || \property_exists($this, $offset); 27 | } 28 | 29 | /** 30 | * @param mixed $offset 31 | * 32 | * @return mixed 33 | */ 34 | public function offsetGet($offset) 35 | { 36 | if ($run = $this->isMethod($offset, 'get')) { 37 | return $this->run($run); 38 | } elseif (\property_exists($this, $offset)) { 39 | if (isset($this->{$offset})) { 40 | return $this->{$offset}; 41 | } elseif (isset($this::$offset)) { 42 | return $this::$offset; 43 | } 44 | } 45 | 46 | return null; 47 | } 48 | 49 | /** 50 | * @param mixed $offset 51 | * @param mixed $value 52 | * 53 | * @return void 54 | */ 55 | public function offsetSet($offset, $value) 56 | { 57 | if ($run = $this->isMethod($offset, 'set')) { 58 | $this->run($run); 59 | } else { 60 | $this->{$offset} = $value; 61 | } 62 | } 63 | 64 | /** 65 | * @param mixed $offset 66 | * 67 | * @return void 68 | */ 69 | public function offsetUnset($offset) 70 | { 71 | if ($run = $this->isMethod($offset, 'unset')) { 72 | $this->run($run); 73 | } else { 74 | $this->{$offset} = null; 75 | } 76 | } 77 | 78 | /** 79 | * @param $method 80 | * @param $case 81 | * 82 | * @return bool|string 83 | */ 84 | protected function isMethod($method, $case) 85 | { 86 | $uMethod = $case . \ucfirst($method); 87 | if (\method_exists($this, $uMethod)) { 88 | return $uMethod; 89 | } 90 | if (\method_exists($this, $method)) { 91 | return $method; 92 | } 93 | return false; 94 | } 95 | 96 | /** 97 | * @param $method 98 | * 99 | * @return mixed 100 | */ 101 | protected function run($method) 102 | { 103 | if (\is_array($method)) { 104 | $params = $method; 105 | $method = \array_shift($params); 106 | if ($params) { 107 | return \call_user_func_array([$this, $method], $params); 108 | } 109 | } 110 | return \call_user_func([$this, $method]); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /classes/InstagramScraper/Traits/InitializerTrait.php: -------------------------------------------------------------------------------- 1 | beforeInit(); 59 | $this->modified = \time(); 60 | if ($this->isAutoConstruct) { 61 | $this->initAuto(); 62 | } elseif (empty($props)) { 63 | $this->initDefaults(); 64 | } else { 65 | $this->init($props); 66 | } 67 | $this->afterInit(); 68 | } 69 | 70 | /** 71 | * @return $this 72 | */ 73 | protected function beforeInit() 74 | { 75 | return $this; 76 | } 77 | 78 | /** 79 | * @return $this 80 | */ 81 | final protected function initAuto() 82 | { 83 | foreach ($this as $prop => $value) { 84 | if (isset(static::$initPropertiesMap[$prop]) and $methodOrProp = static::$initPropertiesMap[$prop] and \method_exists($this, 85 | $methodOrProp) 86 | ) { 87 | //if there is method then use it firstly 88 | \call_user_func([$this, $methodOrProp], $value, $prop); 89 | } 90 | } 91 | $this->isNew = false; 92 | $this->isLoaded = true; 93 | $this->isLoadEmpty = false; 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * @return $this 100 | */ 101 | protected function initDefaults() 102 | { 103 | return $this; 104 | } 105 | 106 | /** 107 | * @param array $props 108 | * 109 | * @return $this 110 | */ 111 | final protected function init(array $props) 112 | { 113 | //?reflection? 114 | foreach ($props as $prop => $value) { 115 | if (\method_exists($this, 'initPropertiesCustom')) { 116 | \call_user_func([$this, 'initPropertiesCustom'], $value, $prop, $props); 117 | } elseif (isset(static::$initPropertiesMap[$prop])) { 118 | $methodOrProp = static::$initPropertiesMap[$prop]; 119 | if (\method_exists($this, $methodOrProp)) { 120 | //if there is method then use it firstly 121 | \call_user_func([$this, $methodOrProp], $value, $prop, $props); 122 | } elseif (\property_exists($this, $methodOrProp)) { 123 | //if there is property then it just assign value 124 | $this->{$methodOrProp} = $value; 125 | } else { 126 | //otherwise fill help data array 127 | //for following initialization 128 | $this->data[$methodOrProp] = $value; 129 | $this->data[$prop] = $value; 130 | } 131 | } else { 132 | //otherwise fill help data array 133 | $this->data[$prop] = $value; 134 | } 135 | } 136 | $this->isNew = false; 137 | $this->isLoaded = true; 138 | $this->isLoadEmpty = false; 139 | 140 | return $this; 141 | } 142 | 143 | /** 144 | * @return $this 145 | */ 146 | protected function afterInit() 147 | { 148 | return $this; 149 | } 150 | 151 | /** 152 | * @return $this 153 | */ 154 | public static function fake() 155 | { 156 | return static::create()->setFake(true); 157 | } 158 | 159 | /** 160 | * @param bool $value 161 | * 162 | * @return $this 163 | */ 164 | protected function setFake($value = true) 165 | { 166 | $this->isFake = (bool)$value; 167 | 168 | return $this; 169 | } 170 | 171 | /** 172 | * @param array $params 173 | * 174 | * @return static 175 | */ 176 | public static function create(array $params = null) 177 | { 178 | return new static($params); 179 | } 180 | 181 | /** 182 | * @return bool 183 | */ 184 | public function isNotEmpty() 185 | { 186 | return !$this->isLoadEmpty; 187 | } 188 | 189 | /** 190 | * @return bool 191 | */ 192 | public function isFake() 193 | { 194 | return $this->isFake; 195 | } 196 | 197 | /** 198 | * @return array 199 | */ 200 | public function toArray() 201 | { 202 | $ret = []; 203 | $map = static::$initPropertiesMap; 204 | foreach ($map as $key => $init) { 205 | if (\property_exists($this, $key)) { 206 | //if there is property then it just assign value 207 | $ret[$key] = $this->{$key}; 208 | } elseif (isset($this[$key])) { 209 | //probably array access 210 | $ret[$key] = $this[$key]; 211 | } else { 212 | $ret[$key] = null; 213 | } 214 | } 215 | 216 | return $ret; 217 | } 218 | 219 | /** 220 | * @param $datetime 221 | * 222 | * @return $this 223 | */ 224 | protected function initModified($datetime) 225 | { 226 | $this->modified = \strtotime($datetime); 227 | 228 | return $this; 229 | } 230 | 231 | /** 232 | * @param string $date 233 | * @param string $key 234 | * 235 | * @return $this 236 | */ 237 | protected function initDatetime($date, $key) 238 | { 239 | return $this->initProperty(\strtotime($date), $key); 240 | } 241 | 242 | /** 243 | * @param $value 244 | * @param $key 245 | * 246 | * @return $this 247 | */ 248 | protected function initProperty($value, $key) 249 | { 250 | $keys = \func_get_args(); 251 | unset($keys[0]); //remove value 252 | if (\count($keys) > 1) { 253 | foreach ($keys as $key) { 254 | if (\property_exists($this, $key)) { //first found set 255 | $this->{$key} = $value; 256 | 257 | return $this; 258 | } 259 | } 260 | } elseif (\property_exists($this, $key)) { 261 | $this->{$key} = $value; 262 | } 263 | 264 | return $this; 265 | } 266 | 267 | /** 268 | * @param mixed $value 269 | * @param string $key 270 | * 271 | * @return $this 272 | */ 273 | protected function initBool($value, $key) 274 | { 275 | return $this->initProperty(!empty($value), "is{$key}", $key); 276 | } 277 | 278 | /** 279 | * @param mixed $value 280 | * @param string $key 281 | * 282 | * @return $this 283 | */ 284 | protected function initInt($value, $key) 285 | { 286 | return $this->initProperty((int)$value, $key); 287 | } 288 | 289 | /** 290 | * @param mixed $value 291 | * @param string $key 292 | * 293 | * @return $this 294 | */ 295 | protected function initFloat($value, $key) 296 | { 297 | return $this->initProperty((float)$value, $key); 298 | } 299 | 300 | /** 301 | * @param string $rawData 302 | * @param string $key 303 | * 304 | * @return $this 305 | */ 306 | protected function initJsonArray($rawData, $key) 307 | { 308 | $value = \json_decode($rawData, true, 512, JSON_BIGINT_AS_STRING); 309 | if (empty($value)) { 310 | //could not resolve - 311 | if ('null' === $rawData or '' === $rawData) { 312 | $value = []; 313 | } else { 314 | $value = (array)$rawData; 315 | } 316 | } else { 317 | $value = (array)$value; 318 | } 319 | 320 | return $this->initProperty($value, $key); 321 | } 322 | 323 | /** 324 | * @param mixed $value 325 | * @param string $key 326 | * 327 | * @return $this 328 | */ 329 | protected function initExplode($value, $key) 330 | { 331 | return $this->initProperty(\explode(',', $value), "is{$key}", $key); 332 | } 333 | 334 | } -------------------------------------------------------------------------------- /classes/Unirest.php: -------------------------------------------------------------------------------- 1 | 'application/json'); 87 | $query = array('foo' => 'hello', 'bar' => 'world'); 88 | 89 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $query); 90 | 91 | $response->code; // HTTP Status code 92 | $response->headers; // Headers 93 | $response->body; // Parsed body 94 | $response->raw_body; // Unparsed body 95 | ``` 96 | 97 | ### JSON Requests *(`application/json`)* 98 | 99 | A JSON Request can be constructed using the `Unirest\Request\Body::Json` helper: 100 | 101 | ```php 102 | $headers = array('Accept' => 'application/json'); 103 | $data = array('name' => 'ahmad', 'company' => 'mashape'); 104 | 105 | $body = Unirest\Request\Body::json($data); 106 | 107 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 108 | ``` 109 | 110 | **Notes:** 111 | - `Content-Type` headers will be automatically set to `application/json` 112 | - the data variable will be processed through [`json_encode`](http://php.net/manual/en/function.json-encode.php) with default values for arguments. 113 | - an error will be thrown if the [JSON Extension](http://php.net/manual/en/book.json.php) is not available. 114 | 115 | ### Form Requests *(`application/x-www-form-urlencoded`)* 116 | 117 | A typical Form Request can be constructed using the `Unirest\Request\Body::Form` helper: 118 | 119 | ```php 120 | $headers = array('Accept' => 'application/json'); 121 | $data = array('name' => 'ahmad', 'company' => 'mashape'); 122 | 123 | $body = Unirest\Request\Body::form($data); 124 | 125 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 126 | ``` 127 | 128 | **Notes:** 129 | - `Content-Type` headers will be automatically set to `application/x-www-form-urlencoded` 130 | - the final data array will be processed through [`http_build_query`](http://php.net/manual/en/function.http-build-query.php) with default values for arguments. 131 | 132 | ### Multipart Requests *(`multipart/form-data`)* 133 | 134 | A Multipart Request can be constructed using the `Unirest\Request\Body::Multipart` helper: 135 | 136 | ```php 137 | $headers = array('Accept' => 'application/json'); 138 | $data = array('name' => 'ahmad', 'company' => 'mashape'); 139 | 140 | $body = Unirest\Request\Body::multipart($data); 141 | 142 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 143 | ``` 144 | 145 | **Notes:** 146 | 147 | - `Content-Type` headers will be automatically set to `multipart/form-data`. 148 | - an auto-generated `--boundary` will be set. 149 | 150 | ### Multipart File Upload 151 | 152 | simply add an array of files as the second argument to to the `Multipart` helper: 153 | 154 | ```php 155 | $headers = array('Accept' => 'application/json'); 156 | $data = array('name' => 'ahmad', 'company' => 'mashape'); 157 | $files = array('bio' => '/path/to/bio.txt', 'avatar' => '/path/to/avatar.jpg'); 158 | 159 | $body = Unirest\Request\Body::multipart($data, $files); 160 | 161 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 162 | ``` 163 | 164 | If you wish to further customize the properties of files uploaded you can do so with the `Unirest\Request\Body::File` helper: 165 | 166 | ```php 167 | $headers = array('Accept' => 'application/json'); 168 | $body = array( 169 | 'name' => 'ahmad', 170 | 'company' => 'mashape' 171 | 'bio' => Unirest\Request\Body::file('/path/to/bio.txt', 'text/plain'), 172 | 'avatar' => Unirest\Request\Body::file('/path/to/my_avatar.jpg', 'text/plain', 'avatar.jpg') 173 | ); 174 | 175 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 176 | ``` 177 | 178 | **Note**: we did not use the `Unirest\Request\Body::multipart` helper in this example, it is not needed when manually adding files. 179 | 180 | ### Custom Body 181 | 182 | Sending a custom body such rather than using the `Unirest\Request\Body` helpers is also possible, for example, using a [`serialize`](http://php.net/manual/en/function.serialize.php) body string with a custom `Content-Type`: 183 | 184 | ```php 185 | $headers = array('Accept' => 'application/json', 'Content-Type' => 'application/x-php-serialized'); 186 | $body = serialize((array('foo' => 'hello', 'bar' => 'world')); 187 | 188 | $response = Unirest\Request::post('http://mockbin.com/request', $headers, $body); 189 | ``` 190 | 191 | ### Authentication 192 | 193 | First, if you are using [Mashape][mashape-url]: 194 | ```php 195 | // Mashape auth 196 | Unirest\Request::setMashapeKey(''); 197 | ``` 198 | 199 | Otherwise, passing a username, password *(optional)*, defaults to Basic Authentication: 200 | 201 | ```php 202 | // basic auth 203 | Unirest\Request::auth('username', 'password'); 204 | ``` 205 | 206 | The third parameter, which is a bitmask, will Unirest which HTTP authentication method(s) you want it to use for your proxy authentication. 207 | 208 | If more than one bit is set, Unirest *(at PHP's libcurl level)* will first query the site to see what authentication methods it supports and then pick the best one you allow it to use. *For some methods, this will induce an extra network round-trip.* 209 | 210 | **Supported Methods** 211 | 212 | | Method | Description | 213 | | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 214 | | `CURLAUTH_BASIC` | HTTP Basic authentication. This is the default choice | 215 | | `CURLAUTH_DIGEST` | HTTP Digest authentication. as defined in [RFC 2617](http://www.ietf.org/rfc/rfc2617.txt) | 216 | | `CURLAUTH_DIGEST_IE` | HTTP Digest authentication with an IE flavor. *The IE flavor is simply that libcurl will use a special "quirk" that IE is known to have used before version 7 and that some servers require the client to use.* | 217 | | `CURLAUTH_NEGOTIATE` | HTTP Negotiate (SPNEGO) authentication. as defined in [RFC 4559](http://www.ietf.org/rfc/rfc4559.txt) | 218 | | `CURLAUTH_NTLM` | HTTP NTLM authentication. A proprietary protocol invented and used by Microsoft. | 219 | | `CURLAUTH_NTLM_WB` | NTLM delegating to winbind helper. Authentication is performed by a separate binary application. *see [libcurl docs](http://curl.haxx.se/libcurl/c/CURLOPT_HTTPAUTH.html) for more info* | 220 | | `CURLAUTH_ANY` | This is a convenience macro that sets all bits and thus makes libcurl pick any it finds suitable. libcurl will automatically select the one it finds most secure. | 221 | | `CURLAUTH_ANYSAFE` | This is a convenience macro that sets all bits except Basic and thus makes libcurl pick any it finds suitable. libcurl will automatically select the one it finds most secure. | 222 | | `CURLAUTH_ONLY` | This is a meta symbol. OR this value together with a single specific auth value to force libcurl to probe for un-restricted auth and if not, only that single auth algorithm is acceptable. | 223 | 224 | ```php 225 | // custom auth method 226 | Unirest\Request::proxyAuth('username', 'password', CURLAUTH_DIGEST); 227 | ``` 228 | 229 | Previous versions of **Unirest** support *Basic Authentication* by providing the `username` and `password` arguments: 230 | 231 | ```php 232 | $response = Unirest\Request::get('http://mockbin.com/request', null, null, 'username', 'password'); 233 | ``` 234 | 235 | **This has been deprecated, and will be completely removed in `v.3.0.0` please use the `Unirest\Request::auth()` method instead** 236 | 237 | ### Cookies 238 | 239 | Set a cookie string to specify the contents of a cookie header. Multiple cookies are separated with a semicolon followed by a space (e.g., "fruit=apple; colour=red") 240 | 241 | ```php 242 | Unirest\Request::cookie($cookie) 243 | ``` 244 | 245 | Set a cookie file path for enabling cookie reading and storing cookies across multiple sequence of requests. 246 | 247 | ```php 248 | Unirest\Request::cookieFile($cookieFile) 249 | ``` 250 | 251 | `$cookieFile` must be a correct path with write permission. 252 | 253 | ### Request Object 254 | 255 | ```php 256 | Unirest\Request::get($url, $headers = array(), $parameters = null) 257 | Unirest\Request::post($url, $headers = array(), $body = null) 258 | Unirest\Request::put($url, $headers = array(), $body = null) 259 | Unirest\Request::patch($url, $headers = array(), $body = null) 260 | Unirest\Request::delete($url, $headers = array(), $body = null) 261 | ``` 262 | 263 | - `url` - Endpoint, address, or uri to be acted upon and requested information from. 264 | - `headers` - Request Headers as associative array or object 265 | - `body` - Request Body as associative array or object 266 | 267 | You can send a request with any [standard](http://www.iana.org/assignments/http-methods/http-methods.xhtml) or custom HTTP Method: 268 | 269 | ```php 270 | Unirest\Request::send(Unirest\Method::LINK, $url, $headers = array(), $body); 271 | 272 | Unirest\Request::send('CHECKOUT', $url, $headers = array(), $body); 273 | ``` 274 | 275 | ### Response Object 276 | 277 | Upon recieving a response Unirest returns the result in the form of an Object, this object should always have the same keys for each language regarding to the response details. 278 | 279 | - `code` - HTTP Response Status Code (Example `200`) 280 | - `headers` - HTTP Response Headers 281 | - `body` - Parsed response body where applicable, for example JSON responses are parsed to Objects / Associative Arrays. 282 | - `raw_body` - Un-parsed response body 283 | 284 | ### Advanced Configuration 285 | 286 | You can set some advanced configuration to tune Unirest-PHP: 287 | 288 | #### Custom JSON Decode Flags 289 | 290 | Unirest uses PHP's [JSON Extension](http://php.net/manual/en/book.json.php) for automatically decoding JSON responses. 291 | sometime you may want to return associative arrays, limit the depth of recursion, or use any of the [customization flags](http://php.net/manual/en/json.constants.php). 292 | 293 | To do so, simply set the desired options using the `jsonOpts` request method: 294 | 295 | ```php 296 | Unirest\Request::jsonOpts(true, 512, JSON_NUMERIC_CHECK & JSON_FORCE_OBJECT & JSON_UNESCAPED_SLASHES); 297 | ``` 298 | 299 | #### Timeout 300 | 301 | You can set a custom timeout value (in **seconds**): 302 | 303 | ```php 304 | Unirest\Request::timeout(5); // 5s timeout 305 | ``` 306 | 307 | #### Proxy 308 | 309 | Set the proxy to use for the upcoming request. 310 | 311 | you can also set the proxy type to be one of `CURLPROXY_HTTP`, `CURLPROXY_HTTP_1_0`, `CURLPROXY_SOCKS4`, `CURLPROXY_SOCKS5`, `CURLPROXY_SOCKS4A`, and `CURLPROXY_SOCKS5_HOSTNAME`. 312 | 313 | *check the [cURL docs](http://curl.haxx.se/libcurl/c/CURLOPT_PROXYTYPE.html) for more info*. 314 | 315 | ```php 316 | // quick setup with default port: 1080 317 | Unirest\Request::proxy('10.10.10.1'); 318 | 319 | // custom port and proxy type 320 | Unirest\Request::proxy('10.10.10.1', 8080, CURLPROXY_HTTP); 321 | 322 | // enable tunneling 323 | Unirest\Request::proxy('10.10.10.1', 8080, CURLPROXY_HTTP, true); 324 | ``` 325 | 326 | ##### Proxy Authenticaton 327 | 328 | Passing a username, password *(optional)*, defaults to Basic Authentication: 329 | 330 | ```php 331 | // basic auth 332 | Unirest\Request::proxyAuth('username', 'password'); 333 | ``` 334 | 335 | The third parameter, which is a bitmask, will Unirest which HTTP authentication method(s) you want it to use for your proxy authentication. 336 | 337 | If more than one bit is set, Unirest *(at PHP's libcurl level)* will first query the site to see what authentication methods it supports and then pick the best one you allow it to use. *For some methods, this will induce an extra network round-trip.* 338 | 339 | See [Authentication](#authentication) for more details on methods supported. 340 | 341 | ```php 342 | // basic auth 343 | Unirest\Request::proxyAuth('username', 'password', CURLAUTH_DIGEST); 344 | ``` 345 | 346 | #### Default Request Headers 347 | 348 | You can set default headers that will be sent on every request: 349 | 350 | ```php 351 | Unirest\Request::defaultHeader('Header1', 'Value1'); 352 | Unirest\Request::defaultHeader('Header2', 'Value2'); 353 | ``` 354 | 355 | You can set default headers in bulk by passing an array: 356 | 357 | ```php 358 | Unirest\Request::defaultHeaders(array( 359 | 'Header1' => 'Value1', 360 | 'Header2' => 'Value2' 361 | )); 362 | ``` 363 | 364 | You can clear the default headers anytime with: 365 | 366 | ```php 367 | Unirest\Request::clearDefaultHeaders(); 368 | ``` 369 | 370 | #### Default cURL Options 371 | 372 | You can set default [cURL options](http://php.net/manual/en/function.curl-setopt.php) that will be sent on every request: 373 | 374 | ```php 375 | Unirest\Request::curlOpt(CURLOPT_COOKIE, 'foo=bar'); 376 | ``` 377 | 378 | You can set options bulk by passing an array: 379 | 380 | ```php 381 | Unirest\Request::curlOpts(array( 382 | CURLOPT_COOKIE => 'foo=bar' 383 | )); 384 | ``` 385 | 386 | You can clear the default options anytime with: 387 | 388 | ```php 389 | Unirest\Request::clearCurlOpts(); 390 | ``` 391 | 392 | #### SSL validation 393 | 394 | You can explicitly enable or disable SSL certificate validation when consuming an SSL protected endpoint: 395 | 396 | ```php 397 | Unirest\Request::verifyPeer(false); // Disables SSL cert validation 398 | ``` 399 | 400 | By default is `true`. 401 | 402 | #### Utility Methods 403 | 404 | ```php 405 | // alias for `curl_getinfo` 406 | Unirest\Request::getInfo() 407 | 408 | // returns internal cURL handle 409 | Unirest\Request::getCurlHandle() 410 | ``` 411 | 412 | ---- 413 | 414 | Made with ♥ from the [Mashape][mashape-url] team 415 | 416 | [unirest-logo]: http://cl.ly/image/2P373Y090s2O/Image%202015-10-12%20at%209.48.06%20PM.png 417 | 418 | 419 | [mashape-url]: https://www.mashape.com/ 420 | 421 | [license-url]: https://github.com/Mashape/unirest-php/blob/master/LICENSE 422 | 423 | [gitter-url]: https://gitter.im/Mashape/unirest-php 424 | [gitter-image]: https://img.shields.io/badge/Gitter-Join%20Chat-blue.svg?style=flat 425 | 426 | [travis-url]: https://travis-ci.org/Mashape/unirest-php 427 | [travis-image]: https://img.shields.io/travis/Mashape/unirest-php.svg?style=flat 428 | 429 | [packagist-url]: https://packagist.org/packages/Mashape/unirest-php 430 | [packagist-license]: https://img.shields.io/packagist/l/Mashape/unirest-php.svg?style=flat 431 | [packagist-version]: https://img.shields.io/packagist/v/Mashape/unirest-php.svg?style=flat 432 | [packagist-downloads]: https://img.shields.io/packagist/dm/Mashape/unirest-php.svg?style=flat 433 | 434 | [codeclimate-url]: https://codeclimate.com/github/Mashape/unirest-php 435 | [codeclimate-quality]: https://img.shields.io/codeclimate/github/Mashape/unirest-php.svg?style=flat 436 | [codeclimate-coverage]: https://img.shields.io/codeclimate/coverage/github/Mashape/unirest-php.svg?style=flat 437 | 438 | [versioneye-url]: https://www.versioneye.com/user/projects/54b82450050646ca5c0001f3 439 | [versioneye-image]: https://img.shields.io/versioneye/d/php/mashape:unirest-php.svg?style=flat 440 | -------------------------------------------------------------------------------- /classes/Unirest/Request/Body.php: -------------------------------------------------------------------------------- 1 | $file) { 60 | $data[$name] = call_user_func(array(__CLASS__, 'File'), $file); 61 | } 62 | } 63 | 64 | return $data; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /classes/Unirest/Response.php: -------------------------------------------------------------------------------- 1 | code = $code; 21 | $this->headers = $this->parseHeaders($headers); 22 | $this->raw_body = $raw_body; 23 | $this->body = $raw_body; 24 | 25 | // make sure raw_body is the first argument 26 | array_unshift($json_args, $raw_body); 27 | 28 | if (function_exists('json_decode')) { 29 | $json = call_user_func_array('json_decode', $json_args); 30 | 31 | if (json_last_error() === JSON_ERROR_NONE) { 32 | $this->body = $json; 33 | } 34 | } 35 | } 36 | 37 | /** 38 | * if PECL_HTTP is not available use a fall back function 39 | * 40 | * thanks to ricardovermeltfoort@gmail.com 41 | * http://php.net/manual/en/function.http-parse-headers.php#112986 42 | * @param string $raw_headers raw headers 43 | * @return array 44 | */ 45 | private function parseHeaders($raw_headers) 46 | { 47 | if (function_exists('http_parse_headers')) { 48 | return http_parse_headers($raw_headers); 49 | } else { 50 | $key = ''; 51 | $headers = array(); 52 | 53 | foreach (explode("\n", $raw_headers) as $i => $h) { 54 | $h = explode(':', $h, 2); 55 | 56 | if (isset($h[1])) { 57 | if (!isset($headers[$h[0]])) { 58 | $headers[$h[0]] = trim($h[1]); 59 | } elseif (is_array($headers[$h[0]])) { 60 | $headers[$h[0]] = array_merge($headers[$h[0]], array(trim($h[1]))); 61 | } else { 62 | $headers[$h[0]] = array_merge(array($headers[$h[0]]), array(trim($h[1]))); 63 | } 64 | 65 | $key = $h[0]; 66 | } else { 67 | if (substr($h[0], 0, 1) == "\t") { 68 | $headers[$key] .= "\r\n\t".trim($h[0]); 69 | } elseif (!$key) { 70 | $headers[0] = trim($h[0]); 71 | } 72 | } 73 | } 74 | 75 | return $headers; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aik27/inwidget", 3 | "type": "library", 4 | "description": "Show pictures from instagram.com on your website!", 5 | "keywords": ["instagram","widget"], 6 | "homepage": "https://inwidget.ru/", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Alexandr Kazarmshchikov", 11 | "email": "aik@inwidget.ru" 12 | } 13 | ], 14 | "minimum-stability": "dev", 15 | "prefer-stable": true, 16 | "require": { 17 | "php": ">=5.4.0", 18 | "ext-curl": "*", 19 | "ext-json": "*" 20 | } 21 | } -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 'fotokto_ru', 14 | 15 | // Primary hashtags 16 | // Separate hashtags by a comma. For example: girl, man 17 | 'HASHTAG' => '', 18 | 19 | // ------------------------------------------------------------- 20 | // Authorization (NOT required) 21 | // ------------------------------------------------------------- 22 | 23 | // Access token granted to your primary account by an Instagram app. 24 | // If you use it, the widget will start sending requests through the official API (https://www.instagram.com/developer/) 25 | 'ACCESS_TOKEN' => '', 26 | 27 | // Login and password of an Instagram account for authorization. 28 | // Authorization is necessary for alternative methods of obtaining data and provides more stability when you using the undocumented API 29 | 'authLogin' => '', 30 | 'authPassword' => '', 31 | 32 | // ------------------------------------------------------------- 33 | // Multi-account configuration 34 | // ------------------------------------------------------------- 35 | 36 | // If you need to separete logins on diffent website pages, just add possible logins to the array below. 37 | // After that you can send login to the widget by GET variable. It workds only with the undocumented API. 38 | // Example: /inwidget/index.php?login=fotokto_ru 39 | 'loginAvailable' => [ 40 | #'fotokto_ru', 41 | #'instagram', 42 | ], 43 | // Same option for tagged media. Add possible tags to the array below. 44 | // Then you can use GET variable for tags. Example: /inwidget/index.php?tag=photography 45 | // You can mix this option with "loginAvailable" and "tagsFromAccountOnly" 46 | 'tagsAvailable' => [ 47 | #'girl', 48 | #'photography', 49 | ], 50 | 51 | // ------------------------------------------------------------- 52 | // Tags 53 | // ------------------------------------------------------------- 54 | 55 | // Specify here list of banned logins. 56 | // Photos of these users will not be display in the widget. 57 | // Separate usernames by a comma. For example: mark18, kitty45 58 | 'tagsBannedLogins' => '', 59 | 60 | // Search tagged media from your account only [ true / false ] 61 | // To improve search, increase value of the "imgCount" option 62 | 'tagsFromAccountOnly' => false, 63 | 64 | // ------------------------------------------------------------- 65 | // Images 66 | // ------------------------------------------------------------- 67 | 68 | // Random order of pictures [ true / false ] 69 | 'imgRandom' => true, 70 | 71 | // How many pictures the widget will get from Instagram? 72 | 'imgCount' => 30, 73 | 74 | // ------------------------------------------------------------- 75 | // Cache 76 | // ------------------------------------------------------------- 77 | 78 | // Cache expiration time (hours) 79 | 'cacheExpiration' => 6, 80 | 81 | // Skip cache data [ true / false ] 82 | // So mean, requests to Instagram API will be sending every time. 83 | // Warning! Use true value only for debug 84 | 'cacheSkip' => false, 85 | 86 | // Full path to the cache directory 87 | 'cachePath' => __DIR__ . '/cache/', 88 | 89 | // ------------------------------------------------------------- 90 | // Skin 91 | // ------------------------------------------------------------- 92 | 93 | // Default skin. 94 | // Possible values: default, modern-blue, modern-green, modern-red, modern-orange, modern-grey, modern-black, modern-violet, modern-yellow 95 | // This option may no effect if you set a skin by $_GET variable 96 | 'skinDefault' => 'default', 97 | 98 | // Possible skin values. 99 | // If you are using a custom skin, add the skin filename in this array without extension. 100 | 'skinAvailable' => [ 101 | 'default', 102 | 'modern-blue', 103 | 'modern-green', 104 | 'modern-red', 105 | 'modern-orange', 106 | 'modern-grey', 107 | 'modern-black', 108 | 'modern-violet', 109 | 'modern-yellow' 110 | ], 111 | 112 | // Path to the skins directory 113 | 'skinPath' => 'skins/', 114 | 115 | // ------------------------------------------------------------- 116 | // Lang 117 | // ------------------------------------------------------------- 118 | 119 | // Default language [ ru / en / ua ] or something else from the lang directory. 120 | // This option may no effect if you set a lang by $_GET variable 121 | 'langDefault' => 'ru', 122 | 123 | // Possible language values. 124 | // If you are using another language, add the lang filename in this array without extension. 125 | 'langAvailable' => ['ru', 'en', 'ua'], 126 | 127 | // Full path to the langs directory 128 | 'langPath' => __DIR__ . '/langs/', 129 | 130 | // Language auto-detection [ true / false ] 131 | // This option may no effect if you set a language by $_GET variable. 132 | 'langAuto' => false, 133 | 134 | ); 135 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | = 5.4.0. Your version: ' . phpversion()); 25 | } 26 | if (!extension_loaded('curl')) { 27 | die('inWidget required cURL PHP extension. Please, install it or ask your hosting provider.'); 28 | } 29 | 30 | #ini_set('include_path', __DIR__ .'/' ); 31 | #require_once 'classes/Autoload.php'; 32 | 33 | require_once 'classes/InstagramScraper.php'; 34 | require_once 'classes/Unirest.php'; 35 | require_once 'classes/InWidget.php'; 36 | 37 | /* ----------------------------------------------------------- 38 | Native initialization 39 | ------------------------------------------------------------*/ 40 | 41 | try { 42 | $inWidget = new \InWidget\Core(); 43 | $inWidget->getData(); 44 | include 'template.php'; 45 | } catch (\Exception $e) { 46 | echo $e->getMessage(); 47 | } 48 | 49 | /* ----------------------------------------------------------- 50 | Custom initialization 51 | ------------------------------------------------------------*/ 52 | 53 | /* 54 | try { 55 | 56 | // Options may change through the class constructor. For example: 57 | 58 | $config = array( 59 | 'LOGIN' => 'fotokto_ru', 60 | 'HASHTAG' => '', 61 | 'ACCESS_TOKEN' => '', 62 | 'authLogin' => '', 63 | 'authPassword' => '', 64 | 'tagsBannedLogins' => '', 65 | 'tagsFromAccountOnly' => false, 66 | 'imgRandom' => false, 67 | 'imgCount' => 30, 68 | 'cacheExpiration' => 6, 69 | 'cacheSkip' => false, 70 | 'cachePath' => __DIR__.'/cache/', 71 | 'skinDefault' => 'default', 72 | 'skinPath'=> 'skins/', 73 | 'langDefault' => 'ru', 74 | 'langAuto' => false, 75 | 'langPath' => __DIR__.'/langs/', 76 | ); 77 | 78 | $inWidget = new \inWidget\Core($config); 79 | 80 | // Also, you may change default values of properties 81 | 82 | $inWidget->width = 800; // widget width in pixels 83 | $inWidget->inline = 6; // number of images in single line 84 | $inWidget->view = 18; // number of images in widget 85 | $inWidget->toolbar = false; // show profile avatar, statistic and action button 86 | $inWidget->preview = 'large'; // quality of images: small, large, fullsize 87 | $inWidget->adaptive = false; // enable adaptive mode 88 | $inWidget->skipGET = true; // skip GET variables to avoid name conflicts 89 | $inWidget->setOptions(); // apply new values 90 | 91 | $inWidget->getData(); 92 | include 'template.php'; 93 | 94 | // Also, you may use API methods directly 95 | 96 | // $account = $inWidget->api->getAccountByLogin($config['LOGIN'], $config['ACCESS_TOKEN'], $config['imgCount']); 97 | // $mediasByLogin = $inWidget->api->getMediasByLogin($config['LOGIN'], $config['ACCESS_TOKEN'], $config['imgCount']); 98 | // $mediasByTag = $inWidget->api->getMediasByTag('girl', $config['ACCESS_TOKEN'], $config['imgCount']); 99 | 100 | } catch (\Exception $e) { 101 | echo $e->getMessage(); 102 | } 103 | */ 104 | -------------------------------------------------------------------------------- /langs/en.php: -------------------------------------------------------------------------------- 1 | 'We\'re on Instagram:', 20 | 'buttonFollow' => 'View', 21 | 'statPosts' => 'posts', 22 | 'statFollowers' => 'followers', 23 | 'statFollowing' => 'following', 24 | 'imgEmpty' => 'user doesn\'t have any photos yet', 25 | 'imgEmptyByHash' => 'photos by tag #{$hashtag} not found', 26 | 'errorCache' => 'Update cache error. Something went wrong.
Using version from', 27 | 'updateNeeded' => 'Please, update widget to last version from inwidget.ru', 28 | ); 29 | -------------------------------------------------------------------------------- /langs/ru.php: -------------------------------------------------------------------------------- 1 | 'Мы в Instagram:', 20 | 'buttonFollow' => 'Посмотреть', 21 | 'statPosts' => 'посты', 22 | 'statFollowers' => 'подписчики', 23 | 'statFollowing' => 'подписки', 24 | 'imgEmpty' => 'у пользователя нет фотографии', 25 | 'imgEmptyByHash' => 'фотографии по тегу #{$hashtag} не найдены ', 26 | 'errorCache' => 'Ошибка обновления кэша.
Используется версия от', 27 | 'updateNeeded' => 'Обновите виджет до последней версии с сайта inwidget.ru', 28 | ); -------------------------------------------------------------------------------- /langs/ua.php: -------------------------------------------------------------------------------- 1 | 'Ми в Instagram:', 20 | 'buttonFollow' => 'Переглянути', 21 | 'statPosts' => 'пости', 22 | 'statFollowers' => 'підписчики', 23 | 'statFollowing' => 'підписки', 24 | 'imgEmpty' => 'у користувача немає фотографій', 25 | 'imgEmptyByHash' => 'фотографії за тегом #{$hashtag} не знайдені ', 26 | 'errorCache' => 'Помилка оновлення кешу.
Використовується версія від', 27 | 'updateNeeded' => 'Оновлення віджет до останньої версії з сайту inwidget.ru', 28 | ); 29 | -------------------------------------------------------------------------------- /plugins/adaptive.php: -------------------------------------------------------------------------------- 1 | inline = 6; 17 | $inWidget->view = 12; 18 | } 19 | 20 | ?> 21 | 22 | 51 | 83 | -------------------------------------------------------------------------------- /skins/default.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: arial; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | background:#f9f9f9; 25 | border-radius: 5px 5px 5px 5px; 26 | -webkit-border-radius: 5px 5px 5px 5px; 27 | -moz-border-radius: 5px 5px 5px 5px; 28 | overflow:hidden; 29 | } 30 | .widget a.title:link, .widget a.title:visited { 31 | display:block; 32 | height:33px; 33 | text-decoration:none; 34 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#547fa7+0,46719b+100 */ 35 | background: #46719b; /* Old browsers */ 36 | background: -moz-linear-gradient(top, #547fa7 0%, #46719b 100%); /* FF3.6-15 */ 37 | background: -webkit-linear-gradient(top, #547fa7 0%,#46719b 100%); /* Chrome10-25,Safari5.1-6 */ 38 | background: linear-gradient(to bottom, #547fa7 0%,#46719b 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 39 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#547fa7', endColorstr='#46719b',GradientType=0 ); /* IE6-9 */ 40 | } 41 | .widget .title .icon { 42 | display:block; 43 | float:left; 44 | width:25px; 45 | height:25px; 46 | background:url('data:img/png;base64,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') no-repeat; 47 | background-size: 25px 25px; 48 | margin:4px 10px 0 5px; 49 | } 50 | .widget .title .text { 51 | float:left; 52 | height:25px; 53 | overflow:hidden; 54 | margin:5px 0 0 0; 55 | color:#FFF; 56 | font-size:18px; 57 | white-space:nowrap; 58 | } 59 | .widget .profile { 60 | width:100%; 61 | height:80px; 62 | border-collapse: collapse; 63 | } 64 | .widget .profile tr td { 65 | padding:0px; 66 | margin:0px; 67 | text-align:center; 68 | } 69 | .widget .profile td { 70 | border:1px solid #c3c3c3; 71 | } 72 | .widget .profile .avatar { 73 | width:1%; 74 | padding:10px !important; 75 | border-left:none !important; 76 | line-height:0px; 77 | } 78 | .widget .profile .avatar img { 79 | width:60px; 80 | } 81 | .widget .profile .value { 82 | width:33%; 83 | height:30px; 84 | font-size:14px; 85 | font-weight:bold; 86 | } 87 | .widget .profile span { 88 | display:block; 89 | font-size:9px; 90 | font-weight:bold; 91 | color:#999999; 92 | margin:-2px 0 0 0; 93 | } 94 | .widget a.follow:link, .widget a.follow:visited { 95 | display:block; 96 | background:#ad4141; 97 | text-decoration:none; 98 | font-size:14px; 99 | color:#FFF; 100 | font-weight:bold; 101 | width:120px; 102 | margin:0 auto 0 auto; 103 | padding:4px 4px 4px 10px; 104 | border:3px solid #FFF; 105 | border-radius: 5px 5px 5px 5px; 106 | -webkit-border-radius: 5px 5px 5px 5px; 107 | -moz-border-radius: 5px 5px 5px 5px; 108 | box-shadow: 0 0px 2px rgba(0,0,0,0.5); 109 | -moz-box-shadow: 0 0px 2px rgba(0,0,0,0.5); 110 | -webkit-box-shadow: 0 0px 2px rgba(0,0,0,0.5); 111 | } 112 | .widget a.follow:hover { 113 | background:#cf3838; 114 | } 115 | .widget .data { 116 | text-align:left; 117 | margin:10px 0 0 10px; 118 | padding:0 0 5px 0; 119 | } 120 | .widget .data a.image:link, .widget .data a.image:visited{ 121 | display:block; 122 | float:left; 123 | margin:0 5px 5px 0; 124 | overflow:hidden; 125 | border:2px solid #FFF; 126 | box-shadow: 0 1px 1px rgba(0,0,0,0.3); 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | } -------------------------------------------------------------------------------- /skins/i/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aik27/inwidget/6d22ee591131ede035409dd508eb7dc26fd31a92/skins/i/icon.png -------------------------------------------------------------------------------- /skins/i/icon_modern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aik27/inwidget/6d22ee591131ede035409dd508eb7dc26fd31a92/skins/i/icon_modern.png -------------------------------------------------------------------------------- /skins/modern-black.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#4c4c4c+0,000000+100 */ 39 | background: #4c4c4c; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #4c4c4c 0%, #000000 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #4c4c4c 0%,#000000 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #4c4c4c 0%,#000000 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#000000',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #4c4c4c; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #2f2f2f; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-blue.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#296499+0,1c466b+100 */ 39 | background: #296499; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #296499 0%, #1c466b 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #296499 0%,#1c466b 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #296499 0%,#1c466b 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#296499', endColorstr='#1c466b',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #296499; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #22547F; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-green.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#2b9929+0,1c682b+100 */ 39 | background: #2b9929; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #2b9929 0%, #1c682b 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #2b9929 0%,#1c682b 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #2b9929 0%,#1c682b 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#2b9929', endColorstr='#1c682b',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #2b9929; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #21751f; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-grey.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#eeeeee+0,b7b7b7+100 */ 39 | background: #eeeeee; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #eeeeee 0%, #b7b7b7 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #eeeeee 0%,#b7b7b7 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #eeeeee 0%,#b7b7b7 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#b7b7b7',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAQAAAC0NkA6AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfhCxwACRXAzOQTAAAC0UlEQVRYw9WYPUwUQRSAv4XzSICTQCCxIIFEJQf0ghoSC4z8dFyidFhobwzBRO0MFHgNhaCdBQ3FXRA0aiw00Rg5xUKDQUNxJKgFeBwhauRvKBj2527ndjfsmvCumDcz771v/vbt3GrsSYQYHdRzBH9kkzTPSLBuNJ3mAyKA33taDcRqIAiBYHUPE+FjYAiBYJZyuBwoQiDoK6Lbp61WS3eIOp9CzZNFk/oOUSr1njpI+bQo1hV5a+pJFfm2KJq6dsggBeSQQf5aatvmSsg3yDlKZDQBVAUDuaXu8gpZ4w9QSoUXJ/eQDBMkmWcVqCRKD5esi1JI3D3x05zM82zgsSvflDvIqOIUFjPmF2Qy52k2i+ZiNiljT16QoFivCQaol3txHaGECK5xRmbcNMOm4WwT43zungxanKvIyPZ7jrs6Ki1/ctTSPpifhUssBq1ydIKEIyQpy2OctbTrEVVppVGW63xzhHzVLz6N9gYqSLUsl1l2hBg21fYGKsiOY2g7URwQFSQjyxpqHEMbNr+8QeZkGSHqCIkSkdoXb5DPci4aPY6QmD77T94g33kjtV6brGWWBi5K7TU/vEFgXJaVjBTI1SFG9BvWuMpIDXlESmqdjCowIcbokHqKKe+QDfrZkvpVJmnKs2hikitS36KfDfWa7ueuuE3fDVMuXeM+7dQSJkwt7TxgzdQ7YOMdz0/1cdshDOWk7SwLLJDNaR2y9Y3np3p7uUmWO4T1ekXe232D29wtHMT53jVMBzPK3ndccEK4u9y9pI1eplmxtK4wRS9tvHIO4O62sskEE9TSTDNVQIY55lhy5esasidLLPHcg72n5TqwGBBxgCj2okf8z5BS3yH7EUURaal2cdxXxAm6pLao0cdDWUnzlH8+IUrolJdD6INyZgP9HjFLGUBLoB9wTu1PrpWZQBAztIDxf7uMGF3UUezLUdbYZpEnJPkNsAv24I9Q8PTgaAAAAABJRU5ErkJggg==") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#000; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #535353; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #383838; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-orange.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#e26200+0,b74c00+100 */ 39 | background: #e26200; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #e26200 0%, #b74c00 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #e26200 0%,#b74c00 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #e26200 0%,#b74c00 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e26200', endColorstr='#b74c00',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #e26200; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #c65600; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-red.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#993629+0,66241b+100 */ 39 | background: #993629; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #993629 0%, #66241b 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #993629 0%,#66241b 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #993629 0%,#66241b 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#993629', endColorstr='#66241b',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #993629; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #832e23; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-violet.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#912999+0,631c68+100 */ 39 | background: #912999; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #912999 0%, #631c68 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #912999 0%,#631c68 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #912999 0%,#631c68 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#912999', endColorstr='#631c68',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,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") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#FFF; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #912999; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #822589; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /skins/modern-yellow.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | body { 6 | width: 100%; 7 | height: 100%; 8 | color: #212121; 9 | font-family: "Trebuchet MS", Helvetica, sans-serif; 10 | font-size:12px; 11 | padding:0px; 12 | margin:0px; 13 | } 14 | img { 15 | border: 0; 16 | } 17 | .clear { 18 | clear:both; 19 | height:0; 20 | line-height:0; 21 | } 22 | .widget { 23 | border:1px solid #c3c3c3; 24 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#ffffff+0,ededed+100 */ 25 | background: #ffffff; /* Old browsers */ 26 | background: -moz-linear-gradient(top, #ffffff 0%, #ededed 100%); /* FF3.6-15 */ 27 | background: -webkit-linear-gradient(top, #ffffff 0%,#ededed 100%); /* Chrome10-25,Safari5.1-6 */ 28 | background: linear-gradient(to bottom, #ffffff 0%,#ededed 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 29 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */ 30 | border-radius: 5px 5px 5px 5px; 31 | -webkit-border-radius: 5px 5px 5px 5px; 32 | -moz-border-radius: 5px 5px 5px 5px; 33 | overflow:hidden; 34 | } 35 | .widget a.title:link, .widget a.title:visited { 36 | display:block; 37 | height:33px; 38 | /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#fbf802+0,feb505+100 */ 39 | background: #fbf802; /* Old browsers */ 40 | background: -moz-linear-gradient(top, #fbf802 0%, #feb505 100%); /* FF3.6-15 */ 41 | background: -webkit-linear-gradient(top, #fbf802 0%,#feb505 100%); /* Chrome10-25,Safari5.1-6 */ 42 | background: linear-gradient(to bottom, #fbf802 0%,#feb505 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 43 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fbf802', endColorstr='#feb505',GradientType=0 ); /* IE6-9 */ 44 | text-decoration:none; 45 | } 46 | .widget .title .icon { 47 | display:block; 48 | float:right; 49 | width:22px; 50 | height:22px; 51 | background: url("data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAQAAAC0NkA6AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfhCxwACRXAzOQTAAAC0UlEQVRYw9WYPUwUQRSAv4XzSICTQCCxIIFEJQf0ghoSC4z8dFyidFhobwzBRO0MFHgNhaCdBQ3FXRA0aiw00Rg5xUKDQUNxJKgFeBwhauRvKBj2527ndjfsmvCumDcz771v/vbt3GrsSYQYHdRzBH9kkzTPSLBuNJ3mAyKA33taDcRqIAiBYHUPE+FjYAiBYJZyuBwoQiDoK6Lbp61WS3eIOp9CzZNFk/oOUSr1njpI+bQo1hV5a+pJFfm2KJq6dsggBeSQQf5aatvmSsg3yDlKZDQBVAUDuaXu8gpZ4w9QSoUXJ/eQDBMkmWcVqCRKD5esi1JI3D3x05zM82zgsSvflDvIqOIUFjPmF2Qy52k2i+ZiNiljT16QoFivCQaol3txHaGECK5xRmbcNMOm4WwT43zungxanKvIyPZ7jrs6Ki1/ctTSPpifhUssBq1ydIKEIyQpy2OctbTrEVVppVGW63xzhHzVLz6N9gYqSLUsl1l2hBg21fYGKsiOY2g7URwQFSQjyxpqHEMbNr+8QeZkGSHqCIkSkdoXb5DPci4aPY6QmD77T94g33kjtV6brGWWBi5K7TU/vEFgXJaVjBTI1SFG9BvWuMpIDXlESmqdjCowIcbokHqKKe+QDfrZkvpVJmnKs2hikitS36KfDfWa7ueuuE3fDVMuXeM+7dQSJkwt7TxgzdQ7YOMdz0/1cdshDOWk7SwLLJDNaR2y9Y3np3p7uUmWO4T1ekXe232D29wtHMT53jVMBzPK3ndccEK4u9y9pI1eplmxtK4wRS9tvHIO4O62sskEE9TSTDNVQIY55lhy5esasidLLPHcg72n5TqwGBBxgCj2okf8z5BS3yH7EUURaal2cdxXxAm6pLao0cdDWUnzlH8+IUrolJdD6INyZgP9HjFLGUBLoB9wTu1PrpWZQBAztIDxf7uMGF3UUezLUdbYZpEnJPkNsAv24I9Q8PTgaAAAAABJRU5ErkJggg==") no-repeat; 52 | background-size: 22px 22px; 53 | margin:6px 6px 0 0; 54 | } 55 | .widget .title .text { 56 | float:left; 57 | height:25px; 58 | overflow:hidden; 59 | margin:5px 0 0 10px; 60 | color:#000; 61 | font-size:18px; 62 | white-space:nowrap; 63 | } 64 | .widget .profile { 65 | width:100%; 66 | height:80px; 67 | border-collapse: collapse; 68 | } 69 | .widget .profile tr td { 70 | padding:0px; 71 | margin:0px; 72 | text-align:center; 73 | } 74 | .widget .profile td { 75 | border:1px solid #c3c3c3; 76 | } 77 | .widget .profile .avatar { 78 | width:1%; 79 | padding:10px !important; 80 | border-left:none !important; 81 | line-height:0px; 82 | } 83 | .widget .profile .avatar img { 84 | width:60px; 85 | } 86 | .widget .profile .value { 87 | width:33%; 88 | height:30px; 89 | font-size:14px; 90 | font-weight:bold; 91 | } 92 | .widget .profile span { 93 | display:block; 94 | font-size:9px; 95 | font-weight:bold; 96 | color:#999999; 97 | margin:-2px 0 0 0; 98 | } 99 | .widget a.follow:link, .widget a.follow:visited { 100 | display:block; 101 | background: #535353; 102 | text-decoration:none; 103 | font-size:14px; 104 | color:#FFF; 105 | font-weight:bold; 106 | width:120px; 107 | margin:0 auto 0 auto; 108 | padding:6px 6px 6px 10px; 109 | border-radius: 5px 5px 5px 5px; 110 | -webkit-border-radius: 5px 5px 5px 5px; 111 | -moz-border-radius: 5px 5px 5px 5px; 112 | } 113 | .widget a.follow:hover { 114 | background: #383838; 115 | } 116 | .widget .data { 117 | text-align:left; 118 | margin:10px 0 0 10px; 119 | padding:0 0 5px 0; 120 | } 121 | .widget .data a.image:link, .widget .data a.image:visited{ 122 | display:block; 123 | float:left; 124 | margin:0 5px 5px 0; 125 | overflow:hidden; 126 | border:2px solid #FFF; 127 | ling-height:0px; 128 | text-decoration:none; 129 | } 130 | .widget .data .image:hover { 131 | filter: alpha(opacity=80); 132 | opacity: 0.8; 133 | } 134 | .widget .data .image span { 135 | display:block; 136 | background-repeat:no-repeat; 137 | background-size:cover; 138 | background-position:center center; 139 | } 140 | .widget .empty { 141 | text-align:center; 142 | margin:10px 0 10px 0; 143 | } 144 | .copyright { 145 | margin:3px 0 3px 0; 146 | font-size:10px; 147 | text-align:center; 148 | } 149 | .copyright a:link, .copyright a:visited { 150 | text-decoration:none; 151 | color:#666; 152 | } 153 | .copyright a:hover { 154 | text-decoration:underline; 155 | } 156 | .cacheError { 157 | font-size:10px; 158 | color:red; 159 | text-align:center; 160 | } 161 | @media (max-width: 240px) { 162 | .widget .profile { 163 | display:none; 164 | } 165 | } 166 | @media (max-width: 180px) { 167 | .widget .title .text { 168 | display:none; 169 | } 170 | .widget .title .icon { 171 | width:100%; 172 | background-position:center top; 173 | margin:5px 0 0 0; 174 | } 175 | } -------------------------------------------------------------------------------- /template.php: -------------------------------------------------------------------------------- 1 | 23 | 24 | 25 | 26 | inWidget - free Instagram widget for your site! 27 | 28 | 29 | 30 | 31 | adaptive === false) : ?> 32 | 48 | 53 | 54 | 55 |
56 | 57 |
 
58 |
lang['title']; ?>
59 |
 
60 |
61 | toolbar == true) : ?> 62 | 63 | 64 | 67 | 71 | 75 | 79 | 80 | 81 | 84 | 85 |
65 | 66 | 68 | data->posts; ?> 69 | lang['statPosts'] ?> 70 | 72 | data->followers ?> 73 | lang['statFollowers'] ?> 74 | 76 | data->following ?> 77 | lang['statFollowing'] ?> 78 |
82 | 83 |
86 | countAvailableImages($inWidget->data->images); 89 | if ($count > 0) { 90 | if ($inWidget->config['imgRandom'] === true) { 91 | shuffle($inWidget->data->images); 92 | } 93 | echo '
'; 94 | foreach ($inWidget->data->images as $key => $item) { 95 | if ($inWidget->isBannedUserId($item->authorId) === true) { 96 | continue; 97 | } 98 | switch ($inWidget->preview) { 99 | case 'large': 100 | $thumbnail = $item->large; 101 | break; 102 | case 'fullsize': 103 | $thumbnail = $item->fullsize; 104 | break; 105 | default: 106 | $thumbnail = $item->small; 107 | } 108 | echo ' '; 109 | $i++; 110 | if ($i >= $inWidget->view) { 111 | break; 112 | } 113 | } 114 | echo '
 
'; 115 | echo '
'; 116 | } else { 117 | if (!empty($inWidget->config['HASHTAG'])) { 118 | $inWidget->lang['imgEmptyByHash'] = str_replace( 119 | '{$hashtag}', 120 | $inWidget->config['HASHTAG'], 121 | $inWidget->lang['imgEmptyByHash'] 122 | ); 123 | echo '
' . $inWidget->lang['imgEmptyByHash'] . '
'; 124 | } else { 125 | echo '
' . $inWidget->lang['imgEmpty'] . '
'; 126 | } 127 | } 128 | ?> 129 |
130 | 133 | data->isBackup)) : ?> 134 |
135 | lang['errorCache'] . ' ' . date( 136 | 'Y-m-d H:i:s', 137 | $inWidget->data->lastupdate 138 | ) . '
' . $inWidget->lang['updateNeeded'] ?> 139 |
140 | 141 | 142 | 143 | 148 | --------------------------------------------------------------------------------