FB_Photo_Sync

Plugin Name: FB Photo Sync Description: Import and manage Facebook photo ablums on your WordPress website.

Defined (1)

The class is defined in the following location(s).

/fb-photo-sync.php  
  1. class FB_Photo_Sync { 
  2.  
  3. var $version = '0.5.7'; 
  4.  
  5. public function __construct() { 
  6. add_action( 'admin_menu', array( $this, 'add_menu_page' ) ); 
  7. add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); 
  8. add_action( 'wp_enqueue_scripts', array( $this, 'fbps_scripts' ) ); 
  9. add_action( 'wp_ajax_fbps_save_album', array( $this, 'ajax_save_photos' ) ); 
  10. add_action( 'wp_ajax_fbps_save_app', array( $this, 'ajax_save_app' ) ); 
  11. add_action( 'wp_ajax_fbps_remove_app', array( $this, 'ajax_remove_app' ) ); 
  12. add_action( 'wp_ajax_fbps_delete_album', array( $this, 'ajax_delete_photos' ) ); 
  13.  
  14. add_shortcode( 'fb_album', array( $this, 'fb_album_shortcode' ) ); 
  15.  
  16. public function admin_scripts() { 
  17. $ver = $this->version; 
  18. wp_enqueue_style( 'fbps-admin-styles', plugin_dir_url( __FILE__ ) . 'css/admin.css', array(), $ver ); 
  19. wp_enqueue_script( 'fbps-zero-clipboard', plugin_dir_url( __FILE__ ) . 'js/jquery.zclip.js', array( 'jquery' ), $ver, true ); 
  20. wp_enqueue_script( 'fbps-admin-script', plugin_dir_url( __FILE__ ) . 'js/admin.js', array( 'jquery', 'fbps-zero-clipboard' ), $ver, true ); 
  21.  
  22. public function fbps_scripts() { 
  23. $ver = $this->version; 
  24. wp_enqueue_style( 'fbps-styles', plugin_dir_url( __FILE__ ) . 'css/styles.css', array(), $ver ); 
  25. wp_enqueue_style( 'light-gallery-css', plugin_dir_url( __FILE__ ) . 'light-gallery/css/lightGallery.css', array(), $ver ); 
  26. wp_enqueue_script( 'light-gallery-js', plugin_dir_url( __FILE__ ) . 'light-gallery/js/lightGallery.min.js', array( 'jquery' ), $ver, false ); 
  27. wp_enqueue_script( 'lazyload', plugin_dir_url( __FILE__ ) . 'js/jquery.lazyload.min.js', array( 'jquery' ), $ver, false ); 
  28.  
  29. public function closest_image_size( $width, $height, $photos ) { 
  30. $current = null; 
  31.  
  32. foreach( $photos as $photo ) { 
  33. if( !$this->valid_image_size( $width, $height, $photo ) ) { 
  34. continue; 
  35.  
  36. $current = $this->get_closest_image( $width, $height, $photo, $current ); 
  37.  
  38. if( $current == null ) { 
  39. $current['source'] = $photos[0]['source']; 
  40.  
  41. return $current['source']; 
  42.  
  43. private function valid_image_size( $width, $height, $photo ) { 
  44. return $width <= $photo['width'] && $height <= $photo['height']; 
  45.  
  46. private function get_image_diff_sum( $width, $height, $photo ) { 
  47. $width_diff = $photo['width'] - $width; 
  48. $height_diff = $photo['height'] - $height; 
  49.  
  50. return $width_diff + $height_diff; 
  51.  
  52. private function get_closest_image( $width, $height, $photo, $current = null ) { 
  53. if( ! $current ) { 
  54. return $photo; 
  55.  
  56. $photo_sum = $this->get_image_diff_sum( $width, $height, $photo ); 
  57. $current_sum = $this->get_image_diff_sum( $width, $height, $current ); 
  58.  
  59. if( $current_sum > $photo_sum ) { 
  60. return $photo; 
  61.  
  62. return $current; 
  63.  
  64. public function save_image( $file, $desc ) { 
  65. // unattached to a post 
  66. $post_id = 0; 
  67. // Download file to temp location 
  68. $tmp = download_url( $file ); 
  69.  
  70. // Set variables for storage 
  71. // fix file filename for query strings 
  72. preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches ); 
  73. $file_array['name'] = basename($matches[0]); 
  74. $file_array['tmp_name'] = $tmp; 
  75.  
  76. // If error storing temporarily, unlink 
  77. if ( is_wp_error( $tmp ) ) { 
  78. @unlink($file_array['tmp_name']); 
  79. $file_array['tmp_name'] = ''; 
  80.  
  81. // do the validation and storage stuff 
  82. $id = media_handle_sideload( $file_array, $post_id, $desc ); 
  83. // If error storing permanently, unlink 
  84. if ( is_wp_error($id) ) { 
  85. @unlink($file_array['tmp_name']); 
  86. return $id; 
  87. return $id; 
  88.  
  89. public function fb_album_shortcode( $atts ) { 
  90. $atts = shortcode_atts( array( 
  91. 'id' => '',  
  92. 'width' => 130,  
  93. 'height' => 130,  
  94. 'order' => 'desc',  
  95. 'wp_photos' => false,  
  96. 'lazy_load' => 'true',  
  97. 'ignore' =>'',  
  98. ), $atts ); 
  99.  
  100. $atts['lazy_load'] = strtolower( $atts['lazy_load'] ) == 'false' ? false : true; 
  101.  
  102. $atts['ignore'] = explode( ', ', $atts['ignore'] ); 
  103. $atts['ignore'] = array_map( 'trim', $atts['ignore'] ); 
  104.  
  105. if( empty( $atts['id'] ) || is_Nan( $atts['id'] ) ) { 
  106. return; 
  107.  
  108. $album = get_option( 'fbps_album_'.$atts['id'] ); 
  109.  
  110. if( !isset( $album['items'] ) ) 
  111. return; 
  112. ob_start(); 
  113. ?> 
  114. <div id="fbps-album-<?php echo esc_attr( $album['id'] ); ?>" class="fbps-album"> 
  115. <h3><?php echo esc_html( $album['name'] ); ?></h3> 
  116. <ul> 
  117. <?php 
  118. if( trim( strtolower( $atts['order'] ) ) == 'desc' ) { 
  119. $album['items'] = array_reverse( $album['items'] ); 
  120. foreach( $album['items'] as $item ) { 
  121. if( in_array( $item['id'], $atts['ignore'] ) ) { 
  122. continue; 
  123. $item_name = isset( $item['name'] ) ? $item['name'] : ''; 
  124. $thumbnail = $this->closest_image_size( $atts['width'], $atts['height'], $item['photos'] ); 
  125. $image = $this->closest_image_size( 960, 960, $item['photos'] ); 
  126. if( $atts['wp_photos'] == 'true' && isset( $item['wp_photo_id'] ) ) { 
  127. $wp_thumbnail = wp_get_attachment_image_src( $item['wp_photo_id'], array( $atts['width'], $atts['height'] ) ); 
  128. $wp_image = wp_get_attachment_image_src( $item['wp_photo_id'], array(960, 960) ); 
  129. if( is_array( $wp_thumbnail ) ) { 
  130. $thumbnail = $wp_thumbnail[0]; 
  131. if( is_array( $wp_image ) ) { 
  132. $image = $wp_image[0]; 
  133. $image_loaded = !$atts['lazy_load'] ? ' background-image: url(' . esc_url( $thumbnail ) . '); ' : ''; 
  134. ?> 
  135. <li id="fbps-photo-<?php echo esc_attr( $item['id'] ); ?>" class="fbps-photo" data-src="<?php echo esc_url( $image ); ?>"> 
  136. <div style="width: <?php echo esc_attr( $atts['width'] ); ?>px; height: <?php echo intval( $atts['height'] ); ?>px; background-color: #ccc;<?php echo esc_attr( $image_loaded ); ?>" data-original="<?php echo esc_url( $thumbnail ); ?>"></div> 
  137. <img src="<?php echo esc_url( $thumbnail ); ?>" style="display: none;" /> 
  138. <div class="lg-sub-html"><p class="lg-fbps"><?php echo esc_html( $item_name ); ?></p></div> 
  139. </li> 
  140. <?php 
  141. ?> 
  142. </ul> 
  143. <div style="clear: both;"></div> 
  144. </div> 
  145. <script type="text/javascript"> 
  146. (function($) { 
  147. <?php if( $atts['lazy_load'] ) { ?> 
  148. $('#fbps-album-<?php echo esc_js( $album['id'] ); ?> li.fbps-photo > div').lazyload({ 
  149. effect: 'fadeIn' 
  150. }); 
  151. <?php } ?> 
  152. $('#fbps-album-<?php echo esc_js( $album['id'] ); ?> > ul').lightGallery(); 
  153. })(jQuery); 
  154. </script> 
  155. <?php 
  156. return ob_get_clean(); 
  157.  
  158. public function admin_tabs( $current = 'import' ) { 
  159. $tabs = array( 'import' => 'Import', 'albums' => 'Albums' ); 
  160. echo '<div class="wrap">'; 
  161. echo '<h2>FB Photo Sync</h2>'; 
  162. echo '<div id="icon-themes" class="icon32"><br /></div>'; 
  163. echo '<h2 class="nav-tab-wrapper">'; 
  164. foreach( $tabs as $tab => $name ) { 
  165. $class = ( $tab == $current ) ? ' nav-tab-active' : ''; 
  166. echo "<a class='nav-tab$class' href='?page=fb-photo-sync&tab=$tab'>$name</a>"; 
  167. echo '</h2>'; 
  168.  
  169. public function admin_content( $current = 'import' ) { 
  170. switch( $current ) { 
  171. case 'import': 
  172. $this->import_page(); 
  173. break; 
  174. case 'albums': 
  175. $this->albums_page(); 
  176. break; 
  177. default: 
  178. $this->import_page(); 
  179. ?> 
  180. <hr style="clear: both;" /> 
  181. <input type="hidden" id="nonce" value="<?php echo wp_create_nonce( 'fb-photo-sync' ); ?>" /> 
  182. <div style="width: 400px;"> 
  183. <form style="float:right" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank"> 
  184. <input type="hidden" name="cmd" value="_s-xclick"> 
  185. <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----<BASE64_ENCODED>-----END PKCS7----- 
  186. "> 
  187. <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> 
  188. <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> 
  189. </form> 
  190. <h3 style="margin:0 0 1px;padding:0;">Like this plugin?</h3> 
  191. <p style="margin:0;padding:0;">Many hours have gone into its development. Please consider a small donation for continued support.</p> 
  192. </div> 
  193. <?php 
  194. echo '</div>'; // wrap 
  195.  
  196. public function import_page() { 
  197. global $facebook; 
  198. $app_id = get_option( 'fbps_app_id' ); 
  199. ?> 
  200. <h3>Facebook Application</h3> 
  201. <div id="fbps-app"></div> 
  202. <?php if( ! $app_id ) { ?> 
  203. <p><input type="text" class="regular-text" id="fbps-app-id" placeholder="Facebook App ID" /> 
  204. <input type="button" id="fbps-app-id-submit" class="button" value="Add App" /></p> 
  205. <hr /> 
  206. <div class="instructions"> 
  207. <h3>Instructions:</h3> 
  208. <ol> 
  209. <li>Head to <a href="https://developers.facebook.com/apps/" target="_blank">https://developers.facebook.com/apps/</a></li> 
  210. <li>Select your app or create a new app</li> 
  211. <li>Click on <strong>Settings</strong> in your app, then at the bottom, click <strong>Add Platform</strong></li> 
  212. <li>Under the <strong>Select Platform</strong> modal, click <strong>Website</strong></li> 
  213. <li>Set the <strong>Site URL</strong> in your Facebook App to your domain: <strong><?php echo home_url('/'); ?></strong></li> 
  214. <li>Copy and Paste the App ID in the text space above and click <strong>Add App</strong></li> 
  215. </ol> 
  216. </div> 
  217. <?php } else { ?> 
  218. <p><input type="button" id="fbps-app-id-remove" class="button" value="Remove App" /></p> 
  219. <div id="status"></div> 
  220. <p><fb:login-button scope="user_photos" onlogin="checkLoginState();" auto_logout_link="true"></fb:login-button></p> 
  221. <p class="description">Having issues? Click <strong>Remove App</strong> above and follow the provided instructions.</p> 
  222. <p class="description">Still having issues? <a href="https://wordpress.org/support/plugin/fb-photo-sync" target="_blank">Search FB Photo Sync support page or post a new topic</a>.</p> 
  223. <?php } ?> 
  224. <?php if( $app_id ) { ?> 
  225. <div class="fbps-enabled"> 
  226. <hr /> 
  227. <div class="fbps-row"> 
  228. <h3>Find Albums on a Public Page</h3> 
  229. <p>Type in a Page ID below and click the <strong>Find Albums</strong> button to pull in available albums. 
  230. <p>Check the albums you want to import into WordPress, and then click the <strong>Import Albums</strong> button below to import them.</p> 
  231. <p>When completed, click the <strong>Albums</strong> tab for the album shortcode to include in your post or page.</p> 
  232. <p> 
  233. <input type="text" class="regular-text" id="fbps-page-input" placeholder="Enter Facebook Page ID" /> 
  234. <input type="button" name="fbps-load-albums" id="fbps-load-albums" class="button" value="Find Albums" /> 
  235. </p> 
  236. <p class="description">http://facebook.com/<strong><u>this-is-the-page-id</u></strong></p> 
  237. </div> 
  238. <div class="fbps-row"> 
  239. <h3>Import Your Personal Facebook Albums</h3> 
  240. <p>Click the <strong>Show Albums</strong> button below for a list of your personal albums you can import to your WordPress website.</p> 
  241. <p> 
  242. <input type="button" name="fbps-show-albums" id="fbps-show-albums" class="button" value="Show Albums" /> 
  243. </p> 
  244. </div> 
  245. <div style="clear:both;"></div> 
  246. <hr /> 
  247. <h3>Import Facebook Albums</h3> 
  248. <ul id="fbps-page-album-list" class="fbps-list"> 
  249. <li>None selected</li> 
  250. </ul> 
  251. <div id="import-form"> 
  252. <h3>Albums to Import</h3> 
  253. <ul id="fbps-import-list" class="fbps-list"> 
  254. </ul> 
  255. <p> 
  256. <label for="fbps-wp-images"><input type="checkbox" checked="checked" name="fbps-wp-images" id="fbps-wp-images" /> Import images to WordPress media library?</label> 
  257. </p> 
  258. <p class="description">Checking the box above will import and save images from Facebook to your WordPress site. Import will take longer, so be patient.</p> 
  259. <p class="submit"> 
  260. <input type="button" id="import-button" class="button button-primary" value="Import Albums"> 
  261. </p> 
  262. </div> 
  263. </div> 
  264. <?php 
  265.  
  266. public function albums_page() { 
  267. global $wpdb; 
  268.  
  269. $query = $wpdb->prepare( " 
  270. SELECT option_name, option_value 
  271. FROM {$wpdb->options} 
  272. WHERE 
  273. option_name LIKE %s 
  274. ", 'fbps_album_%' ); 
  275.  
  276. $albums = $wpdb->get_results( $query ); 
  277. echo '<ul id="fbps-album-list" class="fbps-list">'; 
  278. foreach( $albums as $album ) { 
  279. $dump = unserialize( $album->option_value ); 
  280. $wp_photos = isset( $dump['items'][0]['wp_photo_id'] ) && (bool) $dump['items'][0]['wp_photo_id'] ? 'checked="checked"' : ''; 
  281. ?> 
  282. <li data-id="<?php echo esc_attr( $dump['id'] ); ?>"> 
  283. <h3><?php echo esc_html( $dump['name'] ); ?></h3> 
  284. <a href="#" class="fbps-image-sample" style="background-image: url(<?php echo esc_url( $dump['picture'] ); ?>);"></a> 
  285. <div class="fbps-options"> 
  286. <p><code>[fb_album id="<?php echo esc_attr( $dump['id'] ); ?>"<?php echo $wp_photos != '' ? ' wp_photos="true"' : ''; ?>]</code></p> 
  287. <p><label><input type="checkbox" <?php echo $wp_photos; ?> class="fbps-wp-photos" /> Import images to media library?</label> 
  288. <p><span class="fbps-counter"><span>0</span> of </span><?php echo intval( count( $dump['items'] ) ); ?> Photos | <a href="#" class="delete-album">Delete</a> | <a href="#" class="sync-album">Sync</a></p> 
  289. </div> 
  290. </li> 
  291. <?php 
  292. echo '</ul>'; 
  293.  
  294. private function search_array( $id, $items ) { 
  295. foreach( $items as $key => $item ) { 
  296. if( $item['id'] == $id ) { 
  297. return $key; 
  298. return false; 
  299.  
  300. public function ajax_save_app() { 
  301. if( !check_ajax_referer( 'fb-photo-sync', 'nonce', false ) || !current_user_can( 'manage_options' ) || !isset( $_POST['id'] ) || !is_numeric( $_POST['id'] ) ) { 
  302. wp_send_json_error(); 
  303. $update = update_option( 'fbps_app_id', sanitize_text_field( $_POST['id'] ) ); 
  304. if( $update ) { 
  305. wp_send_json_success(); 
  306. } else { 
  307. wp_send_json_error(); 
  308.  
  309. public function ajax_remove_app() { 
  310. if( !check_ajax_referer( 'fb-photo-sync', 'nonce', false ) || !current_user_can( 'manage_options' ) ) { 
  311. wp_send_json_error(); 
  312. $remove = delete_option( 'fbps_app_id' ); 
  313. if( $remove ) { 
  314. wp_send_json_success(); 
  315. } else { 
  316. wp_send_json_error(); 
  317.  
  318. public function ajax_save_photos() { 
  319. if( !check_ajax_referer( 'fb-photo-sync', 'nonce', false ) || !current_user_can( 'manage_options' ) ) { 
  320. wp_send_json_error(); 
  321. $album = json_decode( stripslashes( $_POST['album'] ), true ); 
  322.  
  323. if( is_array( $album ) ) { 
  324. $wp_photos = $_POST['wp_photos'] == 'true' ? true : false; 
  325.  
  326. $saved_album = get_option( 'fbps_album_' . $album['id'] ) ? null : $album; 
  327.  
  328. if( isset( $saved_album['items'] ) && is_array( $saved_album['items'] ) ) { 
  329. $saved_album['name'] = $album['name']; 
  330. $saved_album['picture'] = $album['picture']; 
  331.  
  332. $i = $this->search_array( $album['items'][0]['id'], $saved_album['items'] ); 
  333.  
  334. if( $i === false ) { 
  335. $item = $album['items'][0]; 
  336. } else { 
  337. $item = array_merge( $saved_album['items'][$i], $album['items'][0] ); 
  338.  
  339. $id = $item['id']; 
  340. if( isset( $item['wp_photo_id'] ) && wp_get_attachment_image( $item['wp_photo_id'] ) != null ) { 
  341. if( !$wp_photos ) { 
  342. wp_delete_attachment( $item['wp_photo_id'], true ); 
  343. } else if( $wp_photos ) { 
  344. $photo = $this->closest_image_size( 1000, 1000, $item['photos'] ); 
  345. $name = isset( $item['name'] ) ? $item['name'] : ''; 
  346. $image_id = $this->save_image( $photo, $name ); 
  347. $item['wp_photo_id'] = $image_id; 
  348.  
  349. $key = $this->search_array( $item['id'], $saved_album['items'] ); 
  350. if( $key === false ) { 
  351. array_push( $saved_album['items'], $item ); 
  352. } else { 
  353. $saved_album['items'][$key] = $item; 
  354. update_option( 'fbps_album_' . esc_attr( $saved_album['id'] ), $saved_album ); 
  355. $data = array( 
  356. 'id' => $album['id'],  
  357. 'wp_photos' => $wp_photos,  
  358. 'album' => $album 
  359. ); 
  360. wp_send_json_success( $data ); 
  361. } else { 
  362. $data = array( 
  363. 'id' => $album['id'],  
  364. 'wp_photos' => $wp_photos 
  365. ); 
  366. wp_send_json_error( $data ); 
  367.  
  368. public function ajax_delete_photos() { 
  369. if( !check_ajax_referer( 'fb-photo-sync', 'nonce', false ) ) { 
  370. wp_send_json_error(); 
  371. $id = $_POST['id']; 
  372. if( isset( $id ) && current_user_can( 'manage_options' ) ) { 
  373. $saved_album = get_option( 'fbps_album_' . $id ); 
  374. if( isset( $saved_album['items'] ) ) { 
  375. foreach( $saved_album['items'] as $saved_item ) { 
  376. if( isset( $saved_item['wp_photo_id'] ) ) { 
  377. wp_delete_attachment( $saved_item['wp_photo_id'], true ); 
  378. delete_option( 'fbps_album_' . $id ); 
  379. $data = array( 
  380. 'id' => esc_attr( $id ) 
  381. ); 
  382. wp_send_json_success( $data ); 
  383. } else { 
  384. $data = array( 
  385. 'id' => esc_attr( $id ) 
  386. ); 
  387. wp_send_json_error( $data ); 
  388.  
  389. public function add_menu_page() { 
  390. add_options_page( 'FB Photo Sync', 'FB Photo Sync', 'manage_options', 'fb-photo-sync', array( $this, 'display_options_page' ) ); 
  391.  
  392. public function display_options_page() { 
  393. $current = isset( $_GET['tab'] ) ? $_GET['tab'] : 'import'; 
  394. $this->admin_tabs( $current ); 
  395. $this->admin_content( $current ); 
  396. ?> 
  397. <div id="fb-root"></div> 
  398. <script> 
  399. var fbps_app_id = "<?php echo esc_js( get_option( 'fbps_app_id' ) ); ?>"; 
  400. function statusChangeCallback(response) { 
  401. if (response.status === 'connected') { 
  402. testAPI(); 
  403. } else if (response.status === 'unknown') { 
  404. document.getElementById('status').innerHTML = '<p>Please log ' + 'into this app.</p>'; 
  405. jQuery('.fbps-enabled').hide(); 
  406. } else { 
  407. document.getElementById('status').innerHTML = '<p>Please log ' + 'into Facebook.</p>'; 
  408. jQuery('.fbps-enabled').hide(); 
  409.  
  410. function checkLoginState() { 
  411. FB.getLoginStatus(function(response) { 
  412. statusChangeCallback(response); 
  413. }); 
  414.  
  415. window.fbAsyncInit = function() { 
  416. FB.init({ 
  417. appId: fbps_app_id,  
  418. status: true,  
  419. cookie: true,  
  420. xfbml: true,  
  421. version: 'v2.4' 
  422. }); 
  423.  
  424. FB.getLoginStatus(function(response) { 
  425. statusChangeCallback(response); 
  426. }); 
  427. }; 
  428.  
  429. (function(d, s, id) { 
  430. var js, fjs = d.getElementsByTagName(s)[0]; 
  431. if(d.getElementById(id)) {return;} 
  432. js = d.createElement(s); js.id = id; 
  433. js.src = "//connect.facebook.net/en_US/sdk.js"; 
  434. fjs.parentNode.insertBefore(js, fjs); 
  435. }(document, 'script', 'facebook-jssdk')); 
  436.  
  437. function testAPI() { 
  438. FB.api('/me', function(response) { 
  439. document.getElementById('status').innerHTML = '<p>Thanks for logging in, <a href="' + response.link + '" target="_blank">' + response.name + '</a>!</p>'; 
  440. }); 
  441.  
  442. FB.api('/' + fbps_app_id + '?fields=id, icon_url, name', function(response) { 
  443. document.getElementById('fbps-app').innerHTML = '<p><img src="' + response.icon_url + '" /> ' + response.name + '</p>'; 
  444. }); 
  445.  
  446. jQuery('.fbps-enabled').show(); 
  447. </script> 
  448. <?php