Bez popisu

class-featured-image-admin-thumb-admin.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * Featured Image Admin Thumb.
  4. *
  5. * @package Featured_Image_Admin_Thumb_Admin
  6. * @author Sean Hayes <sean@seanhayes.biz>
  7. * @license GPL-2.0+
  8. * @link http://www.seanhayes.biz
  9. * @copyright 2014 Sean Hayes
  10. */
  11. /**
  12. * Plugin class. This class works with the
  13. * administrative side of the WordPress site.
  14. *
  15. * @package Featured_Image_Admin_Thumb_Admin
  16. * Sean Hayes <sean@seanhayes.biz>
  17. */
  18. class Featured_Image_Admin_Thumb_Admin {
  19. /**
  20. * Instance of this class.
  21. *
  22. * @since 1.0.0
  23. *
  24. * @var object
  25. */
  26. protected static $instance = null;
  27. /**
  28. * Slug of the plugin screen.
  29. *
  30. * @since 1.0.0
  31. *
  32. * @var string
  33. */
  34. protected $plugin_screen_hook_suffix = null;
  35. /**
  36. * Initialize the plugin by loading admin scripts & styles and adding a
  37. * settings page and menu.
  38. *
  39. * @since 1.0.0
  40. */
  41. protected $fiat_nonce = null;
  42. protected $text_domain;
  43. protected $fiat_image_size = 'fiat_thumb';
  44. protected $is_woocommerce_active;
  45. protected $is_ninja_forms_active;
  46. protected $is_edd_active;
  47. protected $plugin_slug;
  48. protected $template_html;
  49. protected $fiat_kses;
  50. // Expect that we won't need thumbnails for these post types.
  51. protected $default_excluded_post_types = array(
  52. 'nav_menu_item',
  53. 'revision',
  54. 'attachment',
  55. 'custom_css',
  56. 'customize_changeset',
  57. 'oembed_cache',
  58. );
  59. private function __construct() {
  60. /*
  61. * Call $plugin_slug from public plugin class.
  62. *
  63. */
  64. $plugin = Featured_Image_Admin_Thumb::get_instance();
  65. $this->plugin_slug = $plugin->get_plugin_slug();
  66. $this->text_domain = $plugin->load_plugin_textdomain();
  67. $this->template_html = '<a title="' . __( 'Change featured image', 'featured-image-admin-thumb-fiat' ) . '" href="%1$s" class="fiat_thickbox" data-thumbnail-id="%3$d">%2$s</a>';
  68. $this->fiat_kses = array(
  69. 'a' => array(
  70. 'href' => array(),
  71. 'class' => array(),
  72. 'title' => array(),
  73. 'id' => array(),
  74. 'data-thumbnail-id' => array(),
  75. ),
  76. 'img' => array(
  77. 'src' => array(),
  78. 'alt' => array(),
  79. 'width' => array(),
  80. 'height' => array(),
  81. 'class' => array(),
  82. ),
  83. );
  84. // Load admin style sheet and JavaScript.
  85. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
  86. add_image_size( $this->fiat_image_size, 60, 60, array( 'center', 'center' ) );
  87. $this->is_woocommerce_active = in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ), true );
  88. $this->is_ninja_forms_active = in_array( 'ninja-forms/ninja-forms.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ), true );
  89. $this->is_edd_active = in_array( 'easy-digital-downloads/easy-digital-downloads.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ), true );
  90. if ( $this->is_ninja_forms_active ) {
  91. add_filter( 'fiat/restrict_post_types', array( $this, 'restrict_post_type_filter' ) );
  92. }
  93. add_action( 'admin_init', array( $this, 'fiat_init_columns' ) );
  94. add_action( 'wp_ajax_fiat_get_thumbnail', array( $this, 'fiat_get_thumbnail' ) );
  95. add_action( 'pre_get_posts', array( $this, 'fiat_posts_orderby' ) );
  96. }
  97. /**
  98. * Register admin column handlers for posts and pages, taxonomies and other custom post types
  99. *
  100. * Find all post_types that support thumbnails and remove those that are excluded with our filter
  101. * Then add thumbnail support
  102. *
  103. * Fired in the 'admin_init' action
  104. */
  105. public function fiat_init_columns() {
  106. $available_post_types = array_keys( array_diff( array_flip ( get_post_types_by_support('thumbnail') ), apply_filters( 'fiat/restrict_post_types', $this->default_excluded_post_types ) ) );
  107. if ( $this->is_edd_active && isset( $available_post_types['download'] ) ) {
  108. add_filter( 'edd_download_columns', array( $this, 'include_thumb_column_edd' ) );
  109. add_filter( 'fes_download_table_columns', array( $this, 'include_thumb_column_edd' ) );
  110. }
  111. array_map( array( $this, 'add_post_type_thumb_support' ), $available_post_types );
  112. // For taxonomies.
  113. $taxonomies = get_taxonomies( array(), 'names' );
  114. foreach ( $taxonomies as $taxonomy ) {
  115. add_action( "manage_{$taxonomy}_posts_custom_column", array( $this, 'fiat_custom_columns' ), 2, 2 );
  116. add_filter( "manage_{$taxonomy}_posts_columns", array( $this, 'fiat_add_thumb_column' ) );
  117. }
  118. }
  119. /**
  120. * @param $post_type
  121. *
  122. * Add thumbnail display support for the selected post_type
  123. */
  124. public function add_post_type_thumb_support( $post_type )
  125. {
  126. add_action( "manage_{$post_type}_posts_custom_column", array( $this, 'fiat_custom_columns' ), 2, 2 );
  127. add_filter( "manage_{$post_type}_posts_columns", array( $this, 'fiat_add_thumb_column' ) );
  128. add_filter( "manage_edit-{$post_type}_sortable_columns", array( $this, 'fiat_thumb_sortable_columns' ) );
  129. }
  130. /**
  131. * Return an instance of this class.
  132. *
  133. * @since 1.0.0
  134. *
  135. * @return object A single instance of this class.
  136. */
  137. public static function get_instance() {
  138. // If the single instance hasn't been set, set it now.
  139. if ( null === self::$instance ) {
  140. self::$instance = new self();
  141. }
  142. return self::$instance;
  143. }
  144. /**
  145. * Register and enqueue inline admin-specific style sheet.
  146. *
  147. * @since 1.0.0
  148. *
  149. */
  150. public function enqueue_admin_styles() {
  151. // blank and unused since v 1.5
  152. }
  153. /**
  154. * Register and enqueue admin-specific JavaScript.
  155. *
  156. * @since 1.0.0
  157. *
  158. */
  159. public function enqueue_admin_scripts() {
  160. // Enable the next block if the settings page returns
  161. /*if ( ! isset( $this->plugin_screen_hook_suffix ) ) {
  162. return;
  163. }*/
  164. $screen = get_current_screen();
  165. // Check if we are on an "all posts" screen type.
  166. // If not then just return and do not load the JavaScript code
  167. if ( ! $screen || ( 'edit-' . $screen->post_type !== $screen->id ) ) {
  168. return;
  169. }
  170. $available_post_types = array_diff( get_post_types(), apply_filters( 'fiat/restrict_post_types', $this->default_excluded_post_types ) );
  171. // Add custom uploader css and js support for specific post types.
  172. if ( isset( $available_post_types[ $screen->post_type ] ) ) {
  173. // Add support for custom media uploader to be shown inside a thickbox.
  174. add_thickbox();
  175. wp_enqueue_media();
  176. wp_enqueue_script(
  177. $this->plugin_slug . '-admin-script-thumbnail',
  178. plugins_url( 'assets/js/admin-thumbnail.js', __FILE__ ),
  179. array( 'post' ),
  180. Featured_Image_Admin_Thumb::VERSION,
  181. true
  182. );
  183. wp_localize_script(
  184. $this->plugin_slug . '-admin-script-thumbnail',
  185. 'fiat_thumb',
  186. array(
  187. 'button_text' => __( 'Use as thumbnail', 'featured-image-admin-thumb-fiat' ),
  188. 'change_featured_image' => __( 'Change featured image', 'featured-image-admin-thumb-fiat' ),
  189. )
  190. );
  191. }
  192. }
  193. /**
  194. * Render the settings page for this plugin.
  195. *
  196. * @since 1.0.0
  197. */
  198. public function display_plugin_admin_page() {
  199. include_once 'views/admin.php';
  200. }
  201. /**
  202. * Remove known post_types
  203. *
  204. * @param array $post_types post_types to filter.
  205. *
  206. * Remove post types that conflict with known plugins.
  207. * @return array
  208. */
  209. public function restrict_post_type_filter( $post_types ) {
  210. $post_types[] = 'nf_sub'; // Ninja Forms Submissions post type.
  211. return $post_types;
  212. }
  213. /**
  214. * Append thumbnail to EDD columns unless filtered out.
  215. *
  216. * @param array $download_columns Columns in EDD Downloads table.
  217. *
  218. * @since 1.5.1
  219. * @return array
  220. */
  221. public function include_thumb_column_edd( $download_columns ) {
  222. return array_merge(
  223. $download_columns,
  224. array(
  225. 'thumb' => __( 'Thumb', 'featured-image-admin-thumb-fiat' ),
  226. )
  227. );
  228. }
  229. /**
  230. * @return array|bool
  231. * @since 1.0.0
  232. *
  233. * @uses fiat_thumb
  234. *
  235. * Function to process an image attachment id via AJAX and return to caller
  236. * This is used to populate the "Thumb" column with an image html snippet of the selected thumbnail
  237. *
  238. */
  239. public function fiat_get_thumbnail() {
  240. // Get the post id we are to attach the image to
  241. if ( isset( $_POST['post_id'] ) && ! empty( $_POST['post_id'] ) ) {
  242. $post_ID = intval( $_POST['post_id'] );
  243. if ( ! current_user_can( 'edit_post', $post_ID ) ) {
  244. wp_die( -1 );
  245. } else {
  246. // Check we know who's calling us before proceeding
  247. check_ajax_referer( 'set_post_thumbnail-' . $post_ID, $this->fiat_nonce );
  248. // Get thumbnail ID so we can then get html src to use for thumbnail
  249. if ( isset( $_POST['thumbnail_id'] ) && ! empty( $_POST['thumbnail_id'] ) ) {
  250. $thumbnail_id = intval( $_POST['thumbnail_id'] );
  251. $thumb_url = get_image_tag( $thumbnail_id, '', '', '', $this->fiat_image_size );
  252. $html = sprintf(
  253. $this->template_html,
  254. admin_url( 'media-upload.php?post_id=' . $post_ID . '&amp;type=image&amp;TB_iframe=1&_wpnonce=' . wp_create_nonce( 'set_post_thumbnail-' . $post_ID ) ),
  255. $thumb_url,
  256. esc_attr( $thumbnail_id )
  257. );
  258. echo wp_kses( $html, $this->fiat_kses );
  259. }
  260. }
  261. }
  262. die();
  263. }
  264. /**
  265. * @param $column
  266. * @param $post_id
  267. * @return void
  268. * @since 1.0.0
  269. * @uses fiat_thumb, thumb
  270. *
  271. * Insert representative thumbnail image into Admin Dashboard view
  272. * for All Posts/Pages if we are on the "thumb" column
  273. *
  274. */
  275. public function fiat_custom_columns( $column, $post_id ) {
  276. switch ( $column ) {
  277. case 'thumb':
  278. if ( has_post_thumbnail( $post_id ) ) {
  279. // Determine if our image size has been created and use
  280. // that size/attribute combination
  281. // else get the post-thumbnail image and apply custom sizing to
  282. // size it to fit in the admin dashboard
  283. $sizes = '';
  284. $thumbnail_id = get_post_thumbnail_id( $post_id );
  285. $tpm = wp_get_attachment_metadata( $thumbnail_id );
  286. if ( false !== $tpm && ! empty( $tpm ) ) {
  287. $sizes = $tpm['sizes'];
  288. }
  289. // Default to thumbnail size (as this will be sized down reducing the bandwidth until the image thumbnail is regenerated)
  290. $fiat_image_size = 'thumbnail';
  291. // Review the sizes this particular image has been set to
  292. if ( is_array( $sizes ) ) {
  293. foreach ( $sizes as $s => $k ) {
  294. if ( $this->fiat_image_size === $s ) {
  295. // our size is present, set it and break out
  296. $fiat_image_size = $this->fiat_image_size;
  297. break;
  298. }
  299. }
  300. }
  301. /**
  302. * Check if WooCommerce is active
  303. * If so, only return anchor link markup to inline edit thumbnail
  304. * WooCommerce will supply the image markup
  305. **/
  306. if ( $this->fiat_on_woocommerce_products_list() ) {
  307. $thumb_url = '';
  308. } else {
  309. if ( 'thumbnail' === $fiat_image_size ) {
  310. // size down this time
  311. $thumb_url = wp_get_attachment_image( $thumbnail_id, array( 60, 60 ) );
  312. } else {
  313. // use native sized image
  314. $thumb_url = get_image_tag( $thumbnail_id, '', '', '', $fiat_image_size );
  315. }
  316. }
  317. // Here it is!
  318. $this->fiat_nonce = wp_create_nonce( 'set_post_thumbnail-' . $post_id );
  319. $html = sprintf(
  320. $this->template_html,
  321. admin_url( 'media-upload.php?post_id=' . $post_id . '&amp;type=image&amp;TB_iframe=1&_wpnonce=' . $this->fiat_nonce ),
  322. $thumb_url,
  323. $thumbnail_id
  324. );
  325. // Click me to change!
  326. echo wp_kses( $html, $this->fiat_kses );
  327. } else {
  328. $this->fiat_nonce = wp_create_nonce( 'set_post_thumbnail-' . $post_id );
  329. $set_featured_image = sprintf( __( 'Set %s featured image', 'featured-image-admin-thumb-fiat' ), '<br/>' );
  330. $set_edit_markup = $this->fiat_on_woocommerce_products_list() ? '' : $set_featured_image;
  331. $html = sprintf(
  332. $this->template_html,
  333. admin_url( 'media-upload.php?post_id=' . $post_id . '&amp;type=image&amp;TB_iframe=1&_wpnonce=' . $this->fiat_nonce ),
  334. $set_edit_markup,
  335. $post_id
  336. );
  337. // Click me!
  338. echo wp_kses( $html, $this->fiat_kses );
  339. }
  340. break;
  341. }
  342. }
  343. /**
  344. * @return bool
  345. *
  346. * Is WooCommerce installed and activated and we are showing the product post type?
  347. *
  348. * Logic from here: https://docs.woothemes.com/document/create-a-plugin/
  349. */
  350. public function fiat_on_woocommerce_products_list() {
  351. global $post;
  352. return null !== $post && 'product' === $post->post_type && $this->is_woocommerce_active;
  353. }
  354. /**
  355. * @param $columns
  356. * @return array
  357. * @since 1.0.0
  358. *
  359. * Add our custom column to all posts/pages/custom post types view
  360. *
  361. */
  362. public function fiat_add_thumb_column( $columns ) {
  363. /**
  364. * Check if WooCommerce is active
  365. * If so WooCommerce supplies the title for the column and then we bail
  366. **/
  367. if ( $this->fiat_on_woocommerce_products_list() ) {
  368. return $columns;
  369. } else {
  370. return array_merge(
  371. $columns,
  372. array(
  373. 'thumb' => __( 'Thumb', 'featured-image-admin-thumb-fiat' ),
  374. )
  375. );
  376. }
  377. }
  378. /**
  379. * Check query is main query within admin and if so check
  380. * to see if it's on the thumb column and determine the query
  381. * modification to make.
  382. *
  383. * @param \WP_Query $query
  384. */
  385. public function fiat_posts_orderby( $query ) {
  386. if ( ! is_admin() || ! $query->is_main_query() && ! $this->fiat_on_woocommerce_products_list() ) {
  387. return;
  388. }
  389. if ( 'thumb' === $query->get( 'orderby' ) ) {
  390. $query->set( 'orderby', 'meta_value' );
  391. $query->set( 'meta_key', '_thumbnail_id' );
  392. $query->set( 'meta_type', 'NUMERIC' );
  393. $query->set( 'post_status', 'any' );
  394. 'desc' === $query->get( 'order' ) ? $query->set( 'meta_compare', 'NOT EXISTS' ) : $query->set( 'meta_compare', 'EXISTS' );
  395. }
  396. }
  397. /**
  398. * Add the Thumb column to the available sortable columns
  399. * @param $columns
  400. *
  401. * @return mixed
  402. */
  403. public function fiat_thumb_sortable_columns( $columns ) {
  404. $columns['thumb'] = 'thumb';
  405. return $columns;
  406. }
  407. }