PageRenderTime 355ms CodeModel.GetById 83ms RepoModel.GetById 0ms app.codeStats 1ms

/wordpress/wp-content/plugins/picasa-express-x2/picasa-express-2.php

https://bitbucket.org/mpizza/aws-pizza
PHP | 2467 lines | 1774 code | 277 blank | 416 comment | 280 complexity | 2d5b5ce85bb97567495a9b954e63b1b3 MD5 | raw file
  1. <?php
  2. /*
  3. Plugin Name: Picasa Express x2
  4. Plugin URI: http://wott.info/picasa-express
  5. Description: Browse, search and select photos from any publicly available Google+/Picasa Web Album and add them to your post/pages.
  6. Version: 2.0.2
  7. Author: gjanes
  8. Author URI: http://www.janesfamily.org
  9. Text Domain: pe2
  10. Domain Path: /
  11. Thank you to Wott (wotttt@gmail.com | http://wott.info/picasa-express) for plugin
  12. Picasa Express 2.0. This plugin contained a large re-write and many improvements
  13. of the plugin: Picasa Image Express 2.0 RC2
  14. Thank you to Scrawl ( scrawl@psytoy.net ) for plugin Picasa Image Express 2.0 RC2
  15. for main idea and Picasa icons
  16. Copyright 2013 gjanes ( email : gcj.wordpress@janesfamily.org )
  17. This program is free software; you can redistribute it and/or modify
  18. it under the terms of the GNU General Public License, version 2, as
  19. published by the Free Software Foundation.
  20. This program is distributed in the hope that it will be useful,
  21. but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. GNU General Public License for more details.
  24. You should have received a copy of the GNU General Public License
  25. along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. */
  27. define( 'PE2_VERSION', '2.0.2' );
  28. if (!class_exists("PicasaExpressX2")) {
  29. class PicasaExpressX2 {
  30. /**
  31. * Define options and default values
  32. * @var array
  33. */
  34. var $options = array(
  35. 'pe2_configured' => false,
  36. 'pe2_icon' => 1,
  37. 'pe2_roles' => array('administrator'=>1),
  38. 'pe2_level' => 'blog',
  39. 'pe2_user_name' => 'undefined',
  40. 'pe2_caption' => 0,
  41. 'pe2_video_overlay' => 1,
  42. 'pe2_title' => 1,
  43. 'pe2_link' => 'thickbox_custom',
  44. 'pe2_relate_images' => '1',
  45. 'pe2_img_align' => 'left',
  46. 'pe2_auto_clear' => '1',
  47. 'pe2_img_css' => '',
  48. 'pe2_img_style' => '',
  49. 'pe2_featured_tag' => 1,
  50. 'pe2_additional_tags' => '',
  51. 'pe2_gal_align' => 'left',
  52. 'pe2_gal_css' => '',
  53. 'pe2_gal_style' => '',
  54. 'pe2_img_sort' => 0,
  55. 'pe2_img_asc' => 1,
  56. 'pe2_dialog_crop' => 1,
  57. 'pe2_max_albums_displayed' => '',
  58. 'pe2_gal_order' => 0,
  59. 'pe2_token' => '',
  60. 'pe2_footer_link' => 1,
  61. 'pe2_donate_link' => 1,
  62. 'pe2_save_state' => 1,
  63. 'pe2_saved_state' => '',
  64. 'pe2_last_album' => '',
  65. 'pe2_saved_user_name' => '',
  66. 'pe2_large_limit' => '',
  67. 'pe2_single_image_size' => 'w400',
  68. 'pe2_single_video_size' => 'w400',
  69. );
  70. /**
  71. * plugin URL
  72. * @var string
  73. */
  74. var $plugin_URL;
  75. /**
  76. * Google auth plugin URL
  77. * @var string
  78. */
  79. var $google_authorize_plugin_URL;
  80. /**
  81. * plugin photos displayed
  82. * @var array
  83. */
  84. var $photos_displayed;
  85. function PicasaExpressX2() {
  86. // Hook for plugin de/activation
  87. $multisite = false;
  88. if (
  89. (function_exists('is_multisite') && is_multisite()) || // new version check
  90. (function_exists('activate_sitewide_plugin')) // pre 3.0 version check
  91. ){
  92. $multisite = true;
  93. register_activation_hook( __FILE__, array (&$this, 'init_site_options' ) );
  94. register_deactivation_hook( __FILE__, array (&$this, 'delete_site_options' ) );
  95. } else {
  96. register_activation_hook( __FILE__, array (&$this, 'init_options' ) );
  97. register_deactivation_hook( __FILE__, array (&$this, 'delete_options' ) );
  98. }
  99. // Retrieve plugin options from database if plugin configured
  100. if (!$this->options['pe2_configured']) {
  101. // get plugin URL
  102. $this->plugin_URL = plugins_url().'/'.dirname(plugin_basename(__FILE__));
  103. // figure out the authorize URL and capitalize the URL properly to get by
  104. // the bug in google authorize
  105. $tmp = parse_url(plugins_url());
  106. $tmp2 = explode('.', $tmp['host']);
  107. $tmp2 = array_map('ucwords', $tmp2);
  108. $tmp_host = implode('.', $tmp2);
  109. $this->google_authorize_plugin_URL = $tmp['scheme'].'://'.$tmp_host.$tmp['path'].'/'.plugin_basename(__FILE__);
  110. unset($tmp, $tmp2, $tmp_host);
  111. // define the empty array used to keep track of photos displayed
  112. // (thus preventing duplicates in lightbox/thickbox/highslide nav
  113. $this->photos_displayed = array();
  114. foreach ($this->options as $key => $option) {
  115. $this->options[$key] = get_option($key,$option);
  116. if (!preg_match('/^[whs]\d+$/',$this->options['pe2_large_limit']))
  117. $this->options['pe2_large_limit'] = '';
  118. }
  119. if ($this->options['pe2_configured']) {
  120. if (is_admin()) {
  121. // loading localization if exist
  122. add_action('init', array(&$this, 'load_textdomain'));
  123. // Add settings to the plugins management page under
  124. add_filter('plugin_action_links_'.plugin_basename(__FILE__), array(&$this, 'add_settings_link'));
  125. // Add a page which will hold the Options form
  126. add_action('admin_menu', array(&$this, 'add_settings_page'));
  127. add_filter('contextual_help', array(&$this, 'contextual_help'), 10 , 2);
  128. // Add media button to editor
  129. add_action('media_buttons', array(&$this, 'add_media_button'), 20);
  130. // Add iframe page creator
  131. add_action('media_upload_picasa', array(&$this, 'media_upload_picasa'));
  132. // AJAX request from media_upload_picasa iframe script ( pe2-scripts.js )
  133. add_action('wp_ajax_pe2_get_gallery', array(&$this, 'get_gallery'));
  134. add_action('wp_ajax_pe2_get_images', array(&$this, 'get_images'));
  135. add_action('wp_ajax_pe2_save_state', array(&$this, 'save_state'));
  136. // Add setting for user profile if capable
  137. add_action('show_user_profile', array(&$this, 'user_profile'));
  138. add_action('personal_options_update', array(&$this, 'user_update'));
  139. // new site creation
  140. if ($multisite && function_exists('get_site_option') && get_site_option('pe2_multisite'))
  141. add_action('wpmu_new_blog', array(&$this, 'wpmu_new_blog') );
  142. } else {
  143. /* Attach stylesheet in the user page
  144. * you can enable attach styles if define some special
  145. */
  146. // add_action('wp_head', array(&$this, 'add_style'));
  147. add_shortcode('pe2-gallery', array(&$this, 'gallery_shortcode'));
  148. add_shortcode('pe2-image', array(&$this, 'image_shortcode'));
  149. add_shortcode('clear', array(&$this, 'clear_shortcode'));
  150. if ($this->options['pe2_footer_link']) {
  151. add_action('wp_footer', array(&$this, 'add_footer_link'));
  152. }
  153. }}
  154. }
  155. }
  156. /**
  157. * Walk all blogs and apply $func to every founded
  158. *
  159. * @global integer $blog_id
  160. * @param function $func Function to apply changes to blog
  161. */
  162. function walk_blogs($func) {
  163. $walk = isset($_GET['networkwide'])||isset($_GET['sitewide']); // (de)activate by command from site admin
  164. if (function_exists('get_site_option')) {
  165. $active_sitewide_plugins = (array) maybe_unserialize( get_site_option('active_sitewide_plugins') );
  166. $walk = $walk || isset($active_sitewide_plugins[plugin_basename(__FILE__)]);
  167. }
  168. if ( $walk && function_exists('switch_to_blog')) {
  169. add_site_option('pe2_multisite', true);
  170. global $blog_id, $switched_stack, $switched;
  171. $saved_blog_id = $blog_id;
  172. global $wpdb;
  173. $blogs = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0'");
  174. if( is_array( $blogs ) ) {
  175. reset( $blogs );
  176. foreach ( (array) $blogs as $new_blog_id ) {
  177. switch_to_blog($new_blog_id);
  178. $this->$func();
  179. array_pop( $switched_stack ); // clean
  180. }
  181. switch_to_blog($saved_blog_id);
  182. array_pop( $switched_stack ); // clean
  183. $switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 );
  184. }
  185. } else {
  186. $this->$func();
  187. }
  188. }
  189. function init_site_options() {
  190. $this->walk_blogs('init_options');
  191. }
  192. function delete_site_options() {
  193. $this->walk_blogs('delete_options');
  194. if (function_exists('delete_site_option')) delete_site_option('pe2_multisite');
  195. }
  196. function wpmu_new_blog($new_blog_id) {
  197. switch_to_blog($new_blog_id);
  198. $this->init_options();
  199. restore_current_blog();
  200. }
  201. /**
  202. * Enable plugin configuration and set roles by config
  203. */
  204. function init_options() {
  205. add_option('pe2_configured',true);
  206. foreach (get_option('pe2_roles',$this->options['pe2_roles']) as $role=>$data) {
  207. if ($data) {
  208. $role = get_role($role);
  209. $role->add_cap('picasa_dialog');
  210. }
  211. }
  212. }
  213. /**
  214. * Delete plugin configuration flag
  215. */
  216. function delete_options() {
  217. delete_option('pe2_configured');
  218. }
  219. function load_textdomain() {
  220. if ( function_exists('load_plugin_textdomain') ) {
  221. load_plugin_textdomain('pe2', false, dirname( plugin_basename( __FILE__ ) ) );
  222. }
  223. }
  224. function add_footer_link() {
  225. echo "<p class=\"footer-link\" style=\"font-size:75%;text-align:center;\"><a href=\"http://wott.info/\">".__('With Picasa plugin by Geoff Janes &amp; Wott','pe2')."</a></p>";
  226. }
  227. /**
  228. * Echo the link with icon to run plugin dialog
  229. *
  230. * @param string $id optinal id for link to plugin dialog
  231. * @return void
  232. */
  233. function add_media_button($id = '') {
  234. if (!current_user_can('picasa_dialog')) return;
  235. $plugin_URL = $this->plugin_URL;
  236. $icon = $this->options['pe2_icon'];
  237. // 'type=picasa' => 'media_upload_picasa' action above
  238. $media_picasa_iframe_src = "media-upload.php?type=picasa&tab=type&TB_iframe=true&width=640&height=566";
  239. $media_picasa_title = __("Add Picasa image or gallery", 'pe2');
  240. $put_id = ($id)?"id=\"$id-picasa_dialog\"":'';
  241. echo "<a href=\"$media_picasa_iframe_src\" $put_id class=\"thickbox\" title=\"$media_picasa_title\"><img src=\"$plugin_URL/icon_picasa$icon.gif\" alt=\"$media_picasa_title\" /></a>";
  242. }
  243. /**
  244. * Config scrips and styles and print iframe content for dialog
  245. *
  246. */
  247. function media_upload_picasa() {
  248. if (!current_user_can('picasa_dialog')) return;
  249. // add script and style for dialog
  250. add_action('admin_print_styles', array(&$this, 'add_style'));
  251. add_action('admin_print_scripts', array(&$this, 'add_script'));
  252. // we do not need default script for media_upload
  253. $to_remove = explode(',', 'swfupload-all,swfupload-handlers,image-edit,set-post-thumbnail,imgareaselect');
  254. foreach ($to_remove as $handle) {
  255. if (function_exists('wp_dequeue_script')) wp_dequeue_script($handle);
  256. else wp_deregister_script($handle);
  257. }
  258. // but still reuse code for make media_upload iframe
  259. return wp_iframe(array(&$this, 'type_dialog'));
  260. }
  261. /**
  262. * Attach script and localisation text in dialog
  263. * run from action 'admin_print_scripts' from {@link media_upload_picasa()}
  264. *
  265. * @global object $wp_scripts
  266. */
  267. function add_script() {
  268. global $wp_scripts;
  269. $wp_scripts->add('pe2-script', $this->plugin_URL.'/pe2-scripts.js', array('jquery'),PE2_VERSION);
  270. $options = array(
  271. 'waiting' => str_replace('%pluginpath%', $this->plugin_URL, __("<img src='%pluginpath%/loading.gif' height='16' width='16' /> Please wait", 'pe2')),
  272. 'env_error' => __("Error: Can not insert image(s) due wrong envirionment\nCheck script media-upload.js in the parent/editor window", 'pe2'),
  273. 'image' => __('Image', 'pe2'),
  274. 'gallery' => __('Gallery', 'pe2'),
  275. 'reload' => __('Reload', 'pe2'),
  276. 'options' => __('Options', 'pe2'),
  277. 'album' => __('Album', 'pe2'),
  278. 'shortcode' => __('Shortcode', 'pe2'),
  279. 'thumb_w' => get_option('thumbnail_size_w'),
  280. 'thumb_h' => get_option('thumbnail_size_h'),
  281. 'thumb_crop'=> get_option('thumbnail_crop'),
  282. 'state' => 'albums',
  283. );
  284. foreach ( $this->options as $key => $val ) {
  285. if (!is_array($val)) // skip arrays: pe2_roles
  286. $options[$key]=$val;
  287. }
  288. if ($this->options['pe2_level'] == 'user') {
  289. global $current_user;
  290. $options['pe2_save_state'] = get_user_meta($current_user->data->ID,'pe2_save_state',true);
  291. $options['pe2_saved_state'] = get_user_meta($current_user->data->ID,'pe2_saved_state',true);
  292. $options['pe2_last_album'] = get_user_meta($current_user->data->ID,'pe2_last_album',true);
  293. $options['pe2_saved_user_name'] = get_user_meta($current_user->data->ID,'pe2_saved_user_name',true);
  294. $options['pe2_user_name'] = get_user_meta($current_user->data->ID,'pe2_user_name',true);
  295. }
  296. if ($options['pe2_save_state']) {
  297. if ($options['pe2_saved_state']) $options['state'] = $options['pe2_saved_state'];
  298. if ($options['pe2_saved_user_name']) $options['pe2_user_name'] = $options['pe2_saved_user_name'];
  299. }
  300. $options['pe2_user_name'] = trim($options['pe2_user_name']);
  301. if (''==$options['pe2_user_name']) $options['pe2_user_name']='undefined';
  302. if ('undefined'==$options['pe2_user_name']) $options['state']= 'nouser';
  303. foreach ( $options as $key => $val ) {
  304. $options[$key] = rawurlencode($val);
  305. }
  306. $wp_scripts->localize( 'pe2-script', 'pe2_options', $options );
  307. $wp_scripts->enqueue('pe2-script');
  308. }
  309. /**
  310. * Request styles
  311. * run by action 'admin_print_styles' from {@link media_upload_picasa()}
  312. *
  313. * @global boolean $is_IE
  314. */
  315. function add_style() {
  316. global $is_IE;
  317. wp_enqueue_style('media');
  318. wp_enqueue_style('pe2-style', $this->plugin_URL.'/picasa-express-2.css',array(),PE2_VERSION,'all');
  319. if ($is_IE)
  320. wp_enqueue_style('pe2-style-ie', $this->plugin_URL.'/picasa-express-2-IE.css',array(),PE2_VERSION,'all');
  321. }
  322. /**
  323. * Print dialog html
  324. * run by parameter in (@link wp_iframe()}
  325. *
  326. * @global object $current_user
  327. */
  328. function type_dialog() {
  329. /*
  330. <a href="#" class="button alignright">Search</a>
  331. <form><input type="text" class="alignright" value="Search ..."/></form>
  332. */
  333. ?>
  334. <div id="pe2-nouser" class="pe2-header" style="display:none;">
  335. <input type="text" class="alignleft" value="user name"/>
  336. <a id="pe2-change-user" href="#" class="button alignleft pe2-space"><?php _e('Change user', 'pe2')?></a>
  337. <a id="pe2-cu-cancel" href="#" class="button alignleft pe2-space"><?php _e('Cancel', 'pe2')?></a>
  338. <div id="pe2-message1" class="alignleft"></div>
  339. <br style="clear:both;"/>
  340. </div>
  341. <div id="pe2-albums" class="pe2-header" style="display:none;">
  342. <a id="pe2-user" href="#" class="button alignleft"></a>
  343. <div id="pe2-message2" class="alignleft"><?php _e('Select an Album', 'pe2')?></div>
  344. <a id="pe2-switch2" href="#" class="button alignleft"><?php _e('Album', 'pe2')?></a>
  345. <a href="#" class="pe2-options button alignright pe2-space" ><?php _e('Options','pe2'); ?></a>
  346. <a href="#" class="pe2-reload button alignright" ></a>
  347. <br style="clear:both;"/>
  348. </div>
  349. <div id="pe2-images" class="pe2-header" style="display:none;">
  350. <a id="pe2-album-name" href="#" class="button alignleft"><?php _e('Select an Album', 'pe2')?></a>
  351. <div id="pe2-message3" class="alignleft"><?php _e('Select images', 'pe2')?></div>
  352. <a id="pe2-switch" href="#" class="button alignleft"><?php _e('Image', 'pe2')?></a>
  353. <a id="pe2-insert" href="#" class="button alignleft pe2-space" style="display:none;"><?php _e('Insert', 'pe2')?></a>
  354. <a href="#" class="pe2-options button alignright pe2-space" ></a>
  355. <a href="#" class="pe2-reload button alignright" ></a>
  356. <br style="clear:both;"/>
  357. </div>
  358. <div id="pe2-options" style="display:none;">
  359. <h3><?php _e('Image properties', 'pe2') ?></h3>
  360. <table class="form-table">
  361. <?php
  362. // ---------------------------------------------------------------------
  363. // single image thunbnail size (override)
  364. $option = $this->options['pe2_single_image_size'];
  365. preg_match('/(\w)(\d+)/',$option,$mode);
  366. if(strpos($option, '-c') !== false)
  367. $crop = true;
  368. else
  369. $crop = false;
  370. if (!$mode) $mode=array('','','');
  371. $this->make_settings_row(
  372. __('Single image thumbnail size', 'pe2'),
  373. '<input type="hidden" name="pe2_single_image_size" id="pe2_single_image_size" value="'.$option.'" />Scale: &nbsp; &nbsp;[ <label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="w" '.checked($mode[1], 'w', false).' /> '.__('width','pe2').'</label> &nbsp; '.
  374. '<label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="h" '.checked($mode[1], 'h', false).' /> '.__('height','pe2').'</label> &nbsp; '.
  375. '<label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="s" '.checked($mode[1], 's', false).' /> '.__('any','pe2').'</label> '.
  376. __(' ]&nbsp; &nbsp; proportionally to ','pe2').
  377. '<input type="text" name="pe2_single_image_size_dimension" class="pe2_single_image_size" style="width:60px;" id="pe2_single_image_size_dimension" value="'.$mode[2].'" />'.
  378. __(' pixels.','pe2').
  379. '<label> &nbsp; &nbsp; &nbsp; <input type="checkbox" name="pe2_single_image_size_crop" class="pe2_single_image_size" value="-c" '.checked($crop, true, false).' /> '.__(' Crop image into a square.','pe2').'</label> '
  380. ,
  381. sprintf(__('Value \'%s\' will be used to set single image thumbnail size'),"<span id=\"pe2_single_image_size_message_option\">$option</span>"),
  382. '',
  383. 'id="pe2_single_image_size_message" style="display:'.(($option) ? 'block' : 'none').';"'
  384. );
  385. ?>
  386. <style type="text/css">
  387. input:disabled {
  388. background-color: #eee;
  389. }
  390. </style>
  391. <script type="text/javascript">
  392. function pe2_compute_image_size(mode,value,type) {
  393. var target_input = jQuery('input[name=pe2_' + type + '_size]');
  394. if(target_input.length == 0){
  395. // this is the large image size selection
  396. target_input = jQuery('input[name=pe2_' + type + '_limit]');
  397. }
  398. var val = target_input.val();
  399. // check for the case where it was just enabled after having
  400. // been disabled and saved
  401. if((val == '') || (val == 'w')){
  402. // override with some default
  403. val = 'w600';
  404. }
  405. // split into our parts
  406. var parts = {
  407. mode : val.substring(0, 1),
  408. size : val.replace(/^[a-z]*([0-9]*).*$/,'$1'),
  409. crop : val.replace(/^[a-z]*[0-9]*(.*)$/,'$1')};
  410. // override the particular part that was just changed
  411. parts[mode] = value;
  412. // store the value back in our target
  413. target_input.val(parts.mode+parts.size+parts.crop);
  414. // update the text that displays the setting being used
  415. jQuery('#pe2_' + type + '_size_message_option').text(parts.mode+parts.size+parts.crop);
  416. // if the target inputs type is hidden, then also trigger
  417. // the .change event (hiddens don't automatically trigger
  418. // the .change event for some reason)
  419. if(target_input.attr('type') == 'hidden'){
  420. target_input.trigger('change');
  421. }
  422. }// end function pe2_compute_image_size(..)
  423. // if mode changes, update image size
  424. jQuery('input[name=pe2_single_image_size_mode]').change(function(){ if (jQuery(this).attr('checked')) pe2_compute_image_size('mode',jQuery(this).val(), 'single_image'); });
  425. // if size changes, update image size
  426. jQuery('input[name=pe2_single_image_size_dimension]').change(function(){
  427. pe2_compute_image_size('size',jQuery('input[name=pe2_single_image_size_dimension]').val(), 'single_image');
  428. });
  429. // if crop changes, update image size
  430. jQuery('input[name=pe2_single_image_size_crop]').change(function(){
  431. pe2_determine_crop('single_image', this);
  432. });
  433. function pe2_determine_crop(name, obj){
  434. // use the checked selector to determine if the checkbox is
  435. // checked or not
  436. if(jQuery('input[name=pe2_' + name + '_size_crop]:checked').length > 0){
  437. // the checkbox is checked
  438. pe2_compute_image_size('crop',jQuery(obj).val(), name);
  439. }else{
  440. // the checkbox is not checked
  441. pe2_compute_image_size('crop','',name);
  442. }
  443. }
  444. </script>
  445. <?php
  446. // ---------------------------------------------------------------------
  447. // single video thunbnail size (override)
  448. $option = $this->options['pe2_single_video_size'];
  449. preg_match('/(\w)(\d+)/',$option,$mode);
  450. if(strpos($option, '-c') !== false)
  451. $crop = true;
  452. else
  453. $crop = false;
  454. if (!$mode) $mode=array('','','');
  455. $this->make_settings_row(
  456. __('Single video thumbnail size', 'pe2'),
  457. '<input type="hidden" name="pe2_single_video_size" id="pe2_single_video_size" value="'.$option.'" />Scale: &nbsp; &nbsp;[ <label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="w" '.checked($mode[1], 'w', false).' /> '.__('width','pe2').'</label> &nbsp; '.
  458. '<label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="h" '.checked($mode[1], 'h', false).' /> '.__('height','pe2').'</label> &nbsp; '.
  459. '<label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="s" '.checked($mode[1], 's', false).' /> '.__('any','pe2').'</label> '.
  460. __(' ]&nbsp; &nbsp; proportionally to ','pe2').
  461. '<input type="text" name="pe2_single_video_size_dimension" class="pe2_single_video_size" style="width:60px;" id="pe2_single_video_size_dimension" value="'.$mode[2].'" />'.
  462. __(' pixels.','pe2').
  463. '<label> &nbsp; &nbsp; &nbsp; <input type="checkbox" name="pe2_single_video_size_crop" class="pe2_single_video_size" value="-c" '.checked($crop, true, false).' /> '.__(' Crop image into a square.','pe2').'</label> '
  464. ,
  465. sprintf(__('Value \'%s\' will be used to set single video thumbnail size'),"<span id=\"pe2_single_video_size_message_option\">$option</span>"),
  466. '',
  467. 'id="pe2_single_video_size_message" style="display:'.(($option) ? 'block' : 'none').';"'
  468. );
  469. ?>
  470. <script type="text/javascript">
  471. // if mode changes, update image size
  472. jQuery('input[name=pe2_single_video_size_mode]').change(function(){ if (jQuery(this).attr('checked')) pe2_compute_image_size('mode',jQuery(this).val(), 'single_video'); });
  473. // if size changes, update image size
  474. jQuery('input[name=pe2_single_video_size_dimension]').change(function(){
  475. pe2_compute_image_size('size',jQuery('input[name=pe2_single_video_size_dimension]').val(), 'single_video');
  476. });
  477. // if crop changes, update image size
  478. jQuery('input[name=pe2_single_video_size_crop]').change(function(){
  479. pe2_determine_crop('single_video', this);
  480. });
  481. </script>
  482. <?
  483. $option = $this->options['pe2_caption'];
  484. $this->make_settings_row(
  485. __('Display caption', 'pe2'),
  486. '<label><input type="checkbox" name="pe2_caption" value="1" '.checked($option,'1',false).' /> '.__('Show the caption under thumbnail image', 'pe2').'</label> '
  487. );
  488. $option = $this->options['pe2_title'];
  489. $this->make_settings_row(
  490. __('Add caption as title', 'pe2'),
  491. '<label><input type="checkbox" name="pe2_title" value="1" '.checked($option,'1',false).' /> '.__('Show the caption by mouse hover tip', 'pe2').'</label> '
  492. );
  493. $opts = array (
  494. 'none' => __('No link', 'pe2'),
  495. 'direct' => __('Direct link', 'pe2'),
  496. 'picasa' => __('Link to Picasa Web Album', 'pe2'),
  497. 'lightbox' => __('Lightbox', 'pe2'),
  498. 'thickbox' => __('Thickbox (External)', 'pe2'),
  499. 'thickbox_integrated' => __('Thickbox (Integrated Wordpress version)', 'pe2'),
  500. 'thickbox_custom' => __('Thickbox (Custom from this plugin)', 'pe2'),
  501. 'highslide'=> __('Highslide', 'pe2'),
  502. );
  503. $is_gallery = array (
  504. 'none' => 'false',
  505. 'direct' => 'false',
  506. 'picasa' => 'false',
  507. 'lightbox' => 'true',
  508. 'thickbox' => 'true',
  509. 'thickbox_integrated' => 'true',
  510. 'thickbox_custom' => 'true',
  511. 'highslide'=> 'true',
  512. );
  513. $is_gallery_js = 'var is_gallery = { ';
  514. foreach ($is_gallery as $key=>$val) {
  515. $is_gallery_js .= "$key:$val,";
  516. }
  517. $is_gallery_js = trim($is_gallery_js, ',').' };';
  518. ?>
  519. <script type="text/javascript">
  520. function handle_gallery_properties(t) {
  521. <?php echo $is_gallery_js; ?>
  522. if (is_gallery[t]) {
  523. jQuery('#gallery_properties').show();
  524. jQuery('#gallery-message').show();
  525. jQuery('#nogallery_properties').hide();
  526. } else {
  527. jQuery('#gallery_properties').hide();
  528. jQuery('#gallery-message').hide();
  529. jQuery('#nogallery_properties').show();
  530. }
  531. }
  532. </script>
  533. <?php
  534. $out = '<select name="pe2_link" onchange="handle_gallery_properties(this.value);">';
  535. $option = $this->options['pe2_link'];
  536. foreach ($opts as $key => $val ) {
  537. $out .= "<option value=\"$key\" ".selected($option, $key, false ).">$val</option>";
  538. }
  539. $out .= '</select>';
  540. $this->make_settings_row(
  541. __('Link to larger image', 'pe2'),
  542. $out,
  543. __('To use external libraries like Thickbox, Lightbox or Highslide you need to install and integrate the library independently','pe2'),
  544. '',
  545. 'id="gallery-message" style="display:'.(($is_gallery[$option]=='true') ? 'block' : 'none').';"'
  546. );
  547. $option = $this->options['pe2_relate_images'];
  548. $this->make_settings_row(
  549. __('Relate all of a post\'s images', 'pe2'),
  550. '<label><input type="checkbox" name="pe2_relate_images" value="1" '.checked($option,'1',false).' /> '.__('If using Thickbox, Lightbox or Highslide, relate all images in the page/post together for fluid next/prev navigation', 'pe2').'</label> '
  551. );
  552. $opts = array (
  553. 'none' => __('None'),
  554. 'left' => __('Left'),
  555. 'center' => __('Center'),
  556. 'right' => __('Right'),
  557. );
  558. $option = $this->options['pe2_img_align'];
  559. $out = '';
  560. foreach ($opts as $key => $val ) {
  561. $out .= "<input type=\"radio\" name=\"pe2_img_align\" id=\"img-align$key\" value=\"$key\" ".checked($option, $key, false)." /> ";
  562. $out .= "<label for=\"img-align$key\" style=\"padding-left:22px;margin-right:13px;\" class=\"image-align-$key-label\">$val</label>";
  563. }
  564. $this->make_settings_row(
  565. __('Image alignment', 'pe2'),
  566. $out
  567. );
  568. $option = $this->options['pe2_auto_clear'];
  569. $this->make_settings_row(
  570. __('Auto clear: both', 'pe2'),
  571. '<label><input type="checkbox" name="pe2_auto_clear" value="1" '.checked($option,'1',false).' /> '.__('Automatically add &lt;p class="clear"&gt;&lt;/p&gt; after groups of images inserted together', 'pe2').'</label> '
  572. );
  573. $this->make_settings_row(
  574. __('CSS Class', 'pe2'),
  575. '<input type="text" name="pe2_img_css" class="regular-text" value="'.esc_attr($this->options['pe2_img_css']).'"/>',
  576. __("You can define default class for images from theme's style.css", 'pe2')
  577. );
  578. $this->make_settings_row(
  579. __('Style', 'pe2'),
  580. '<input type="text" name="pe2_img_style" class="regular-text" value="'.esc_attr($this->options['pe2_img_style']).'"/>',
  581. __('You can hardcode some css attributes', 'pe2')
  582. );
  583. $this->make_settings_row(
  584. __('Album thumbnail size'),
  585. '<label for="thumbnail_size_w">'.__('Width').'</label> '.
  586. '<input name="thumb_w" type="text" id="thumbnail_size_w" value="'.esc_attr( get_option('thumbnail_size_w')).'" class="small-text" />&nbsp;&nbsp;&nbsp;'.
  587. '<label for="thumbnail_size_h">'.__('Height').'</label> '.
  588. '<input name="thumb_h" type="text" id="thumbnail_size_h" value="'.esc_attr( get_option('thumbnail_size_h')).'" class="small-text" /><br />'.
  589. '<input name="thumb_crop" type="checkbox" id="thumbnail_crop" value="1" '.checked('1', get_option('thumbnail_crop'),false).'/> '.
  590. '<label for="thumbnail_crop">'.__('Crop thumbnail to exact dimensions (normally thumbnails are proportional)').'</label>'
  591. );
  592. ?>
  593. </table>
  594. <h3><?php _e('Gallery properties', 'pe2') ?></h3>
  595. <div id="nogallery_properties" style="<?php echo ($is_gallery[$this->options['pe2_link']]=='true') ? 'display:none;' : 'display:block;'?>">
  596. <p><?php _e('To view and change properties you have to select Thickbox, Lightbox or Highslide support for the images above', 'pe2') ?></p>
  597. </div>
  598. <div id="gallery_properties" style="<?php echo ($is_gallery[$this->options['pe2_link']]=='false') ? 'display:none;' : 'display:block;'?>">
  599. <table class="form-table">
  600. <?php
  601. // display tag options
  602. $this->make_settings_row(
  603. __('Photo tag options', 'pe2'),
  604. '<input name="pe2_featured_tag" type="checkbox" id="pe2_featured_tag" value="1" '.checked('1', get_option('pe2_featured_tag'),false).'/> '.
  605. '<label for="pe2_featured_tag">'.__('Include photos from this album only if they contain the "Featured" tag').'</label><br />'.
  606. '<label for="pe2_additional_tags" style="vertical-align: top;">'.__('Additional tag(s) required').'</label> '.
  607. '<div style="display: inline-block;"><input type="text" name="pe2_additional_tags" id="pe2_additional_tags" class="regular-text" style="width: 240px;" value="'.esc_attr($this->options['pe2_additional_tags']).'"/><br/><span style="font-size: 9px;">('.__('Separate multiple tags by commas. NOTE: currently Google requires private album access for tags to work').')</span></div>'
  608. );
  609. $option = $this->options['pe2_gal_align'];
  610. $out = '';
  611. foreach ($opts as $key => $val ) {
  612. $out .= "<input type=\"radio\" name=\"pe2_gal_align\" id=\"gal-align$key\" value=\"$key\" ".checked($option, $key, false)." /> ";
  613. $out .= "<label for=\"gal-align$key\" style=\"padding-left:22px;margin-right:13px;\" class=\"image-align-$key-label\">$val</label>";
  614. }
  615. $this->make_settings_row(
  616. __('Gallery alignment', 'pe2'),
  617. $out
  618. );
  619. $this->make_settings_row(
  620. __('CSS Class', 'pe2'),
  621. '<input type="text" name="pe2_gal_css" class="regular-text" value="'.esc_attr($this->options['pe2_gal_css']).'"/>',
  622. __("You can define default class for images from theme's style.css", 'pe2')
  623. );
  624. $this->make_settings_row(
  625. __('Style', 'pe2'),
  626. '<input type="text" name="pe2_gal_style" class="regular-text" value="'.esc_attr($this->options['pe2_gal_style']).'"/>',
  627. __('You can hardcode some css attributes', 'pe2')
  628. );
  629. ?>
  630. </table>
  631. </div>
  632. </div>
  633. <div id="pe2-main">
  634. </div>
  635. <?php
  636. }
  637. /**
  638. * Request server with token if defined
  639. *
  640. * @param string $url URL for request data
  641. * @param boolean $token use token from settings
  642. * @return string received data
  643. */
  644. function get_feed($url,$token=false) {
  645. global $wp_version;
  646. // add Auth later
  647. $options = array(
  648. 'timeout' => 30 ,
  649. 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
  650. 'sslverify' => false // prevent some problems with Google in token request
  651. );
  652. if (!$token) {
  653. if ($this->options['pe2_level'] == 'user') {
  654. global $current_user;
  655. $token = get_user_meta($current_user->data->ID,'pe2_token',true);
  656. } else {
  657. $token = $this->options['pe2_token'];
  658. }
  659. }
  660. if ($token) $options['headers'] = array ( 'Authorization' =>"AuthSub token=\"$token\"" );
  661. $response = wp_remote_get($url, $options);
  662. if ( is_wp_error( $response ) )
  663. return $response;
  664. if ( 200 != $response['response']['code'] )
  665. return new WP_Error('http_request_failed', __('Response code is ').$response['response']['code']);
  666. // preg sensitive for \n\n, but we not need any formating inside
  667. return (str_replace("\n",'',trim( $response['body'] )));
  668. }
  669. /**
  670. * Find tag in content by attribute
  671. *
  672. * @param string $content
  673. * @param string $tag
  674. * @param string $attr
  675. * @return string attribute value or all parameters if not found. false if no tag found
  676. */
  677. function get_item_attr($content,$tag,$attr) {
  678. if (!preg_match("|<$tag\s+([^>]+)/?>|u",$content,$m))
  679. return false;
  680. $a = preg_split("/[\s=]/",$m[1]);
  681. for ($i=0; $i<count($a); $i+=2) {
  682. if ($a[$i]==$attr) return trim($a[$i+1],"'\" ");
  683. }
  684. return join(',',$a);
  685. }
  686. /**
  687. * Find tag in content
  688. *
  689. * @param string $content
  690. * @param string $tag
  691. * @param boolean $first Search only first. False by default
  692. * @return bool|string|array content of the found node. false if not found
  693. */
  694. function get_item($content,$tag,$first=false) {
  695. if (!preg_match_all("|<$tag(?:\s[^>]+)?>(.+?)</$tag>|u",$content,$m,PREG_PATTERN_ORDER))
  696. return false;
  697. // echo "$tag: ".count($m[1])."<br/>";
  698. if (count($m[1])>1 && !$first) return ($m[1]);
  699. else return ($m[1][0]);
  700. }
  701. /**
  702. * wp_ajax_pe2_get_gallery
  703. * print html for gallery
  704. *
  705. */
  706. function get_gallery() {
  707. if (!current_user_can('picasa_dialog')) {
  708. echo json_encode((object) array('error'=>__('Insufficient privelegies','pe2')));
  709. die();
  710. }
  711. $out = (object)array();
  712. if (isset($_POST['user'])) {
  713. $user = $_POST['user'];
  714. } else die();
  715. $rss = $this->get_feed("http://picasaweb.google.com/data/feed/base/user/$user?alt=rss&kind=album&hl=en_US");
  716. if (is_wp_error($rss)) {
  717. $out->error = $rss->get_error_message();
  718. } else if (!$this->get_item($rss,'atom:id')) {
  719. $out->error = __('Invalid picasa username: ', 'pe2').$user;
  720. } else {
  721. $items = $this->get_item($rss,'item');
  722. $output = '';
  723. if ($items) {
  724. if (!is_array($items)) $items = array($items);
  725. $output .= "\n<table><tr>\n";
  726. $i = 0;
  727. $max_albums = get_option('pe2_max_albums_displayed');
  728. foreach($items as $item) {
  729. // http://picasaweb.google.com/data/entry/base/user/wotttt/albumid/5408701349107410241?alt=rss&amp;hl=en_US
  730. $guid = str_replace("entry","feed",$this->get_item($item,'guid'))."&kind=photo";
  731. $title = $this->escape($this->get_item($item,'title'));
  732. $desc = $this->escape($this->get_item($item,'media:description'));
  733. $url = $this->get_item_attr($item,'media:thumbnail','url');
  734. $item_type = (strpos($item, 'medium=\'video\'') !== false ? 'video' : 'image');
  735. // resize the thumbnail URL so that it fits properly in the media
  736. // window
  737. $url = str_replace('s160-c', 's140-c', $url);
  738. // generate the output
  739. $output .= "<td><a href='#$guid'><img src='$url' alt='$desc' type='$item_type'/><span>$title</span></a></td>\n";
  740. // increment the shared image counter for the following
  741. // two checks
  742. $i++;
  743. // determine if we need to stop outputting albums
  744. if(($max_albums > 0) && ($i >= $max_albums)){
  745. // we've reached our max, break out of the loop
  746. break;
  747. }
  748. // determine if we need to break this row and start a new
  749. // one
  750. if ($i % 4 == 0) $output .= "</tr><tr>\n";
  751. }// end foreach album item to output
  752. $output .= "</tr></table>\n";
  753. }// end if we have items to output
  754. $out->items = $this->get_item($rss,'openSearch:totalResults');
  755. $out->title = $this->get_item($rss,'title',true);
  756. $out->data = $output;
  757. $out->cache = $_POST['cache'];
  758. }// end else for if there were any errors
  759. echo json_encode($out);
  760. die();
  761. }
  762. /**
  763. * wp_ajax_pe2_get_images
  764. * print html for images
  765. *
  766. */
  767. function get_images() {
  768. if (!current_user_can('picasa_dialog')) {
  769. echo json_encode((object) array('error'=>__('Insufficient privelegies','pe2')));
  770. die();
  771. }
  772. $out = (object)array();
  773. if (isset($_POST['guid'])) {
  774. // determine if this guid is base64 encoded or a straight album URL,
  775. // decoding if necessary
  776. if(strpos($_POST['guid'], 'http') !== 0){
  777. // decode it
  778. $album = base64_decode($_POST['guid']);
  779. }else{
  780. // simply store it after decoding any entities that may have been
  781. // created by the editor or elsewhere
  782. $album = html_entity_decode($_POST['guid']);
  783. }
  784. } else die();
  785. $rss = $this->get_feed($album);
  786. if (is_wp_error($rss)) {
  787. $out->error = $rss->get_error_message();
  788. } else if (!$this->get_item($rss,'atom:id')) {
  789. $out->error = __('Invalid album ', 'pe2');
  790. } else {
  791. $items = $this->get_item($rss,'item');
  792. $output = '';
  793. $key = 1; $images = array();
  794. $sort = $this->options['pe2_img_sort'];
  795. $dialog_crop = ($this->options['pe2_dialog_crop'] == 1 ? '-c' : '');
  796. if ($items) {
  797. if (!is_array($items)) $items = array($items);
  798. foreach($items as $item) {
  799. switch ($sort) {
  800. case 0: $key++; break;
  801. case 1: $key = strtotime($this->get_item($item,'pubDate',true)); break;
  802. case 2: $key = $this->get_item($item,'title',true); break;
  803. case 3: $key = $this->get_item($item,'media:title',true); break;
  804. }
  805. $images[$key] = array (
  806. 'album' => $this->get_item($item,'link'), // picasa album image
  807. 'title' => $this->escape($this->get_item($item,'title')),
  808. 'file' => $this->escape($this->get_item($item,'media:title')),
  809. 'desc' => $this->escape($this->get_item($item,'media:description')),
  810. 'item_type' => (strpos($item, 'medium=\'video\'') !== false ? 'video' : 'image'),
  811. 'url' => str_replace('s72','s144'.$dialog_crop,$this->get_item_attr($item,'media:thumbnail','url')),
  812. );
  813. }
  814. if ($this->options['pe2_img_asc']) ksort($images);
  815. else krsort($images);
  816. $output .= "\n<table><tr>\n";
  817. $i = 0;
  818. foreach($images as $item) {
  819. $output .= "<td><a href='{$item['album']}'><img src='{$item['url']}' alt='{$item['file']}' type='{$item['item_type']}' title='{$item['desc']}' /><span>{$item['title']}</span></a></td>\n";
  820. if ($i++%4==3) $output .= "</tr><tr>\n";
  821. }
  822. $output .= "</tr></table>\n";
  823. }
  824. // do our action for dialog footer
  825. $output = apply_filters('pe2_get_images_footer', $output);
  826. // add our successful results to the output to return
  827. $out->items = $this->get_item($rss,'openSearch:totalResults');
  828. $out->title = $this->get_item($rss,'title',true);
  829. $out->data = $output;
  830. $out->cache = $_POST['cache'];
  831. }// end else for if we had an error getting the images
  832. // output the result and exit
  833. echo json_encode($out);
  834. die();
  835. }
  836. /**
  837. * Escape quotes to html entinty
  838. *
  839. * @param <type> $str
  840. * @return <type>
  841. */
  842. function escape($str) {
  843. $str = preg_replace('/"/', '&quot;', $str);
  844. $str = preg_replace("/'/", '&#039;', $str);
  845. return $str;
  846. }
  847. /**
  848. * wp_ajax_pe2_save_state
  849. * save state of dialog
  850. */
  851. function save_state() {
  852. if (!current_user_can('picasa_dialog')) {
  853. echo json_encode((object) array('error'=>__('Insufficient privelegies','pe2')));
  854. die();
  855. }
  856. if (!isset($_POST['state'])) die();
  857. global $current_user;
  858. switch ( $saved_state = sanitize_text_field($_POST['state']) ) {
  859. case 'nouser' :
  860. case 'albums' :
  861. if ($this->options['pe2_level'] == 'user')
  862. update_user_meta($current_user->data->ID, 'pe2_saved_user_name', sanitize_text_field($_POST['last_request']) );
  863. else
  864. update_option( 'pe2_saved_user_name', sanitize_text_field($_POST['last_request']) );
  865. break;
  866. case 'images' :
  867. if ($this->options['pe2_level'] == 'user')
  868. update_user_meta($current_user->data->ID, 'pe2_last_album', sanitize_text_field($_POST['last_request']) );
  869. else
  870. update_option( 'pe2_last_album', sanitize_text_field($_POST['last_request']) );
  871. break;
  872. default:
  873. die();
  874. }
  875. if ($this->options['pe2_level'] == 'user')
  876. update_user_meta($current_user->data->ID, 'pe2_saved_state', $saved_state );
  877. else
  878. update_option( 'pe2_saved_state', $saved_state );
  879. die();
  880. }
  881. /**
  882. * Envelope content with tag
  883. * used by shortcode 'pe2_gallery'
  884. *
  885. * @param array $atts tag, class and style defined. album also
  886. * @param string $content
  887. * @return string
  888. */
  889. function gallery_shortcode($atts, $content) {
  890. extract(shortcode_atts(array(
  891. 'class' => $this->options['pe2_gal_css'],
  892. 'style' => $this->options['pe2_gal_style'],
  893. 'align' => $this->options['pe2_gal_align'],
  894. 'tag' => 'div',
  895. 'album' => '',
  896. 'thumb_w' => get_option('thumbnail_size_w'),
  897. 'thumb_h' => get_option('thumbnail_size_h'),
  898. 'thumb_crop' => get_option('thumbnail_crop'),
  899. 'img_align' => $this->options['pe2_img_align'],
  900. 'img_class' => $this->options['pe2_img_css'],
  901. 'img_style' => $this->options['pe2_img_style'],
  902. 'img_sort' => $this->options['pe2_img_sort'],
  903. 'img_asc' => $this->options['pe2_img_asc'],
  904. 'caption' => $this->options['pe2_caption'],
  905. 'pe2_title' => $this->options['pe2_title'],
  906. 'link' => $this->options['pe2_link'],
  907. 'relate_images' => $this->options['pe2_relate_images'],
  908. 'large_size' => $this->options['pe2_large_limit'],
  909. 'limit' => '',
  910. 'hide_rest' => ''
  911. ), $atts ));
  912. if ($album) {
  913. // request images for album - generate the request URL
  914. if(strpos($album, 'http') !== 0){
  915. // for backwards compatibility, decode the base64 encoded album data
  916. // stored in the tag
  917. $feed_url = base64_decode($album);
  918. }else{
  919. // simply store the album url after decoding any entities created by
  920. // the visual/HTML editor
  921. $feed_url = html_entity_decode($album);
  922. }
  923. // determine if we have any tags to send with the query
  924. if(isset($atts['tags'])){
  925. // we also have tags to query, append them
  926. $feed_url .= '&tag='.urlencode($atts['tags']).'&orderby=date';
  927. }
  928. // grab the data and process it
  929. $rss = $this->get_feed($feed_url);
  930. if (is_wp_error($rss)) {
  931. $content = $rss->get_error_message();
  932. } else if ($this->get_item($rss,'atom:id')) {
  933. $items = $this->get_item($rss,'item');
  934. $output = '';
  935. // determine if we're relating all images, or just those
  936. // in this gallery
  937. if($relate_images){
  938. // use the per-post unique ID so all images in the post
  939. // are related
  940. $uniqid = 'post-'.get_the_ID();
  941. }else{
  942. // generate a unique id for this gallery
  943. $uniqid = uniqid('');
  944. }
  945. // prepare common image attributes
  946. $iclass = explode(' ',$img_class);
  947. $istyle = array($img_style);
  948. // create align vars
  949. // for caption - align="alignclass" including alignnone also
  950. $calign = '';
  951. if ($caption) {
  952. $calign = 'align="align'.$img_align.'" ';
  953. }
  954. // new size for thumbnail
  955. $new_thumb_size = '';
  956. if ($thumb_w && $thumb_h) {
  957. // both sizes and crop
  958. if ($thumb_w == $thumb_h) {
  959. if ($thumb_crop) $new_thumb_size = '/s'.$thumb_w.'-c';
  960. else $new_thumb_size = '/s'.$thumb_w;
  961. }
  962. else if ($thumb_w > $thumb_h) $new_thumb_size = '/w'.$thumb_w;
  963. else $new_thumb_size = '/h'.$thumb_h;
  964. }
  965. else if ($thumb_w) $new_thumb_size = '/w'.$thumb_w;
  966. else if ($thumb_h) $new_thumb_size = '/h'.$thumb_h;
  967. // new size for large image
  968. $new_large_size='/s0';
  969. if ($large_size) $new_large_size = '/'.$large_size;
  970. $cdim = ($thumb_w)?('width="'.$thumb_w.'" '):'';
  971. // link and gallery additions
  972. $amore='';
  973. switch ($link) {
  974. case 'thickbox':
  975. case 'thickbox_integrated':
  976. case 'thickbox_custom':
  977. $amore = 'class="thickbox" ';
  978. if (true) $amore .= 'rel="'.$uniqid.'" ';
  979. break;
  980. case 'lightbox':
  981. $amore = (true)?('rel="lightbox-'.$uniqid.'" '):'rel="lightbox" ';
  982. break;
  983. case 'highslide':
  984. $amore = (true)?('class="highslide" onclick="return hs.expand(this,{ slideshowGroup: \''.$uniqid.'\' })"'):
  985. 'class="highslide" onclick="return hs.expand(this)"';
  986. break;
  987. }
  988. $iclass = implode(' ',array_diff($iclass,array(''))); $iclass = ($iclass)?('class="'.$iclass.'" '):'';
  989. $istyle = implode(' ',array_diff($istyle,array(''))); $istyle = ($istyle)?('style="'.$istyle.'" '):'';
  990. $key = 1; $images = array();
  991. if ($items) {
  992. if (!is_array($items)) $items = array($items);
  993. // if we're searching by tags, the RSS feed returned the results
  994. // in the order of most-recent first, which doesn't make very
  995. // much sense when considering how this works. reverse teh
  996. // array order
  997. if(isset($atts['tags'])){
  998. // we searched for tags and messed up the order, reverse it
  999. $items = array_reverse($items);
  1000. }
  1001. // loop through each and build the HTML
  1002. foreach($items as $item) {
  1003. switch ((string)$img_sort) {
  1004. case 'None':
  1005. case 'none':
  1006. case '0': $key++; break;
  1007. case 'date':
  1008. case '1': $key = strtotime($this->get_item($item,'pubDate',true)); break;
  1009. case 'Title':
  1010. case 'title':
  1011. case '2': $key = $this->get_item($item,'title',true); break;
  1012. case 'File name':
  1013. case 'File':
  1014. case 'file':
  1015. case '3': $key = $this->get_item($item,'media:title',true); break;
  1016. case 'Random':
  1017. case 'random':
  1018. case '4': $key = rand(); break;
  1019. default: $key++; break;
  1020. }
  1021. $url = $this->get_item_attr($item,'media:thumbnail','url');
  1022. $title = $this->escape($this->get_item($item,'title'));
  1023. $picasa_link = $this->get_item($item, 'link');
  1024. $images[$key] = array (
  1025. 'ialbum' => $this->get_item($item,'link'), // picasa album image
  1026. 'icaption' => $title,
  1027. 'ialt' => $this->escape($this->get_item($item,'media:title')),
  1028. 'isrc' => str_replace('/s72',$new_thumb_size,$url),
  1029. 'iorig' => str_replace('/s72',$new_large_size,$url),
  1030. 'ititle' => ($pe2_title)?'title="'.$title.'" ':'',
  1031. 'ilink' => $picasa_link,
  1032. //FIXME - CSS needs to be corrected
  1033. //'itype' => (strpos($item, 'medium=\'video\'') !== false ? 'video' : 'image')
  1034. 'itype' => ''
  1035. );
  1036. if ($limit && !$hide_rest) {
  1037. if (++$count>=$limit) break;
  1038. }
  1039. }// end foreach items to process
  1040. if ($img_asc) ksort($images);
  1041. else krsort($images);
  1042. if ($limit && $hide_rest && $limit==absint($limit)) $count=0;
  1043. else $limit=false;
  1044. foreach($images as $item) {
  1045. $img = "<img src=\"{$item['isrc']}\" alt=\"{$item['ialt']}\" type=\"{$item['itype']}\" {$item['ititle']}{$iclass}{$istyle} />";
  1046. if ($link != 'none') {
  1047. if ($link == 'picasa') $item['iorig'] = $item['ialbum'];
  1048. // determine if this particular link has been displayed
  1049. // already or not (to prevent multiple copies related
  1050. // to each other from busting the navigation)
  1051. if(in_array($item['iorig'], $this->photos_displayed)){
  1052. // this photo has already been displayed, skip relating
  1053. // it to the rest and instead make up a new relationship
  1054. // for it so that we don't break the navigation
  1055. $amore_this = str_replace($uniqid, uniqid(), $amore);
  1056. }else{
  1057. // this photo hasn't been displayed yet, it can be related
  1058. // without issue
  1059. $amore_this = $amore;
  1060. }
  1061. // store this photo in our list of displayed photos
  1062. $this->photos_displayed[] = $item['iorig'];
  1063. // create the image link
  1064. $img = "<a href=\"{$item['iorig']}\" link=\"{$item['ilink']}\" {$item['ititle']}{$amore_this}>$img</a>";
  1065. }
  1066. if ($caption) {
  1067. // add caption
  1068. $img = "[caption id=\"\" {$calign}{$cdim}caption=\"{$item['icaption']}\"]{$img}[/caption] ";
  1069. }
  1070. $output .= $img;
  1071. if ($limit) {
  1072. if (++$count>=$limit) {
  1073. $istyle=$hstyle;
  1074. $amore .= ' style="display:none;"';
  1075. $caption=false;
  1076. }
  1077. }
  1078. }
  1079. $class = array_merge( array(($align!='none')?'align'.$align:''), explode(' ',$class) );
  1080. $class = array_diff($class, array('') );
  1081. $class = implode(' ', $class );
  1082. }
  1083. }
  1084. $content .= $output;
  1085. }
  1086. $code = "<$tag class=\"pe2-album $pe2_gal_class\" style=\"$pe2_gal_style\">".do_shortcode($content)."</$tag><div class='clear'></div>";
  1087. return $code;
  1088. }
  1089. /**
  1090. * Envelope content with tag
  1091. * used by shortcode 'pe2_image'
  1092. *
  1093. * @param array $atts tag, class and style defined.
  1094. * @param string $content
  1095. * @return string
  1096. */
  1097. function image_shortcode($atts, $content) {
  1098. // extract all of the variables from defaults/options with
  1099. // any tag attribute overrides
  1100. extract(shortcode_atts(array_merge(array(
  1101. 'src' => '',
  1102. 'href' => '',
  1103. 'caption' => '',
  1104. 'type' => '',
  1105. 'alt' => '',
  1106. 'limit' => '',
  1107. 'hide_rest' => ''
  1108. ), $this->options
  1109. ), $atts )
  1110. );
  1111. // create align vars
  1112. // for caption - align="alignclass" including alignnone also
  1113. // else add alignclass to iclass
  1114. $calign = '';
  1115. $iclass = array();
  1116. if ($pe2_caption) {
  1117. $calign = 'align="align'.$pe2_img_align.'" ';
  1118. } else {
  1119. array_push($iclass,'align'.$pe2_img_align);
  1120. }
  1121. // generate the unique id if we're relating images
  1122. $uniqid = 'post-'.get_the_ID();
  1123. // link and gallery additions
  1124. $a_link_additions = '';
  1125. switch ($pe2_link) {
  1126. case 'thickbox':
  1127. case 'thickbox_integrated':
  1128. case 'thickbox_custom':
  1129. $a_link_additions = 'class="thickbox" ';
  1130. if($pe2_relate_images){
  1131. // they have chosen to relate all of the images, use the post id
  1132. $a_link_additions .= 'rel="'.$uniqid.'" ';
  1133. }
  1134. break;
  1135. case 'lightbox':
  1136. if($pe2_relate_images){
  1137. // they have chosen to relate all of the images, use the post id
  1138. $a_link_additions = 'rel="lightbox-'.$uniqid.'" ';
  1139. }else{
  1140. // separate images without navigation
  1141. $a_link_additions = 'rel="lightbox" ';
  1142. }
  1143. break;
  1144. case 'highslide':
  1145. if($pe2_relate_images){
  1146. // they have chosen to relate all of the images, use the post id
  1147. $a_link_additions = 'class="highslide" onclick="return hs.expand(this,{ slideshowGroup: \''.$uniqid.'\' })"';
  1148. }else{
  1149. // separate images without navigation
  1150. $a_link_additions = 'class="highslide" onclick="return hs.expand(this)"';
  1151. }
  1152. break;
  1153. }// end switch
  1154. // determine the type and then set the thumbnail url
  1155. $amore = '';
  1156. $imore = '';
  1157. if($type == 'image'){
  1158. // use the image size
  1159. $thumb_size = $pe2_single_image_size;
  1160. // set the link href to the large size. determine if the
  1161. // size has been defined, or if we just use the default
  1162. if($pe2_large_limit == null){
  1163. // none set, use a default
  1164. $large_size = 's0';
  1165. }else{
  1166. // use the large limit from the configuration
  1167. $large_size = $pe2_large_limit;
  1168. }
  1169. // create the a link, linking to the larger version of the image
  1170. $a_href = preg_replace('/\/(w|h|s)[0-9]+(-c|)\//', '/'.$large_size.'/', $src);
  1171. // set the amore to our a_link_additions
  1172. $amore = $a_link_additions;
  1173. }else{
  1174. // use the video size
  1175. $thumb_size = $pe2_single_video_size;
  1176. // set the link href to the picasa HREF
  1177. $a_href = $href;
  1178. // set the amore to make it open in a new tab and mark it as a video
  1179. // type, and not add in the a_link_additions configuration
  1180. $amore .= ' target="_blank" type="video"';
  1181. $imore = ' type="video"';
  1182. }// end else for if we're displaying an image
  1183. // generate the URL for the thumbnail image
  1184. $thumb_src = preg_replace('/\/(w|h|s)[0-9]+(-c|)\//', '/'.$thumb_size.'/', $src);
  1185. // add our pe2 class to the image class
  1186. $iclass[] = 'pe2-photo';
  1187. // generate the other image attributes we need
  1188. $ititle = ($pe2_title) ? 'title="'.$caption.'" ' : '';
  1189. $iclass = implode(' ', $iclass);
  1190. if($pe2_img_css){
  1191. $iclass .= ' '.$pe2_img_css;
  1192. }
  1193. if($iclass){
  1194. $iclass = 'class="'.$iclass.'" ';
  1195. }
  1196. if($pe2_img_style){
  1197. $istyle = 'style="'.$pe2_img_style.'" ';
  1198. }else{
  1199. $istyle = '';
  1200. }
  1201. // create the HTML for the image tag
  1202. $html = "<img src=\"{$thumb_src}\" alt=\"{$alt}\" {$ititle}{$iclass}{$istyle}{$imore} />";
  1203. // add the link?
  1204. if ($pe2_link != 'none') {
  1205. // the image should also have a link, determine if this particular
  1206. // link has been displayed already or not (to prevent multiple
  1207. // copies related to each other from busting the navigation)
  1208. if(in_array($a_href, $this->photos_displayed)){
  1209. // this photo has already been displayed, skip relating
  1210. // it to the rest and instead make up a new relationship
  1211. // for it so that we don't break the navigation
  1212. $amore_this = str_replace($uniqid, uniqid(), $amore);
  1213. }else{
  1214. // this photo hasn't been displayed yet, it can be related
  1215. // without issue
  1216. $amore_this = $amore;
  1217. }
  1218. // store this photo in our list of displayed photos
  1219. $this->photos_displayed[] = $a_href;
  1220. // figure out what the link is
  1221. if($link == 'picasa'){
  1222. // the large_url gets switched for the href
  1223. $a_href = $href;
  1224. }
  1225. // wrap the current image tag with the A tag, adding the "link"
  1226. // attribute so the thickbox-custom can add the link to picasa
  1227. $html = "<a href=\"{$a_href}\" link=\"{$href}\" {$ititle}{$amore_this}>$html</a>";
  1228. }// end if we need to add the link
  1229. //FIXME - this functionality has not been tested yet
  1230. if ($pe2_caption) {
  1231. // add caption
  1232. $html = "[caption id=\"\" {$calign}caption=\"{$title}\"]{$html}[/caption] ";
  1233. }
  1234. // return our processed shortcode with teh image link
  1235. return do_shortcode($html);
  1236. }// end function image_shortcode(..)
  1237. /**
  1238. * Envelope content with tag with additinoal class 'clear'
  1239. * used by shortcode 'clear'
  1240. *
  1241. * @param array $atts tag and class
  1242. * @param string $content
  1243. * @return string
  1244. */
  1245. function clear_shortcode($atts, $content) {
  1246. extract(shortcode_atts(array(
  1247. 'class' => '',
  1248. 'tag' => 'div',
  1249. ), $atts ));
  1250. $class .= (($class)?' ':'').'clear';
  1251. $code = "<$tag class='$class'>".do_shortcode($content)."</$tag>";
  1252. return $code;
  1253. }
  1254. /**
  1255. * Print and request user for Picasa in profile. Token link present
  1256. * uses if settings in user level
  1257. * run by action 'show_user_profile' from user-edit.php
  1258. *
  1259. * @param object $user
  1260. */
  1261. function user_profile($user) {
  1262. if (!current_user_can('picasa_dialog')) return;
  1263. if ($this->options['pe2_level'] != 'user') return;
  1264. $user_id = $user->ID;
  1265. if ( isset($_GET['revoke']) ) {
  1266. $response = $this->get_feed("https://www.google.com/accounts/AuthSubRevokeToken");
  1267. if ( is_wp_error( $response ) ) {
  1268. $message = __('Google return error: ','pe2').$response->get_error_message();
  1269. } else {
  1270. $message = __('Private access revoked','pe2');
  1271. }
  1272. delete_user_meta($user_id,'pe2_token');
  1273. $this->options['pe2_token'] = '';
  1274. }
  1275. if ( isset($_GET['message']) && $_GET['message']) {
  1276. $message = esc_html(stripcslashes($_GET['message']));
  1277. }
  1278. if (!get_user_meta($user_id,'pe2_user_name',true) && current_user_can('manage_options') ) {
  1279. update_user_meta($user_id,'pe2_user_name',$this->options['pe2_user_name']);
  1280. if ($this->options['pe2_token'])
  1281. update_user_meta($user_id,'pe2_token',$this->options['pe2_token']);
  1282. }
  1283. ?>
  1284. <h3><?php _e('Picasa access', 'pe2') ?></h3>
  1285. <?php
  1286. if ($message) {
  1287. echo '<div id="picasa-express-x2-message" class="updated"><p><strong>'.$message.'</strong></p></div>';
  1288. }
  1289. ?>
  1290. <table class="form-table">
  1291. <?php
  1292. $user = get_user_meta($user_id,'pe2_user_name',true);
  1293. $result = 'ok';
  1294. $response = $this->get_feed("http://picasaweb.google.com/data/feed/base/user/$user?alt=rss&kind=album&hl=en_US");
  1295. if ( is_wp_error( $response ) )
  1296. $result = 'nok: '.$response->get_error_message();
  1297. else if (!$this->get_item($response,'atom:id')) {
  1298. $result = 'nok: wrong answer';
  1299. }
  1300. if (method_exists('WP_Http', '_getTransport')) {
  1301. $ta = array(); $transports = WP_Http::_getTransport(array());
  1302. foreach ($transports as $t) $ta[] = strtolower(str_replace('WP_Http_','',get_class($t)));
  1303. if ($ta) $result = sprintf(__("checking user: %s transport: %s",'pe2'),$result,implode(',',$ta));
  1304. } else if (method_exists('WP_Http', '_get_first_available_transport')) {
  1305. $transport = WP_Http::_get_first_available_transport(array());
  1306. if ($transport) {
  1307. $transport_name = strtolower(str_replace('WP_HTTP_','',$transport));
  1308. $result = sprintf(' '.__("checking user: %s - transport: %s",'pe2'),$result,$transport_name);
  1309. }
  1310. } else {
  1311. $result = '';
  1312. }
  1313. $this->make_settings_row(
  1314. __('Picasa user name', 'pe2'),
  1315. '<input type="text" class="regular-text" name="pe2_user_name" value="'.esc_attr($user).'" />'.$result.
  1316. ((!get_user_meta($user_id,'pe2_token',true))?'<br /><a href="https://www.google.com/accounts/AuthSubRequest?next='.urlencode($this->google_authorize_plugin_URL.'?authorize&user='.$user_id).'&scope=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2F&session=1&secure=0">'.__('Requesting access to private albums', 'pe2').'</a>':'<br/><a href="?revoke=true">'.__('Revoke access to private albums', 'pe2').'</a>'),
  1317. ((get_user_meta($user_id,'pe2_token',true))?__('You already received the access to private albums', 'pe2'):__('By this link you will be redirected to the Google authorization page. Please, use same name as above to login before accept.', 'pe2'))
  1318. );
  1319. $option = get_user_meta($user_id,'pe2_save_state',true);
  1320. $this->make_settings_row(
  1321. __('Save last state', 'pe2'),
  1322. '<label><input type="checkbox" name="pe2_save_state" value="1" '.checked($option,'1',false).' /> '.__('Save last state in dialog', 'pe2').'</label> ',
  1323. __('Save user when changes, album if you insert images or albums list if you shorcode for album', 'pe2')
  1324. );
  1325. ?>
  1326. </table>
  1327. <?php
  1328. }
  1329. /**
  1330. * Save parameters and save profile
  1331. * by action 'personal_options_update' in user-edit.php
  1332. */
  1333. function user_update() {
  1334. if (!current_user_can('picasa_dialog')) return;
  1335. $user_id = sanitize_text_field($_POST['user_id']);
  1336. if ($user_id && isset($_POST['pe2_user_name']) && sanitize_text_field($_POST['pe2_user_name']) != get_user_meta($user_id,'pe2_user_name',true)) {
  1337. $picasa_user = sanitize_text_field($_POST['pe2_user_name']);
  1338. if (!$picasa_user) $picasa_user='undefined';
  1339. update_user_meta($user_id,'pe2_user_name', $picasa_user);
  1340. delete_user_meta($user_id,'pe2_token');
  1341. }
  1342. update_user_meta($user_id,'pe2_save_state', ((isset($_POST['pe2_save_state']) && $_POST['pe2_save_state'])?'1':'0'));
  1343. }
  1344. /**
  1345. * Add setting link to plugin action
  1346. * run by action 'plugin_action_links_*'
  1347. *
  1348. */
  1349. function add_settings_link($links) {
  1350. if (!current_user_can('manage_options')) return $links;
  1351. $settings_link = '<a href="options-general.php?page=picasa-express-2">'.__('Settings', 'pe2').'</a>';
  1352. array_unshift( $links, $settings_link );
  1353. return $links;
  1354. }
  1355. /**
  1356. * Config settings, add actions for registry setting and add styles
  1357. * run by action 'admin_menu'
  1358. *
  1359. */
  1360. function add_settings_page() {
  1361. if (!current_user_can('manage_options')) return;
  1362. add_options_page(__('Picasa Express x2', 'pe2'), __('Picasa Express x2', 'pe2'), 'manage_options', 'picasa-express-2', array(&$this, 'settings_form'));
  1363. add_action('admin_init', array(&$this, 'settings_reg'));
  1364. add_action('admin_print_styles-settings_page_picasa-express-2', array(&$this, 'settings_style'));
  1365. }
  1366. /**
  1367. * Register all option for save
  1368. *
  1369. */
  1370. function settings_reg() {
  1371. foreach ($this->options as $key => $option) {
  1372. if ($key != 'pe2_token') // skip token in non secure requests
  1373. register_setting( 'picasa-express-2', $key );
  1374. }
  1375. }
  1376. /**
  1377. * Define misseed style for setting page
  1378. */
  1379. function settings_style() {
  1380. $images = admin_url('images');
  1381. echo<<<STYLE
  1382. <style type="text/css" id="pe2-media" name="pe2-media">
  1383. .image-align-none-label {
  1384. background: url($images/align-none.png) no-repeat center left;
  1385. }
  1386. .image-align-left-label {
  1387. background: url($images/align-left.png) no-repeat center left;
  1388. }
  1389. .image-align-center-label {
  1390. background: url($images/align-center.png) no-repeat center left;
  1391. }
  1392. .image-align-right-label {
  1393. background: url($images/align-right.png) no-repeat center left;
  1394. }
  1395. </style>
  1396. STYLE;
  1397. }
  1398. /**
  1399. * Add help to the top of the setting page
  1400. */
  1401. function contextual_help($help, $screen) {
  1402. if ( 'settings_page_picasa-express-2' == $screen ) {
  1403. $homepage = __('Plugin homepage','pe2');
  1404. $messages = array(
  1405. __('To receive access for private album press link under username. You will be redirected to Google for grant access. If you press "Grant access" button you will be returned to settings page, but access will be granted.','pe2'),
  1406. __("In the album's images you have to press button with 'Image' button. The 'Gallery' will appear on the button and you can select several images. This can be happen if you use Thickbox, Lightbox or Highslide support.",'pe2'),
  1407. __("By default images inserted in the displayed order. If you need control the order in gallery - enable 'Selection order'.", 'pe2'),
  1408. __('To use external libraries like Thickbox, Lightbox or Highslide you need to install and integrate the library independently','pe2'),
  1409. );
  1410. $message = '<p>'.implode('</p><p>',$messages).'</p>';
  1411. $help .= <<<HELP_TEXT
  1412. <h5>Small help</h5>
  1413. $message
  1414. <div class="metabox-prefs">
  1415. <a href="http://wott.info/picasa-express">$homepage</a>
  1416. </div>
  1417. HELP_TEXT;
  1418. }
  1419. return $help;
  1420. }
  1421. /**
  1422. * Make the row from parameters for setting tables
  1423. */
  1424. function make_settings_row($title, $content, $description='', $title_pars='', $description_pars='') {
  1425. ?>
  1426. <tr valign="top" <?php echo $title_pars; ?>>
  1427. <th scope="row"><?php echo $title; ?></th>
  1428. <td>
  1429. <?php echo $content; ?>
  1430. <br />
  1431. <span class="description" <?php echo $description_pars; ?>><?php echo $description; ?></span>
  1432. </td>
  1433. </tr>
  1434. <?php
  1435. }
  1436. /**
  1437. * Show the main settings form
  1438. */
  1439. function settings_form(){
  1440. if (
  1441. ( isset($_GET['updated']) && 'true' == $_GET['updated'] ) ||
  1442. ( isset($_GET['settings-updated']) && 'true' == $_GET['settings-updated'] )
  1443. ) {
  1444. // successfully performed an update, execute any custom
  1445. // logic that can't be performed by automatic settings storage
  1446. // change 'picasa_dialog' capability to new role
  1447. $roles = get_editable_roles();
  1448. foreach ( $roles as $role => $data) {
  1449. $_role = get_role($role);
  1450. if (isset($this->options['pe2_roles'][$role]) && $this->options['pe2_roles'][$role]) {
  1451. $_role->add_cap('picasa_dialog');
  1452. } else {
  1453. $_role->remove_cap('picasa_dialog');
  1454. }
  1455. }
  1456. // update the path to wordpress, using a PHP include so that
  1457. // the file cannot be read by a request directly from the web
  1458. // For more information, see line ~2160
  1459. if(!file_exists(dirname(__FILE__).'/pe2-wp-path.php')){
  1460. // create the file containing the path
  1461. @file_put_contents(dirname(__FILE__).'/pe2-wp-path.php', '<? // AUTO-GENERATED by picasa-express-2 settings page, used in google token retrival
  1462. $pe2_wp_path = \''.str_replace('wp-admin', '', getcwd()).'\';');
  1463. }// end if we need to generate the wordpress path storage file
  1464. }// end successful settings update
  1465. if ( isset($_GET['revoke']) ) {
  1466. $response = $this->get_feed("https://www.google.com/accounts/AuthSubRevokeToken");
  1467. if ( is_wp_error( $response ) ) {
  1468. $message = __('Google return error: ','pe2').$response->get_error_message();
  1469. } else {
  1470. $message = __('Private access revoked','pe2');
  1471. }
  1472. delete_option('pe2_token');
  1473. $this->options['pe2_token'] = '';
  1474. }
  1475. if ( isset($_GET['message']) && $_GET['message']) {
  1476. $message = esc_html(stripcslashes($_GET['message']));
  1477. }
  1478. ?>
  1479. <div class="wrap">
  1480. <div id="icon-options-general" class="icon32"><br /></div>
  1481. <h2><?php _e('Picasa Express x2 settings', 'pe2')?></h2>
  1482. <?php
  1483. if (isset($message) && $message) {
  1484. echo '<div id="picasa-express-x2-message" class="updated"><p><strong>'.$message.'</strong></p></div>';
  1485. }
  1486. ?>
  1487. <form method="post" action="options.php">
  1488. <?php settings_fields( 'picasa-express-2' ); ?>
  1489. <?php if ($this->options['pe2_donate_link']) { ?>
  1490. <a href="http://wott.info/donate/" target="_blank" style="position:relative;display:block;float:right;margin:10px;height: 10px;">
  1491. <img src="http://lh6.ggpht.com/_P3-vavBhxe8/TKAJwocDI3I/AAAAAAAAAhQ/VZ9rmzWqXA4/s128/Paypal_button1.png" alt="PayPal donate" title="Donate to Wott via PayPal to support plugin development" width="128" height="62" />
  1492. </a>
  1493. <?php } ?>
  1494. <input type="hidden" name="pe2_configured" value="1" />
  1495. <h3><?php _e('Picasa access', 'pe2') ?></h3>
  1496. <table class="form-table">
  1497. <?php
  1498. $option = $this->options['pe2_roles'];
  1499. $editable_roles = get_editable_roles();
  1500. $pe2_roles = array();
  1501. foreach( $editable_roles as $role => $details ) {
  1502. $name = translate_user_role($details['name'] );
  1503. $pe2_roles[] = "<label><input name=\"pe2_roles[$role]\" type=\"checkbox\" value=\"1\" ".checked(isset($option[$role]),true,false)."/> $name</label>";
  1504. }
  1505. $out = implode('<br/>', $pe2_roles);
  1506. unset($pe2_roles);
  1507. $this->make_settings_row(
  1508. __('Assign capability to Roles', 'pe2'),
  1509. $out,
  1510. __('Roles for users who can use Picasa albums access via plugin', 'pe2')
  1511. );
  1512. $option = $this->options['pe2_level'];
  1513. $this->make_settings_row(
  1514. __('Picasa access level', 'pe2'),
  1515. '<label><input type="radio" name="pe2_level" value="blog" '.checked($option,'blog',false).' onclick="jQuery(\'.picasa-site-user\').show();" /> '.__('Blog').'</label> &nbsp; '.
  1516. '<label><input type="radio" name="pe2_level" value="user" '.checked($option,'user',false).' onclick="jQuery(\'.picasa-site-user\').hide();" /> '.__('User').'</label> ',
  1517. __('Picasa user name ( including private album access ) defined for whole blog or for every user independently', 'pe2')
  1518. );
  1519. ?>
  1520. </table>
  1521. <h3><?php _e('Display properties', 'pe2') ?></h3>
  1522. <table class="form-table">
  1523. <?php
  1524. $user = $this->options['pe2_user_name'];
  1525. if ('blog'==$this->options['pe2_level'] && $user) {
  1526. $result = 'ok';
  1527. $response = $this->get_feed("http://picasaweb.google.com/data/feed/base/user/$user?alt=rss&kind=album&hl=en_US");
  1528. if ( is_wp_error( $response ) )
  1529. $result = 'nok: '.$response->get_error_message();
  1530. else if (!$this->get_item($response,'atom:id')) {
  1531. $result = 'nok: wrong answer';
  1532. }
  1533. if (method_exists('WP_Http', '_getTransport')) {
  1534. $ta = array(); $transports = WP_Http::_getTransport(array());
  1535. foreach ($transports as $t) $ta[] = strtolower(str_replace('WP_Http_','',get_class($t)));
  1536. if ($ta) $result = sprintf(__("checking user: %s transport: %s",'pe2'),$result,implode(',',$ta));
  1537. } else if (method_exists('WP_Http', '_get_first_available_transport')) {
  1538. $transport = WP_Http::_get_first_available_transport(array());
  1539. if ($transport) {
  1540. $transport_name = strtolower(str_replace('WP_HTTP_','',$transport));
  1541. $result = sprintf(' '.__("checking user: %s - transport: %s",'pe2'),$result,$transport_name);
  1542. }
  1543. }
  1544. } else $result='';
  1545. // get our token variable
  1546. if ($this->options['pe2_level'] == 'user') {
  1547. global $current_user;
  1548. $token = get_user_meta($current_user->data->ID,'pe2_token',true);
  1549. } else {
  1550. $token = $this->options['pe2_token'];
  1551. }
  1552. $this->make_settings_row(
  1553. __('Picasa user name for site', 'pe2'),
  1554. '<input type="text" class="regular-text" name="pe2_user_name" value="'.esc_attr($user).'" />'.$result.
  1555. (($token == null)?'<br /><a href="https://www.google.com/accounts/AuthSubRequest?next='.urlencode($this->google_authorize_plugin_URL.'?authorize').'&scope=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2F&session=1&secure=0">'.__('Requesting access to private albums', 'pe2').'</a>':'<br/><a href="?page=picasa-express-2&revoke=true">'.__('Revoke access to private albums', 'pe2').'</a>'),
  1556. (($token != null)?__('You have successfully authorized access to private albums.', 'pe2'):__('By clicking this link you will be redirected to the Google authorization page. Please use the same username as what is listed above to login before authorizing.', 'pe2')),
  1557. 'class="picasa-site-user" style="display:'.(('blog'==$this->options['pe2_level'])?'table-row':'none').'"'
  1558. );
  1559. $option = $this->options['pe2_save_state'];
  1560. $this->make_settings_row(
  1561. __('Save last state', 'pe2'),
  1562. '<label><input type="checkbox" name="pe2_save_state" value="1" '.checked($option,'1',false).' /> '.__('Save last state in dialog', 'pe2').'</label> ',
  1563. __('Save the last used username when it changes, the last selected album if you insert images, or the albums list if you insert an album shorcode', 'pe2'),
  1564. 'class="picasa-site-user" style="display:'.(('blog'==$this->options['pe2_level'])?'table-row':'none').'"'
  1565. );
  1566. $opts = array(
  1567. 1 => __('Picasa squire icon', 'pe2'),
  1568. 2 => __('Picasa squire grayscale icon', 'pe2'),
  1569. 3 => __('Picasa round icon', 'pe2'),
  1570. 4 => __('Picasa round grayscale icon', 'pe2'),
  1571. );
  1572. $option = $this->options['pe2_icon'];
  1573. $out = '';
  1574. foreach ($opts as $i=>$text) {
  1575. $out .= '<label>';
  1576. $out .= "<input type=\"radio\" name=\"pe2_icon\" value=\"$i\" ".checked($option,$i,false)." />";
  1577. $out .= "<img src=\"{$this->plugin_URL}/icon_picasa$i.gif\" alt=\"$text\" title=\"$text\"/> &nbsp; ";
  1578. $out .= '</label>';
  1579. }
  1580. $this->make_settings_row(
  1581. __('Picasa icon', 'pe2'),
  1582. $out,
  1583. __('This icon marks the dialog activation link in the edit post page', 'pe2')
  1584. );
  1585. $opts = array(
  1586. 0 => __('None', 'pe2'),
  1587. 1 => __('Date', 'pe2'),
  1588. 2 => __('Title', 'pe2'),
  1589. 3 => __('File name', 'pe2'),
  1590. );
  1591. $option = $this->options['pe2_img_sort'];
  1592. $out = '';
  1593. foreach ($opts as $i=>$text) {
  1594. $out .= '<label>';
  1595. $out .= "<input type=\"radio\" name=\"pe2_img_sort\" value=\"$i\" ".checked($option,$i,false)." /> $text &nbsp; ";
  1596. $out .= '</label>';
  1597. }
  1598. $this->make_settings_row(
  1599. __('Sorting images in album', 'pe2'),
  1600. $out,
  1601. __('This option drives image sorting in the dialog', 'pe2')
  1602. );
  1603. $option = $this->options['pe2_img_asc'];
  1604. $this->make_settings_row(
  1605. __('Sorting order', 'pe2'),
  1606. '<label><input type="radio" name="pe2_img_asc" value="1" '.checked($option,'1',false).' /> '.__('Ascending', 'pe2').'</label> &nbsp; '.
  1607. '<label><input type="radio" name="pe2_img_asc" value="0" '.checked($option,'0',false).' /> '.__('Descending', 'pe2').'</label> '
  1608. );
  1609. $option = $this->options['pe2_dialog_crop'];
  1610. $this->make_settings_row(
  1611. __('Selection dialog thumbnail style', 'pe2'),
  1612. '<label><input type="radio" name="pe2_dialog_crop" value="1" '.checked($option,'1',false).' /> '.__('Crop into a square', 'pe2').'</label> &nbsp; '.
  1613. '<label><input type="radio" name="pe2_dialog_crop" value="0" '.checked($option,'0',false).' /> '.__('Scale proportionally', 'pe2').'</label> ',
  1614. __('This applies to image thumbnails only, not album cover thumbnails')
  1615. );
  1616. $option = $this->options['pe2_max_albums_displayed'];
  1617. $this->make_settings_row(
  1618. __('Maximum albums displayed', 'pe2'),
  1619. '<label>'.__('Max number of albums to display in the dialog:', 'pe2').' <input type="text" name="pe2_max_albums_displayed" value="'.$option.'" size=4 />',
  1620. __('Leave blank to display all albums', 'pe2').'</label> '
  1621. );
  1622. ?>
  1623. </table>
  1624. <h3><?php _e('Image properties', 'pe2') ?></h3>
  1625. <table class="form-table">
  1626. <?php
  1627. // ---------------------------------------------------------------------
  1628. // single image thunbnail size (override)
  1629. $option = $this->options['pe2_single_image_size'];
  1630. preg_match('/(\w)(\d+)/',$option,$mode);
  1631. if(strpos($option, '-c') !== false)
  1632. $crop = true;
  1633. else
  1634. $crop = false;
  1635. if (!$mode) $mode=array('','','');
  1636. $this->make_settings_row(
  1637. __('Single image thumbnail size', 'pe2'),
  1638. '<input type="hidden" name="pe2_single_image_size" value="'.$option.'" />Scale: &nbsp; &nbsp;[ <label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="w" '.checked($mode[1], 'w', false).' /> '.__('width','pe2').'</label> &nbsp; '.
  1639. '<label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="h" '.checked($mode[1], 'h', false).' /> '.__('height','pe2').'</label> &nbsp; '.
  1640. '<label><input type="radio" name="pe2_single_image_size_mode" class="pe2_single_image_size" value="s" '.checked($mode[1], 's', false).' /> '.__('any','pe2').'</label> '.
  1641. __(' ]&nbsp; &nbsp; proportionally to ','pe2').
  1642. '<input type="text" name="pe2_single_image_size_dimension" class="pe2_single_image_size" style="width:60px;" id="pe2_single_image_size_dimension" value="'.$mode[2].'" />'.
  1643. __(' pixels.','pe2').
  1644. '<label> &nbsp; &nbsp; &nbsp; <input type="checkbox" name="pe2_single_image_size_crop" class="pe2_single_image_size" value="-c" '.checked($crop, true, false).' /> '.__(' Crop image into a square.','pe2').'</label> '
  1645. ,
  1646. sprintf(__('Value \'%s\' will be used to set single image thumbnail size'),"<span id=\"pe2_single_image_size_message_option\">$option</span>"),
  1647. '',
  1648. 'id="pe2_single_image_size_message" style="display:'.(($option) ? 'block' : 'none').';"'
  1649. );
  1650. ?>
  1651. <style type="text/css">
  1652. input:disabled {
  1653. background-color: #eee;
  1654. }
  1655. </style>
  1656. <script type="text/javascript">
  1657. function pe2_compute_image_size(mode,value,type) {
  1658. var target_input = jQuery('input[name=pe2_' + type + '_size]');
  1659. if(target_input.length == 0){
  1660. // this is the large image size selection
  1661. target_input = jQuery('input[name=pe2_' + type + '_limit]');
  1662. }
  1663. var val = target_input.val();
  1664. // check for the case where it was just enabled after having
  1665. // been disabled and saved
  1666. if((val == '') || (val == 'w')){
  1667. // override with some default
  1668. val = 'w600';
  1669. }
  1670. // split into our parts
  1671. var parts = {
  1672. mode : val.substring(0, 1),
  1673. size : val.replace(/^[a-z]*([0-9]*).*$/,'$1'),
  1674. crop : val.replace(/^[a-z]*[0-9]*(.*)$/,'$1')};
  1675. // override the particular part that was just changed
  1676. parts[mode] = value;
  1677. // store the value back in our target
  1678. target_input.val(parts.mode+parts.size+parts.crop);
  1679. // update the text that displays the setting being used
  1680. jQuery('#pe2_' + type + '_size_message_option').text(parts.mode+parts.size+parts.crop);
  1681. // if the target inputs type is hidden, then also trigger
  1682. // the .change event (hiddens don't automatically trigger
  1683. // the .change event for some reason)
  1684. if(target_input.attr('type') == 'hidden'){
  1685. target_input.trigger('change');
  1686. }
  1687. }// end function pe2_compute_image_size(..)
  1688. // if mode changes, update image size
  1689. jQuery('input[name=pe2_single_image_size_mode]').change(function(){ if (jQuery(this).attr('checked')) pe2_compute_image_size('mode',jQuery(this).val(), 'single_image'); });
  1690. // if size changes, update image size
  1691. jQuery('input[name=pe2_single_image_size_dimension]').change(function(){
  1692. pe2_compute_image_size('size',jQuery('input[name=pe2_single_image_size_dimension]').val(), 'single_image');
  1693. });
  1694. // if crop changes, update image size
  1695. jQuery('input[name=pe2_single_image_size_crop]').change(function(){
  1696. pe2_determine_crop('single_image', this);
  1697. });
  1698. function pe2_determine_crop(name, obj){
  1699. // use the checked selector to determine if the checkbox is
  1700. // checked or not
  1701. if(jQuery('input[name=pe2_' + name + '_size_crop]:checked').length > 0){
  1702. // the checkbox is checked
  1703. pe2_compute_image_size('crop',jQuery(obj).val(), name);
  1704. }else{
  1705. // the checkbox is not checked
  1706. pe2_compute_image_size('crop','',name);
  1707. }
  1708. }
  1709. </script>
  1710. <?php
  1711. // ---------------------------------------------------------------------
  1712. // single video thunbnail size (override)
  1713. $option = $this->options['pe2_single_video_size'];
  1714. preg_match('/(\w)(\d+)/',$option,$mode);
  1715. if(strpos($option, '-c') !== false)
  1716. $crop = true;
  1717. else
  1718. $crop = false;
  1719. if (!$mode) $mode=array('','','');
  1720. $this->make_settings_row(
  1721. __('Single video thumbnail size', 'pe2'),
  1722. '<input type="hidden" name="pe2_single_video_size" value="'.$option.'" />Scale: &nbsp; &nbsp;[ <label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="w" '.checked($mode[1], 'w', false).' /> '.__('width','pe2').'</label> &nbsp; '.
  1723. '<label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="h" '.checked($mode[1], 'h', false).' /> '.__('height','pe2').'</label> &nbsp; '.
  1724. '<label><input type="radio" name="pe2_single_video_size_mode" class="pe2_single_video_size" value="s" '.checked($mode[1], 's', false).' /> '.__('any','pe2').'</label> '.
  1725. __(' ]&nbsp; &nbsp; proportionally to ','pe2').
  1726. '<input type="text" name="pe2_single_video_size_dimension" class="pe2_single_video_size" style="width:60px;" id="pe2_single_video_size_dimension" value="'.$mode[2].'" />'.
  1727. __(' pixels.','pe2').
  1728. '<label> &nbsp; &nbsp; &nbsp; <input type="checkbox" name="pe2_single_video_size_crop" class="pe2_single_video_size" value="-c" '.checked($crop, true, false).' /> '.__(' Crop image into a square.','pe2').'</label> '
  1729. ,
  1730. sprintf(__('Value \'%s\' will be used to set single video thumbnail size'),"<span id=\"pe2_single_video_size_message_option\">$option</span>"),
  1731. '',
  1732. 'id="pe2_single_video_size_message" style="display:'.(($option) ? 'block' : 'none').';"'
  1733. );
  1734. ?>
  1735. <script type="text/javascript">
  1736. // if mode changes, update image size
  1737. jQuery('input[name=pe2_single_video_size_mode]').change(function(){ if (jQuery(this).attr('checked')) pe2_compute_image_size('mode',jQuery(this).val(), 'single_video'); });
  1738. // if size changes, update image size
  1739. jQuery('input[name=pe2_single_video_size_dimension]').change(function(){
  1740. pe2_compute_image_size('size',jQuery('input[name=pe2_single_video_size_dimension]').val(), 'single_video');
  1741. });
  1742. // if crop changes, update image size
  1743. jQuery('input[name=pe2_single_video_size_crop]').change(function(){
  1744. pe2_determine_crop('single_video', this);
  1745. });
  1746. </script>
  1747. <?
  1748. // ---------------------------------------------------------------------
  1749. // album thumbnail image size
  1750. $this->make_settings_row(__('Album thumbnail size', 'pe2'),
  1751. __('Album thumbnail images are inserted using the default thumbnail size. This can be modified by using the <a href="options-media.php">Settings-&gt;Media</a> page.', 'pe2'));
  1752. // ---------------------------------------------------------------------
  1753. // large image size
  1754. $option = $this->options['pe2_large_limit'];
  1755. preg_match('/(\w)(\d+)/',$option,$mode);
  1756. if (!$mode) $mode=array('','','');
  1757. $this->make_settings_row(
  1758. __('Large image size', 'pe2'),
  1759. '<label><input type="checkbox" name="pe2_large_limit" value="'.$option.'" '.checked(($option)?1:0,1,false).' /> '.__('Set / Limit: ','pe2').'</label> '.
  1760. '<label> &nbsp; &nbsp;[ <input type="radio" name="pe2_large_size_mode" class="pe2_large_limit" value="w" '.checked($mode[1], 'w', false).' '.disabled(($option)?1:0,0,false).' /> '.__('width','pe2').'</label> &nbsp; '.
  1761. '<label><input type="radio" name="pe2_large_size_mode" class="pe2_large_limit" value="h" '.checked($mode[1], 'h', false).' '.disabled(($option)?1:0,0,false).' /> '.__('height','pe2').'</label> &nbsp; '.
  1762. '<label><input type="radio" name="pe2_large_size_mode" class="pe2_large_limit" value="s" '.checked($mode[1], 's', false).' '.disabled(($option)?1:0,0,false).' /> '.__('any','pe2').' ]&nbsp; &nbsp; </label> '.
  1763. __(' proportionally to ','pe2').
  1764. '<input type="text" name="pe2_large_size_dimension" class="pe2_large_limit" style="width:60px;" id="pe2_large_size" value="'.$mode[2].'" '.disabled(($option)?1:0,0,false).' />'.
  1765. __(' pixels.','pe2').
  1766. '<label> &nbsp; &nbsp; &nbsp; <input type="checkbox" name="pe2_large_size_crop" class="pe2_large_limit" value="-c" '.checked($crop, true, false).' /> '.__(' Crop image into a square.','pe2').'</label> '
  1767. ,
  1768. sprintf(__('Value \'%s\' will be used to set / limit large image'),"<span id=\"pe2_large_size_message_option\">$option</span>"),
  1769. '',
  1770. 'id="large-limit-message" style="display:'.(($option) ? 'block' : 'none').';"'
  1771. );
  1772. ?>
  1773. <script type="text/javascript">
  1774. jQuery('input[name=pe2_large_limit]').change(function(){
  1775. if (jQuery(this).attr('checked')) {
  1776. // the checkbox is set
  1777. jQuery('input.pe2_large_limit').removeAttr('disabled');
  1778. jQuery('#large-limit-message').show();
  1779. // set the default for the input boxes
  1780. jQuery('input[name=pe2_large_size_mode][value=w]').attr('checked', 'true');
  1781. jQuery('input[name=pe2_large_size_dimension]').val('600');
  1782. // call the calculation function for each section
  1783. pe2_compute_image_size('mode',jQuery('input[name=pe2_large_size_mode]').val(), 'large');
  1784. pe2_compute_image_size('size',jQuery('input[name=pe2_large_size_dimension]').val(), 'large');
  1785. } else {
  1786. jQuery('input.pe2_large_limit').removeAttr('checked').attr('disabled','disabled');
  1787. jQuery('input[name=pe2_large_size]').val('');
  1788. jQuery('#pe2_large_size_message_option').text('');
  1789. jQuery('input[name=pe2_large_limit]').val('');
  1790. jQuery('#large-limit-message').hide();
  1791. }
  1792. });
  1793. // if mode changes, update image size
  1794. jQuery('input[name=pe2_large_size_mode]').change(function(){ if (jQuery(this).attr('checked')) pe2_compute_image_size('mode',jQuery(this).val(), 'large'); });
  1795. // if size changes, update image size
  1796. jQuery('input[name=pe2_large_size_dimension]').change(function(){
  1797. pe2_compute_image_size('size',jQuery('input[name=pe2_large_size_dimension]').val(), 'large');
  1798. });
  1799. // if crop changes, update image size
  1800. jQuery('input[name=pe2_large_size_crop]').change(function(){
  1801. pe2_determine_crop('large', this);
  1802. });
  1803. </script>
  1804. <?php
  1805. $option = $this->options['pe2_caption'];
  1806. $this->make_settings_row(
  1807. __('Display caption', 'pe2'),
  1808. '<label><input type="checkbox" name="pe2_caption" value="1" '.checked($option,'1',false).' /> '.__('Show the caption under thumbnail image', 'pe2').'</label> '
  1809. );
  1810. $option = $this->options['pe2_video_overlay'];
  1811. $this->make_settings_row(
  1812. __('Use video overlay', 'pe2'),
  1813. '<label><input type="checkbox" name="pe2_video_overlay" value="1" '.checked($option,'1',false).' /> '.__('Use the JavaScript video overlay on thumbnails for videos on the main display page/post and in the selection dialog', 'pe2').'</label> '
  1814. );
  1815. $option = $this->options['pe2_title'];
  1816. $this->make_settings_row(
  1817. __('Add caption as title', 'pe2'),
  1818. '<label><input type="checkbox" name="pe2_title" value="1" '.checked($option,'1',false).' /> '.__('Show the caption by mouse hover tip', 'pe2').'</label> '
  1819. );
  1820. $opts = array (
  1821. 'none' => __('No link', 'pe2'),
  1822. 'direct' => __('Direct link', 'pe2'),
  1823. 'picasa' => __('Link to Picasa Web Album', 'pe2'),
  1824. 'lightbox' => __('Lightbox', 'pe2'),
  1825. 'thickbox' => __('Thickbox (External)', 'pe2'),
  1826. 'thickbox_integrated' => __('Thickbox (Integrated Wordpress version)', 'pe2'),
  1827. 'thickbox_custom' => __('Thickbox (Custom from this plugin)', 'pe2'),
  1828. 'highslide'=> __('Highslide', 'pe2'),
  1829. );
  1830. $is_gallery = array (
  1831. 'none' => 'false',
  1832. 'direct' => 'false',
  1833. 'picasa' => 'false',
  1834. 'lightbox' => 'true',
  1835. 'thickbox' => 'true',
  1836. 'thickbox_integrated' => 'true',
  1837. 'thickbox_custom' => 'true',
  1838. 'highslide'=> 'true',
  1839. );
  1840. $is_gallery_js = 'var is_gallery = { ';
  1841. foreach ($is_gallery as $key=>$val) {
  1842. $is_gallery_js .= "$key:$val,";
  1843. }
  1844. $is_gallery_js = trim($is_gallery_js, ',').' };';
  1845. ?>
  1846. <script type="text/javascript">
  1847. function handle_gallery_properties(t) {
  1848. <?php echo $is_gallery_js; ?>
  1849. if (is_gallery[t]) {
  1850. jQuery('#gallery_properties').show();
  1851. jQuery('#gallery-message').show();
  1852. jQuery('#nogallery_properties').hide();
  1853. } else {
  1854. jQuery('#gallery_properties').hide();
  1855. jQuery('#gallery-message').hide();
  1856. jQuery('#nogallery_properties').show();
  1857. }
  1858. }
  1859. </script>
  1860. <?php
  1861. $out = '<select name="pe2_link" onchange="handle_gallery_properties(this.value);">';
  1862. $option = $this->options['pe2_link'];
  1863. foreach ($opts as $key => $val ) {
  1864. $out .= "<option value=\"$key\" ".selected($option, $key, false ).">$val</option>";
  1865. }
  1866. $out .= '</select>';
  1867. $this->make_settings_row(
  1868. __('Link to larger image', 'pe2'),
  1869. $out,
  1870. __('To use external libraries like Thickbox, Lightbox or Highslide you need to install and integrate the library independently','pe2'),
  1871. '',
  1872. 'id="gallery-message" style="display:'.(($is_gallery[$option]=='true') ? 'block' : 'none').';"'
  1873. );
  1874. $option = $this->options['pe2_relate_images'];
  1875. $this->make_settings_row(
  1876. __('Relate all of a post\'s images', 'pe2'),
  1877. '<label><input type="checkbox" name="pe2_relate_images" value="1" '.checked($option,'1',false).' /> '.__('If using Thickbox, Lightbox or Highslide, relate all images in the page/post together for fluid next/prev navigation', 'pe2').'</label> '
  1878. );
  1879. $opts = array (
  1880. 'none' => __('None'),
  1881. 'left' => __('Left'),
  1882. 'center' => __('Center'),
  1883. 'right' => __('Right'),
  1884. );
  1885. $option = $this->options['pe2_img_align'];
  1886. $out = '';
  1887. foreach ($opts as $key => $val ) {
  1888. $out .= "<input type=\"radio\" name=\"pe2_img_align\" id=\"img-align$key\" value=\"$key\" ".checked($option, $key, false)." /> ";
  1889. $out .= "<label for=\"img-align$key\" style=\"padding-left:22px;margin-right:13px;\" class=\"image-align-$key-label\">$val</label>";
  1890. }
  1891. $this->make_settings_row(
  1892. __('Image alignment', 'pe2'),
  1893. $out
  1894. );
  1895. $option = $this->options['pe2_auto_clear'];
  1896. $this->make_settings_row(
  1897. __('Auto clear: both', 'pe2'),
  1898. '<label><input type="checkbox" name="pe2_auto_clear" value="1" '.checked($option,'1',false).' /> '.__('Automatically add &lt;p class="clear"&gt;&lt;/p&gt; after groups of images inserted together', 'pe2').'</label> '
  1899. );
  1900. $this->make_settings_row(
  1901. __('CSS Class', 'pe2'),
  1902. '<input type="text" name="pe2_img_css" class="regular-text" value="'.esc_attr($this->options['pe2_img_css']).'"/>',
  1903. __("You can define default class for images from theme's style.css", 'pe2')
  1904. );
  1905. $this->make_settings_row(
  1906. __('Style', 'pe2'),
  1907. '<input type="text" name="pe2_img_style" class="regular-text" value="'.esc_attr($this->options['pe2_img_style']).'"/>',
  1908. __('You can hardcode some css attributes', 'pe2')
  1909. );
  1910. ?>
  1911. </table>
  1912. <h3><?php _e('Gallery properties', 'pe2') ?></h3>
  1913. <p>
  1914. <?php _e('Multiple images from an album can be grouped into a gallery by Lightbox, Thickbox or Highslide and viewed sequentially with embedded navigation.', 'pe2') ?>
  1915. </p>
  1916. <div id="nogallery_properties" style="<?php echo ($is_gallery[$this->options['pe2_link']]=='true') ? 'display:none;' : 'display:block;'?>">
  1917. <p><?php _e('To view and change properties you have to select Thickbox, Lightbox or Highslide support for the images above', 'pe2') ?></p>
  1918. </div>
  1919. <div id="gallery_properties" style="<?php echo ($is_gallery[$this->options['pe2_link']]=='false') ? 'display:none;' : 'display:block;'?>">
  1920. <table class="form-table">
  1921. <?php
  1922. // display tag options
  1923. $this->make_settings_row(
  1924. __('Photo tag options', 'pe2'),
  1925. '<input name="pe2_featured_tag" type="checkbox" id="pe2_featured_tag" value="1" '.checked('1', get_option('pe2_featured_tag'),false).'/> '.
  1926. '<label for="pe2_featured_tag">'.__('Include photos from albums only if they contain the "Featured" tag').'</label><br />'.
  1927. '<label for="pe2_additional_tags" style="vertical-align: top;">'.__('Additional tag(s) required').'</label> '.
  1928. '<div style="display: inline-block;"><input type="text" name="pe2_additional_tags" id="pe2_additional_tags" class="regular-text" value="'.esc_attr($this->options['pe2_additional_tags']).'"/><br/><span style="font-size: 9px;">('.__('Separate multiple tags by commas. NOTE: currently Google requires private album access for tags to work').')</span></div>'
  1929. );
  1930. // remaining gallery options
  1931. $this->make_settings_row(
  1932. __('Selection order', 'pe2'),
  1933. '<label><input type="checkbox" name="pe2_gal_order" value="1" '.checked($this->options['pe2_gal_order'],'1',false).' /> '.__("Click images in your preferred order", 'pe2').'</label>'
  1934. );
  1935. $option = $this->options['pe2_gal_align'];
  1936. $out = '';
  1937. foreach ($opts as $key => $val ) {
  1938. $out .= "<input type=\"radio\" name=\"pe2_gal_align\" id=\"gal-align$key\" value=\"$key\" ".checked($option, $key, false)." /> ";
  1939. $out .= "<label for=\"gal-align$key\" style=\"padding-left:22px;margin-right:13px;\" class=\"image-align-$key-label\">$val</label>";
  1940. }
  1941. $this->make_settings_row(
  1942. __('Gallery alignment', 'pe2'),
  1943. $out
  1944. );
  1945. $this->make_settings_row(
  1946. __('CSS Class', 'pe2'),
  1947. '<input type="text" name="pe2_gal_css" class="regular-text" value="'.esc_attr($this->options['pe2_gal_css']).'"/>',
  1948. __("You can define default class for images from theme's style.css", 'pe2')
  1949. );
  1950. $this->make_settings_row(
  1951. __('Style', 'pe2'),
  1952. '<input type="text" name="pe2_gal_style" class="regular-text" value="'.esc_attr($this->options['pe2_gal_style']).'"/>',
  1953. __('You can hardcode some css attributes', 'pe2')
  1954. );
  1955. ?>
  1956. </table>
  1957. </div>
  1958. <h3><?php _e('Advertising', 'pe2') ?></h3>
  1959. <table class="form-table">
  1960. <?php
  1961. $this->make_settings_row(
  1962. __('Footer link', 'pe2'),
  1963. '<label><input type="checkbox" name="pe2_footer_link" value="1" '.checked($this->options['pe2_footer_link'],'1',false).' /> '.__('Enable footer link "With Picasa plugin by Wott"','pe2').'</label>'
  1964. );
  1965. $this->make_settings_row(
  1966. __('PayPal donation banner', 'pe2'),
  1967. '<label><input type="checkbox" name="pe2_donate_link" value="1" '.checked($this->options['pe2_donate_link'],'1',false).' /> '.__('Enable PayPal banner on this page','pe2').'</label>'
  1968. );
  1969. ?>
  1970. </table>
  1971. <p class="submit">
  1972. <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
  1973. </p>
  1974. </form>
  1975. </div>
  1976. <?php
  1977. }
  1978. }
  1979. }
  1980. if (isset($_GET['authorize'])&&!defined('ABSPATH')) {
  1981. if (!isset($_GET['token'])||!$_GET['token']||strlen($_GET['token'])>256) {
  1982. header('Location: '.preg_replace('/wp-content.*/','',$_SERVER["REQUEST_URI"]).'wp-admin/options-general.php?page=picasa-express-2');
  1983. die();
  1984. }
  1985. // require wp-load so that wordpress loads allowing us to perform the updates
  1986. // to the appropriate setting
  1987. if(file_exists(dirname(__FILE__).'/pe2-wp-path.php')){
  1988. // include the pe2-wp-path.php to define the wordpress root
  1989. // (this allows a customized path (sometimes necessary in certain
  1990. // wordpress installations) to be set when saving the pe2 preferences page
  1991. // and written to the file system so it can be loaded here prior
  1992. // to any wordpress filters or functionality being available)
  1993. // (using an include that sets a variable so that if the file is
  1994. // accessed from the web nothing is visible, thus not causing a
  1995. // security problem)
  1996. include(dirname(__FILE__).'/pe2-wp-path.php');
  1997. }
  1998. if(!isset($pe2_wp_path)){
  1999. // for some reason the include doesn't exist (preferences haven't
  2000. // been written, or web server doesn't have write access to the
  2001. // plugin directory) or the include didn't set the appropriate
  2002. // variable.
  2003. // We have no choice but to determine the path as best as we can
  2004. // and hope it works with this installation
  2005. $pe2_wp_path = preg_replace('/wp-content.*/','',__FILE__);
  2006. }
  2007. // require wp-load.php for the core wordpress functions we need
  2008. require_once($pe2_wp_path.'wp-load.php');
  2009. // create our instance and continue updating
  2010. if (!isset($pe2_instance)) $pe2_instance = new PicasaExpressX2();
  2011. if ('user' == $pe2_instance ->options['pe2_level'] && isset($_GET['user']) ) {
  2012. $user_id = sanitize_text_field($_GET['user']);
  2013. $user = new WP_User( $user_id );
  2014. global $wp_roles;
  2015. if ( ! isset( $wp_roles ) ) $wp_roles = new WP_Roles();
  2016. $allow = false;
  2017. foreach ( $user->roles as $role) {
  2018. if (isset($wp_roles->roles[$role]['capabilities']['picasa_dialog'])) {
  2019. $allow=true; break;
  2020. }
  2021. }
  2022. if (!$allow) {
  2023. header('Location: '.preg_replace('/wp-content.*/','',$_SERVER["REQUEST_URI"]).'wp-admin/profile.php');
  2024. die();
  2025. }
  2026. }
  2027. $response = $pe2_instance->get_feed("https://www.google.com/accounts/AuthSubSessionToken",sanitize_text_field($_GET['token']));
  2028. $message='';
  2029. if (is_wp_error($response)) {
  2030. $message = 'Can\'t request token: ' .$response->get_error_message();
  2031. } else if ($response) {
  2032. $lines = explode("\n", $response);
  2033. // grab our current logged in user
  2034. $current_user = wp_get_current_user();
  2035. $user_id = $current_user->ID;
  2036. // go thorugh all lines in the reponse looking for the token
  2037. foreach ($lines as $line) {
  2038. $pair = explode("=", $line, 2);
  2039. if (0==strcasecmp($pair[0],'token')) {
  2040. if ((get_option('pe2_level') == 'user') && isset($user_id))
  2041. update_user_meta($user_id,'pe2_token',sanitize_text_field($pair[1]));
  2042. else
  2043. update_option('pe2_token',sanitize_text_field($pair[1]));
  2044. $message = 'Private access received';
  2045. }
  2046. }
  2047. }
  2048. if (isset($user_id))
  2049. header('Location: '.preg_replace('/wp-content.*/','',$_SERVER["REQUEST_URI"]).'wp-admin/profile.php?message='.rawurlencode($message));
  2050. else
  2051. header('Location: '.preg_replace('/wp-content.*/','',$_SERVER["REQUEST_URI"]).'wp-admin/options-general.php?page=picasa-express-2&message='.rawurlencode($message));
  2052. die();
  2053. } else {
  2054. if (!isset($pe2_instance)) $pe2_instance = new PicasaExpressX2();
  2055. }
  2056. // add the pe2 display css file
  2057. add_action('init','pe2_add_display_css');
  2058. function pe2_add_display_css(){
  2059. // add the pe2-display.css file
  2060. wp_enqueue_style('pe2-display.css',plugins_url('/pe2-display.css', __FILE__), null, PE2_VERSION);
  2061. }// end function pe2_add_display_css()
  2062. // to use the default thickbox script with wordpress:
  2063. if(get_option('pe2_link') == 'thickbox_integrated'){
  2064. // they chose the option to use the internal Wordpress version of Thickbox
  2065. add_action('init','pe2_add_thickbox_script');
  2066. }
  2067. function pe2_add_thickbox_script(){
  2068. // add in the thickbox script built into wordpress if not in the admin
  2069. // and the user has selected thickbox as the display method
  2070. if(!is_admin()){
  2071. // not in the admin, so we can load thickbox
  2072. wp_enqueue_script('jquery');
  2073. wp_enqueue_script('thickbox',null,array('jquery'));
  2074. wp_enqueue_style('thickbox.css', '/'.WPINC.'/js/thickbox/thickbox.css', null, '1.0');
  2075. }
  2076. }// end function pe2_add_thickbox_script()
  2077. // to use a custom thickbox script for display:
  2078. if(get_option('pe2_link') == 'thickbox_custom'){
  2079. // they chose the option to use the custom thickbox from this plugin
  2080. add_action('init', 'pe2_add_custom_thickbox_script');
  2081. }
  2082. function pe2_add_custom_thickbox_script(){
  2083. // add in the thickbox script built into wordpress if not in the admin
  2084. // and the user has selected thickbox as the display method
  2085. if(!is_admin()){
  2086. // not in the admin, so we can load thickbox
  2087. wp_enqueue_script('jquery');
  2088. wp_enqueue_style('thickbox.css', '/'.WPINC.'/js/thickbox/thickbox.css', null, PE2_VERSION);
  2089. add_action('wp_footer', 'pe2_add_custom_thickbox_config');
  2090. }
  2091. }// end function pe2_add_custom_thickbox_script()
  2092. function pe2_add_custom_thickbox_config(){
  2093. ?><script type='text/javascript'>
  2094. /* <![CDATA[ */
  2095. var thickboxL10n = {"next":"Next >","prev":"< Prev","image":"Image","of":"of","close":"Close","noiframes":"This feature requires inline frames. You have iframes disabled or your browser does not support them.","loadingAnimation":"<?= str_replace('/', '\/', includes_url('/js/thickbox/loadingAnimation.gif')) ?>","closeImage":"<?= str_replace('/', '\/', includes_url('/js/thickbox/tb-close.png')) ?>"};
  2096. /* ]]> */
  2097. </script>
  2098. <script src="<?= plugins_url('/thickbox-custom.js', __FILE__) ?>?ver=<?= PE2_VERSION ?>"></script>
  2099. <?
  2100. }// end function pe2_add_custom_thickbox_config()
  2101. // function to add the play button image overlay over video images
  2102. if(get_option('pe2_video_overlay') == '1'){
  2103. // they chose the option to use the video overlay, enable it
  2104. add_action('wp_footer','pe2_add_video_overlay');
  2105. add_action('pe2_get_images_footer','pe2_add_video_overlay_filter');
  2106. }
  2107. function pe2_add_video_overlay($dialog = false){
  2108. ?><script>
  2109. jQuery(document).ready(function(){
  2110. // ready event, find any images with class="video" and append
  2111. // a div after them to style, thus allowing us to style it
  2112. // to create the "video play button" overlay
  2113. jQuery('img[type=video]').each(function(){
  2114. // for each video image on the page, determine it's height/
  2115. // width and then set the video_overlay to the matching
  2116. // dimensions
  2117. pe2_add_video_overlay_helper(jQuery(this));
  2118. });
  2119. });
  2120. function pe2_add_video_overlay_helper(image_obj){
  2121. // check to make sure we have our image dimensions
  2122. if((image_obj.width() > 0) && (image_obj.height() > 0)){
  2123. // we're good, we have image dimensions. wait one more second
  2124. // to make sure they're correct, then insert our overlay
  2125. setTimeout(function(){pe2_add_video_overlay_helper_run(image_obj)}, 1000);
  2126. }else{
  2127. // no dimensions yet, delay and retry
  2128. setTimeout(function(){pe2_add_video_overlay_helper(image_obj)}, 1000);
  2129. }
  2130. }// pe2_add_video_overlay_helper(..)
  2131. function pe2_add_video_overlay_helper_run(image_obj){
  2132. // add the HTML for the overlay
  2133. image_obj.wrap('<div class="play_overlay_wrapper"></div>');
  2134. image_obj.after('<span class="play_overlay" style="width: ' + image_obj.width() + 'px; height: ' + image_obj.height() + 'px; <?
  2135. // determine which margin we need to adjust, based on where we're
  2136. // being called
  2137. if($dialog){
  2138. // we're being called from the image selection dialog
  2139. ?>margin-left: 5px; margin-top: -' + (image_obj.height() + 5) + 'px;<?
  2140. }else{
  2141. // we're being called from wordpress display
  2142. ?>margin-left: -' + (image_obj.width() + 4) + 'px; margin-top: 2px;<?
  2143. }
  2144. // finish up the JS
  2145. ?>"></span>');
  2146. }// end function pe2_add_video_overlay_helper_run(..)
  2147. </script>
  2148. <?
  2149. }// end function pe2_add_video_overlay(..)
  2150. function pe2_add_video_overlay_filter($output){
  2151. // get the output of the pe2_add_video_overlay() function and append it
  2152. // to the $output
  2153. ob_start();
  2154. pe2_add_video_overlay(true);
  2155. $output .= ob_get_clean();
  2156. // return the modified output
  2157. return $output;
  2158. }// end function pe2_add_video_overlay_filter(..)