PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/post-thumbnail-editor/post-thumbnail-editor.php

https://github.com/pica-design/nextstepmaine
PHP | 439 lines | 272 code | 57 blank | 110 comment | 28 complexity | eb5f1e7688e69d9181f155575c3f9707 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-3.0, GPL-3.0
  1. <?php
  2. /*
  3. Plugin name: Post Thumbnail Editor
  4. Plugin URI: http://sewpafly.github.io/post-thumbnail-editor/
  5. Author: sewpafly
  6. Author URI: http://sewpafly.github.io/post-thumbnail-editor/
  7. Version: 2.4.0
  8. Description: Individually manage your post thumbnails
  9. LICENSE
  10. =======
  11. Copyright 2013 (email : sewpafly@gmail.com)
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. GNU General Public License for more details.
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. /*
  25. * Useful constants
  26. */
  27. define( 'PTE_PLUGINURL', plugins_url(basename( dirname(__FILE__))) . "/");
  28. define( 'PTE_PLUGINPATH', dirname(__FILE__) . "/");
  29. define( 'PTE_DOMAIN', "post-thumbnail-editor");
  30. define( 'PTE_VERSION', "2.4.0");
  31. // TODO:
  32. // * Find the best place for the require log (only when it's really needed, create an init function?)
  33. // * Change all the log calls?
  34. // * Rip out everything that's not a CONSTANT or a hook in here
  35. // * Make this an object
  36. // * Add a tour for new users
  37. require_once( PTE_PLUGINPATH . 'php/log.php' );
  38. /*
  39. * Option Functionality
  40. */
  41. function pte_get_option_name(){
  42. global $current_user;
  43. if ( ! isset( $current_user ) ){
  44. get_currentuserinfo();
  45. }
  46. return "pte-option-{$current_user->ID}";
  47. }
  48. function pte_get_user_options(){
  49. $pte_options = get_option( pte_get_option_name() );
  50. if ( !is_array( $pte_options ) ){
  51. $pte_options = array();
  52. }
  53. $defaults = array( 'pte_debug' => false
  54. , 'pte_crop_save' => false
  55. , 'pte_thumbnail_bar' => 'horizontal'
  56. , 'pte_imgedit_disk' => false
  57. , 'pte_imgedit_max_size' => 600
  58. , 'pte_debug_out_chrome' => false
  59. , 'pte_debug_out_file' => false
  60. );
  61. // WORDPRESS DEBUG overrides user setting...
  62. return array_merge( $defaults, $pte_options );
  63. }
  64. function pte_get_site_options(){
  65. $pte_site_options = get_option( 'pte-site-options' );
  66. if ( !is_array( $pte_site_options ) ){
  67. $pte_site_options = array();
  68. }
  69. $defaults = array( 'pte_hidden_sizes' => array()
  70. , 'cache_buster' => true
  71. );
  72. return array_merge( $defaults, $pte_site_options );
  73. }
  74. function pte_get_options(){
  75. global $pte_options, $current_user;
  76. if ( isset( $pte_options ) ){
  77. return $pte_options;
  78. }
  79. $pte_options = array_merge( pte_get_user_options(), pte_get_site_options() );
  80. if ( WP_DEBUG )
  81. $pte_options['pte_debug'] = true;
  82. if ( !isset( $pte_options['pte_jpeg_compression'] ) ){
  83. $pte_options['pte_jpeg_compression'] = apply_filters( 'jpeg_quality', 90, 'pte_options' );
  84. }
  85. return $pte_options;
  86. }
  87. function pte_update_user_options(){
  88. require_once( PTE_PLUGINPATH . 'php/options.php' );
  89. $options = pte_get_user_options();
  90. if ( isset( $_REQUEST['pte_crop_save'] ) ) {
  91. if ( strtolower( $_REQUEST['pte_crop_save'] ) === "true" )
  92. $options['pte_crop_save'] = true;
  93. else
  94. $options['pte_crop_save'] = false;
  95. }
  96. if ( isset( $_REQUEST['pte_thumbnail_bar'] ) ) {
  97. if ( strtolower( $_REQUEST['pte_thumbnail_bar'] ) == 'vertical' )
  98. $options['pte_thumbnail_bar'] = 'vertical';
  99. else
  100. $options['pte_thumbnail_bar'] = 'horizontal';
  101. }
  102. update_option( pte_get_option_name(), $options );
  103. }
  104. /**
  105. * Get the URL for the PTE interface
  106. *
  107. * @param $id the post id of the attachment to modify
  108. */
  109. function pte_url( $id, $iframe=false ){
  110. if ($iframe) {
  111. $pte_url = admin_url( 'admin-ajax.php' )
  112. . "?action=pte_ajax&pte-action=iframe&pte-id={$id}"
  113. . "&TB_iframe=true";
  114. }
  115. else {
  116. $pte_url = admin_url('upload.php')
  117. . "?page=pte-edit&pte-id={$id}";
  118. }
  119. return $pte_url;
  120. }
  121. /**
  122. * Used in functions.php, log.php & options.php to get pseudo-TMP file paths
  123. */
  124. function pte_tmp_dir()
  125. {
  126. $uploads = wp_upload_dir();
  127. $PTE_TMP_DIR = $uploads['basedir'] . DIRECTORY_SEPARATOR . "ptetmp" . DIRECTORY_SEPARATOR;
  128. $PTE_TMP_URL = $uploads['baseurl'] . "/ptetmp/";
  129. return compact( 'PTE_TMP_DIR', 'PTE_TMP_URL' );
  130. }
  131. /*
  132. * Put Hooks and immediate hook functions in this file
  133. */
  134. /** For the "Edit Image" stuff **/
  135. /* Hook into the Edit Image page */
  136. add_action('dbx_post_advanced', 'pte_edit_form_hook_redirect');
  137. /* Slight redirect so this isn't called on all versions of the media upload page */
  138. function pte_edit_form_hook_redirect(){
  139. add_action('add_meta_boxes', 'pte_admin_media_scripts');
  140. }
  141. add_action( 'media_upload_library', 'pte_admin_media_scripts_editor' );
  142. add_action( 'media_upload_gallery', 'pte_admin_media_scripts_editor' );
  143. add_action( 'media_upload_image', 'pte_admin_media_scripts_editor' );
  144. function pte_admin_media_scripts_editor(){
  145. pte_admin_media_scripts('attachment');
  146. }
  147. function pte_admin_media_scripts($post_type){
  148. $options = pte_get_options();
  149. pte_add_thickbox();
  150. if ($post_type == "attachment") {
  151. wp_enqueue_script( 'pte'
  152. , PTE_PLUGINURL . 'apps/coffee-script.js'
  153. , array('underscore')
  154. , PTE_VERSION
  155. );
  156. add_action( 'admin_print_footer_scripts', 'pte_enable_editor_js', 100);
  157. }
  158. else {
  159. //add_action( 'admin_print_footer_scripts', 'pte_enable_media_js', 100);
  160. wp_enqueue_script( 'pte'
  161. , PTE_PLUGINURL . 'js/snippets/pte_enable_media.js'
  162. , array('media-views')
  163. , PTE_VERSION
  164. , true
  165. );
  166. wp_enqueue_style( 'pte'
  167. , PTE_PLUGINURL . 'css/pte-media.css'
  168. , NULL
  169. , PTE_VERSION
  170. );
  171. }
  172. wp_localize_script('pte'
  173. , 'pteL10n'
  174. , array('PTE' => __('Post Thumbnail Editor', PTE_DOMAIN)
  175. , 'url' => pte_url( "<%= id %>", true )
  176. )
  177. );
  178. }
  179. function pte_enable_editor_js(){
  180. injectCoffeeScript( PTE_PLUGINPATH . "js/snippets/editor.coffee" );
  181. }
  182. function pte_enable_media_js(){
  183. injectCoffeeScript( PTE_PLUGINPATH . "js/snippets/media.coffee" );
  184. }
  185. function injectCoffeeScript($coffeeFile){
  186. $coffee = @file_get_contents( $coffeeFile );
  187. //$options = json_encode( pte_get_options() );
  188. echo <<<EOT
  189. <script type="text/coffeescript">
  190. $coffee
  191. </script>
  192. EOT;
  193. }
  194. // Add the PTE link to the featured image in the post screen
  195. // Called in wp-admin/includes/post.php
  196. add_filter( 'admin_post_thumbnail_html', 'pte_admin_post_thumbnail_html', 10, 2 );
  197. function pte_admin_post_thumbnail_html( $content, $post_id ){
  198. pte_add_thickbox();
  199. $thumbnail_id = get_post_thumbnail_id( $post_id );
  200. if ( $thumbnail_id == null )
  201. return $content;
  202. return $content .= '<p id="pte-link" class="hide-if-no-js"><a class="thickbox" href="'
  203. . pte_url( $thumbnail_id, true )
  204. . '">'
  205. . esc_html__( 'Post Thumbnail Editor', PTE_DOMAIN )
  206. . '</a></p>';
  207. }
  208. /* Fix wordpress ridiculousness about making a thickbox max width=720 */
  209. function pte_add_thickbox() {
  210. add_thickbox();
  211. wp_enqueue_script('pte-fix-thickbox',
  212. PTE_PLUGINURL . "js/snippets/pte-fix-thickbox.js",
  213. array( 'media-upload' ),
  214. PTE_VERSION
  215. );
  216. }
  217. /* For all purpose needs */
  218. add_action('wp_ajax_pte_ajax', 'pte_ajax');
  219. function pte_ajax(){
  220. // Move all adjuntant functions to a separate file and include that here
  221. require_once(PTE_PLUGINPATH . 'php/functions.php');
  222. PteLogger::debug( "PARAMETERS: " . print_r( $_REQUEST, true ) );
  223. switch ($_GET['pte-action'])
  224. {
  225. case "iframe":
  226. pte_init_iframe();
  227. break;
  228. case "resize-images":
  229. pte_resize_images();
  230. break;
  231. case "confirm-images":
  232. pte_confirm_images();
  233. break;
  234. case "delete-images":
  235. pte_delete_images();
  236. break;
  237. case "get-thumbnail-info":
  238. $id = (int) $_GET['id'];
  239. if ( pte_check_id( $id ) )
  240. print( json_encode( pte_get_all_alternate_size_information( $id ) ) );
  241. break;
  242. case "change-options":
  243. pte_update_user_options();
  244. break;
  245. }
  246. die();
  247. }
  248. /**
  249. * Perform the capability check
  250. *
  251. * @param $id References the post that the user needs to have permission to edit
  252. * @returns boolean true if the current user has permission else false
  253. */
  254. function pte_check_id( $id ) {
  255. if ( !$post = get_post( $id ) ) {
  256. return false;
  257. }
  258. if ( current_user_can( 'edit_post', $id )
  259. || current_user_can( 'pte-edit', $id ) )
  260. {
  261. return apply_filters( 'pte-capability-check', true, $id );
  262. }
  263. return apply_filters( 'pte-capability-check', false, $id );
  264. }
  265. /* Adds the Thumbnail option to the media library list */
  266. add_filter('media_row_actions', 'pte_media_row_actions', 10, 3); // priority: 10, args: 3
  267. function pte_media_row_actions($actions, $post, $detached){
  268. // Add capability check
  269. if ( !pte_check_id( $post->ID ) ) {
  270. return $actions;
  271. }
  272. $options = pte_get_options();
  273. $pte_url = pte_url( $post->ID );
  274. $actions['pte'] = "<a href='${pte_url}' title='"
  275. . __( 'Edit Thumbnails', PTE_DOMAIN )
  276. . "'>" . __( 'Thumbnails', PTE_DOMAIN ) . "</a>";
  277. return $actions;
  278. }
  279. /* Add Settings Page */
  280. add_action( 'load-settings_page_pte', 'pte_options' );
  281. /* Add Settings Page -> Submit/Update options */
  282. add_action( 'load-options.php', 'pte_options' );
  283. function pte_options(){
  284. require_once( PTE_PLUGINPATH . 'php/options.php' );
  285. pte_options_init();
  286. }
  287. /* Add SubMenus/Pages */
  288. add_action( 'admin_menu', 'pte_admin_menu' );
  289. /**
  290. * These pages are linked into the hook system of wordpress, this means
  291. * that almost any wp_admin page will work as long as you append "?page=pte"
  292. * or "?page=pte-edit". Try the function `'admin_url("index.php") . '?page=pte';`
  293. *
  294. * The function referred to here will output the HTML for the page that you want
  295. * to display. However if you want to hook into enqueue_scripts or styles you
  296. * should use the page-suffix that is returned from the function. (e.g.
  297. * `add_action("load-".$hook, hook_func);`)
  298. *
  299. * There is also another hook with the same name as the hook that's returned.
  300. * I don't remember in which order it is launched, but I believe the pertinent
  301. * code is in admin-header.php.
  302. */
  303. function pte_admin_menu(){
  304. add_options_page( __('Post Thumbnail Editor', PTE_DOMAIN),
  305. __('Post Thumbnail Editor', PTE_DOMAIN),
  306. 'edit_posts',
  307. 'pte',
  308. 'pte_launch_options_page'
  309. );
  310. // The submenu page function does not put a menu item in the wordpress sidebar.
  311. add_submenu_page(NULL, __('Post Thumbnail Editor', PTE_DOMAIN),
  312. __('Post Thumbnail Editor', PTE_DOMAIN),
  313. 'edit_posts',
  314. 'pte-edit',
  315. 'pte_edit_page'
  316. );
  317. }
  318. function pte_launch_options_page(){
  319. require_once( PTE_PLUGINPATH . 'php/options.php' );
  320. pte_options_page();
  321. }
  322. /**
  323. * This runs after headers have been sent, see the pte_edit_setup for the
  324. * function that runs before anything is sent to the browser
  325. */
  326. function pte_edit_page(){
  327. // This is set via the pte_edit_setup function
  328. global $pte_body;
  329. echo( $pte_body );
  330. }
  331. /* Admin Edit Page: setup*/
  332. /**
  333. * This hook (load-media_page_pte-edit)
  334. * depends on which page you use in the admin section
  335. * (load-media_page_pte-edit) : wp-admin/upload.php?page=pte-edit
  336. * (dashboard_page_pte-edit) : wp-admin/?page=pte-edit
  337. * (posts_page_pte-edit) : wp-admin/edit.php?page=pte-edit
  338. */
  339. add_action( 'load-media_page_pte-edit', 'pte_edit_setup' );
  340. function pte_edit_setup() {
  341. global $post, $title, $pte_body;
  342. $post_id = (int) $_GET['pte-id'];
  343. if ( !isset( $post_id )
  344. || !is_int( $post_id )
  345. || !wp_attachment_is_image( $post_id )
  346. || !pte_check_id( $post_id ) ) {
  347. //die("POST: $post_id IS_INT:" . is_int( $post_id ) . " ATTACHMENT: " . wp_attachment_is_image( $post_id ));
  348. wp_redirect( admin_url( "upload.php" ) );
  349. exit();
  350. }
  351. $post = get_post( $post_id );
  352. $title = __( "Post Thumbnail Editor", PTE_DOMAIN );
  353. include_once( PTE_PLUGINPATH . "php/functions.php" );
  354. $pte_body = pte_body( $post->ID );
  355. // Add the scripts and styles
  356. wp_enqueue_script( 'jquery' );
  357. wp_enqueue_script( 'jquery-ui-dialog' );
  358. wp_enqueue_script( 'iris' );
  359. wp_enqueue_style( 'colors' );
  360. wp_enqueue_style( 'wp-jquery-ui-dialog' );
  361. }
  362. /**
  363. * This code creates the image used for the crop
  364. *
  365. * By overwriting the wordpress code (same functions), we can change the default size
  366. * to our own option.
  367. */
  368. add_action('wp_ajax_pte_imgedit_preview','pte_wp_ajax_imgedit_preview_wrapper');
  369. function pte_wp_ajax_imgedit_preview_wrapper(){
  370. require_once( PTE_PLUGINPATH . "php/overwrite_imgedit_preview.php" );
  371. pte_wp_ajax_imgedit_preview();
  372. }
  373. /** End Settings Hooks **/
  374. load_plugin_textdomain( PTE_DOMAIN
  375. , false
  376. , basename( PTE_PLUGINPATH ) . DIRECTORY_SEPARATOR . "i18n" );