PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/class.redirector.admin.php

https://github.com/Horttcore/Redirector
PHP | 651 lines | 322 code | 208 blank | 121 comment | 48 complexity | 80b3eebd620c2274a899e8bd6df58dd5 MD5 | raw file
  1. <?php
  2. /**
  3. * Security, checks if WordPress is running
  4. **/
  5. if ( !function_exists( 'add_action' ) ) :
  6. header( 'Status: 403 Forbidden' );
  7. header( 'HTTP/1.1 403 Forbidden' );
  8. exit();
  9. endif;
  10. /**
  11. * Redirector Admin Class
  12. *
  13. * @package Redirector
  14. * @since 3.0.1
  15. * @author Ralf Hortt
  16. */
  17. final class Redirector_Admin {
  18. /**
  19. * Version
  20. *
  21. * @var string
  22. **/
  23. protected $version = '3.0.1';
  24. /**
  25. * Constructor
  26. *
  27. * @access public
  28. * @since v3.0.0
  29. * @author Ralf Hortt
  30. **/
  31. public function __construct()
  32. {
  33. add_action( 'admin_init', array( $this, 'admin_init' ) );
  34. add_action( 'admin_print_scripts-post.php', array( $this, 'enqueue_script' ) );
  35. add_action( 'admin_print_scripts-post-new.php', array( $this, 'enqueue_script' ) );
  36. add_action( 'admin_print_styles-post.php', array( $this, 'enqueue_style' ) );
  37. add_action( 'admin_print_styles-post-new.php', array( $this, 'enqueue_style' ) );
  38. add_action( 'plugins_loaded', array( $this, 'load_plugin_textdomain' ) );
  39. add_action( 'plugins_loaded', array( $this, 'maybe_update' ) );
  40. add_action( 'save_post', array( $this, 'save_post' ) );
  41. add_action( 'wp_ajax_redirector-search-posts', array( $this, 'search_posts' ) );
  42. add_post_type_support( 'page', 'redirector' );
  43. } // end __construct
  44. /**
  45. * Plugin initialisation
  46. *
  47. * @access public
  48. * @since v3.0.0
  49. * @author Ralf Hortt
  50. **/
  51. public function admin_init()
  52. {
  53. $post_types = get_post_types();
  54. if ( !$post_types )
  55. return;
  56. foreach ( $post_types as $post_type ) :
  57. if ( !post_type_supports( $post_type, 'redirector' ) )
  58. continue;
  59. add_meta_box( 'redirect', __( 'Redirect', 'redirector' ), array( $this, 'metabox' ), $post_type, 'side' );
  60. endforeach;
  61. } // end admin_init
  62. /**
  63. * Enqueue Javascript
  64. *
  65. * @access public
  66. * @since v3.0.0
  67. * @author Ralf Hortt
  68. **/
  69. public function enqueue_script()
  70. {
  71. wp_register_script( 'redirector', plugins_url( '../javascript/redirector.js', __FILE__ ), array( 'jquery', 'thickbox', 'underscore', 'backbone' ) );
  72. wp_localize_script( 'redirector', 'redirector', array(
  73. 'searchNonce' => wp_create_nonce( 'redirector-search-nonce' ),
  74. ) );
  75. wp_enqueue_script( 'redirector' );
  76. } // end enqueue_script
  77. /**
  78. * Enqueue CSS
  79. *
  80. * @access public
  81. * @since v3.0.0
  82. * @author Ralf Hortt
  83. **/
  84. public function enqueue_style()
  85. {
  86. wp_enqueue_style( 'redirector', plugins_url( '../css/redirector.css', __FILE__ ) );
  87. } // end enqueue_style
  88. /**
  89. * Returns page of the first child
  90. *
  91. * @access public
  92. * @param int $post_id Post ID
  93. * @since v3.0.0
  94. * @author Ralf Hortt
  95. **/
  96. public function get_first_child_title( $post_id )
  97. {
  98. $post_type = get_post_type( $post_id );
  99. $post = get_posts( array(
  100. 'post_type' => $post_type,
  101. 'post_parent' => $post_id,
  102. 'orderby' => 'menu_order',
  103. 'order' => 'ASC',
  104. 'numberposts' => 1,
  105. ) );
  106. if ( !empty( $post ) )
  107. return '<a href="' . get_permalink( $post[0]->ID ) . '" target="_blank">' . $post[0]->post_title . '</a>';
  108. else
  109. return FALSE;
  110. } // end get_first_child_title
  111. /**
  112. * List posts
  113. *
  114. * @access protected
  115. * @since v3.0.0
  116. * @author Ralf Hortt
  117. **/
  118. protected function list_posts( $posts )
  119. {
  120. $post_types = array();
  121. ?>
  122. <table class="widefat">
  123. <thead>
  124. <tr>
  125. <th><?php _e( 'Title' ) ?></th>
  126. <th><?php _e( 'Type' ) ?></th>
  127. <th>&nbsp;</th>
  128. </tr>
  129. </thead>
  130. <tbody>
  131. <?php
  132. $i = 1;
  133. foreach ( $posts as $post ) :
  134. $class = ( 1 == $i % 2 ) ? 'alternate' : 'default';
  135. $title = ( '' == $post->post_title ) ? __( '( No title )', 'redirector' ) : $post->post_title;
  136. if ( !isset( $post_types[$post->post_type] ) ) :
  137. $post_type = get_post_type_object( $post->post_type );
  138. $post_types[$post->post_type] = $post_type->labels->singular_name;
  139. endif;
  140. ?>
  141. <tr class="<?php echo $class ?>">
  142. <th class="item-title">
  143. <a href="<?php echo get_permalink( $post->ID ) ?>" target="_blank"><?php echo $title ?></a>
  144. <?php if ( 'post' == $post->post_type ) :
  145. echo '<br><i>' . date_i18n( get_option( 'date_format' ), strtotime( $post->post_date ) ) . '</i>';
  146. endif;
  147. ?>
  148. </th>
  149. <td class="item-info"><?php echo $post_types[$post->post_type] ?></td>
  150. <td><a class="button select-redirector-post-id" href="#" data-id="<?php echo $post->ID ?>"><?php _e( 'Select', 'redirector' ); ?></a></td>
  151. </tr>
  152. <?php
  153. $i++;
  154. endforeach;
  155. ?>
  156. </tbody>
  157. <tfoot>
  158. <tr>
  159. <th><?php _e( 'Title' ) ?></th>
  160. <th><?php _e( 'Type' ) ?></th>
  161. <th>&nbsp;</th>
  162. </tr>
  163. </tfoot>
  164. </table>
  165. <?php
  166. } // end list_posts
  167. /**
  168. * Load plugin textdomain
  169. *
  170. * @access public
  171. * @since v3.0.0
  172. * @author Ralf Hortt
  173. **/
  174. public function load_plugin_textdomain()
  175. {
  176. load_plugin_textdomain( 'redirector', false, dirname( plugin_basename( __FILE__ ) ) . '/../languages/' );
  177. } // end load_plugin_textdomain
  178. /**
  179. * Check if database update is needed
  180. *
  181. * @access protected
  182. * @since v3.0.0
  183. * @author Ralf Hortt
  184. **/
  185. public function maybe_update()
  186. {
  187. $options = get_option( 'redirector' );
  188. if ( isset( $options['version'] ) && version_compare( $this->version, $options['version'], '<=' ) )
  189. return;
  190. global $wpdb;
  191. // Update from v1.x.x to v2.x.x
  192. $sql = "UPDATE $wpdb->postmeta SET meta_key = '_redirector' WHERE meta_key = 'redirector'";
  193. $wpdb->query($sql);
  194. // Update from v2.x.x to v3.x.x
  195. $meta = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '_redirector'" );
  196. if ( !$meta )
  197. return;
  198. foreach ( $meta as $m ) :
  199. // No need to do something
  200. if ( is_serialized( $m->meta_value ) )
  201. continue;
  202. // Post
  203. if ( is_numeric( $m->meta_value ) ) :
  204. update_post_meta( $m->post_id, '_redirector', array(
  205. 'type' => 'post',
  206. 'post_id' => $m->meta_value
  207. ) );
  208. // First child
  209. elseif ( 'child' == $m->meta_value ) :
  210. update_post_meta( $m->post_id, '_redirector', array(
  211. 'type' => 'first-child',
  212. ) );
  213. // SSL
  214. elseif ( 'https' == $m->meta_value ) :
  215. update_post_meta( $m->post_id, '_redirector', array(
  216. 'type' => 'https',
  217. ) );
  218. // URL
  219. elseif ( '' != $m->meta_value ) :
  220. update_post_meta( $m->post_id, '_redirector', array(
  221. 'type' => 'url',
  222. 'url' => $m->meta_value
  223. ) );
  224. endif;
  225. do_action( 'redirector-update' );
  226. endforeach;
  227. // Cachify compability
  228. if ( class_exists( 'Cachify' ) ) :
  229. Cachify::flush_total_cache();
  230. endif;
  231. // Update version number
  232. update_option( 'redirector', array(
  233. 'version' => $this->version
  234. ));
  235. } // end maybe_update
  236. /**
  237. * Redirector Meta Box
  238. *
  239. * @access public
  240. * @param obj $post Post Object
  241. * @return output html
  242. * @author Ralf Hortt
  243. **/
  244. public function metabox( $post )
  245. {
  246. $redirect = get_post_meta( $post->ID, '_redirector', TRUE );
  247. $redirect_id = ( isset( $redirect['post_id'] ) ) ? $redirect['post_id'] : '';
  248. $type = ( isset( $redirect['type'] ) ) ? $redirect['type'] : '';
  249. $status = ( isset( $redirect['status'] ) ) ? $redirect['status'] : '302';
  250. wp_nonce_field( 'redirector', 'redirector_nonce' );
  251. do_action( 'redirector_metabox_begin', $post ); ?>
  252. <div class="redirector-redirect-type">
  253. <label><input type="radio" name="redirect-type" value="" <?php if ( !$redirect ) echo 'checked="checked"' ?>> <?php _e( 'None', 'redirector' ); ?></label>
  254. </div><!-- .redirector-redirect-type -->
  255. <div class="redirector-redirect-type">
  256. <label><input type="radio" name="redirect-type" value="post" <?php checked( $type, 'post' ) ?>> <?php _e( 'Post object', 'redirector' ); ?></label>
  257. <div <?php if ( isset( $redirect['type'] ) && 'post' == $redirect['type'] ) echo 'style="display:block;"' ?>>
  258. <input type="hidden" id="redirector-post-id" name="redirector-post-id" value="<?php echo $redirect_id ?>">
  259. <div id="redirector-post-id-preview">
  260. <?php if ( $redirect_id ) : ?>
  261. <a href="<?php get_permalink( $redirect_id ) ?>"><?php echo get_the_title( $redirect_id ) ?></a>
  262. <?php endif; ?>
  263. </div>
  264. <a class="button thickbox" id="redirector-set-post-id" href="#TB_inline?width=640&amp;height=auto&amp;inlineId=redirector-post-search" title="<?php _e( 'Select redirection', 'redirector' ); ?>"><?php _e( 'Select', 'redirector' ); ?></a>
  265. <?php $this->modal_search( $redirect, $redirect_id ) ?>
  266. </div>
  267. </div><!-- .redirector-redirect-type -->
  268. <div class="redirector-redirect-type">
  269. <?php $url = ( isset( $redirect['url'] ) ) ? esc_url( apply_filters( 'redirector_url', $redirect['url'] ) ) : ''; ?>
  270. <label><input type="radio" name="redirect-type" value="url" <?php checked( $type, 'url' ) ?>> <?php _e( 'Website', 'redirector' ); ?></label>
  271. <div <?php if ( 'url' == $type ) echo 'style="display:block;"' ?>>
  272. <label>
  273. <?php _e( 'URL:', 'redirector' ); ?><br>
  274. <input name="redirector-url" value="<?php echo $url ?>" type="url" />
  275. </label><br>
  276. <a id="redirector-url-preview" href="<?php echo $url ?>" target="_blank"><?php echo $url ?></a>
  277. </div>
  278. </div><!-- .redirector-redirect-type -->
  279. <div class="redirector-redirect-type">
  280. <input type="radio" id="redirect_child" data-type="child" name="redirect-type" value="first-child" <?php checked( $type, 'first-child' ) ?>> <label for="redirect_child"><?php _e( 'First child', 'redirector' ); ?></label>
  281. <div <?php if ( 'first-child' == $type ) echo 'style="display:block;"' ?>>
  282. <?php
  283. if ( FALSE !== ( $child_title = $this->get_first_child_title( $post->ID ) ) )
  284. echo $child_title;
  285. else
  286. echo '<i>' . __( 'No child', 'redirector' ) . '</i>';
  287. ?>
  288. </div>
  289. </div><!-- .redirector-redirect-type -->
  290. <div class="redirector-redirect-type">
  291. <input type="radio" id="redirect_https" data-type="https" name="redirect-type" value="https" <?php checked( $type, 'https' ) ?>> <label for="redirect_https"><?php _e( 'SSL', 'redirector' ); ?></label><br>
  292. <div <?php if ( 'https' == $type ) echo 'style="display:block;"' ?>>
  293. <a href="<?php echo esc_url( str_replace( 'http:', 'https:', get_permalink( $post->ID ) ) ) ?>" target="_blank"><?php echo $post->post_title ?></a>
  294. </div>
  295. </div><!-- .redirector-redirect-type -->
  296. <?php do_action( 'redirector-redirect-type', $post ); ?>
  297. <div class="redirector-redirect-status">
  298. <p>
  299. <strong><?php _e( 'Status Code', 'redirector' ); ?></strong>
  300. <?php
  301. $stati = apply_filters( 'redirector-redirect-stati', array(
  302. '301' => __( '301 Moved Permanently', 'redirector' ),
  303. '302' => __( '302 Moved Temporarily / Found', 'redirector' ),
  304. ) );
  305. ksort( $stati );
  306. foreach ( $stati as $value => $label ) :
  307. ?>
  308. <div><label><input <?php checked( $value, $status ) ?> type="radio" name="redirect-status" value="<?php echo $value ?>"> <?php echo $label ?></label></div>
  309. <?php
  310. endforeach;
  311. ?>
  312. </p>
  313. </div>
  314. <?php
  315. do_action( 'redirector_metabox_end', $post );
  316. }
  317. /**
  318. * Modal box
  319. *
  320. * @access protected
  321. * @since v3.0.0
  322. * @author Ralf Hortt
  323. **/
  324. protected function modal_search( $redirect, $redirect_id )
  325. {
  326. do_action( 'redirector-modal-search-begin' );
  327. ?>
  328. <div id="redirector-post-search">
  329. <p>
  330. <input type="search" value="" id="redirector-search" placeholder="<?php _e( 'Search' ); ?>"> <a href="#" class="button" id="redirector-search-post"><?php _e( 'Search' ); ?></a>
  331. </p>
  332. <div id="redirector-search-result"></div>
  333. <div id="redirector-recent-posts">
  334. <?php $this->recent_posts(); ?>
  335. </div>
  336. </div>
  337. <?php
  338. do_action( 'redirector-modal-search-end' );
  339. } // end modal_search
  340. /**
  341. * Display recent posts
  342. *
  343. * @access protected
  344. * @since v3.0.0
  345. * @author Ralf Hortt
  346. **/
  347. protected function recent_posts()
  348. {
  349. $posts = get_posts( apply_filters( 'redirector-recent-posts', array(
  350. 'post_type' => 'any',
  351. 'orderby' => 'post_date',
  352. 'order' => 'ASC',
  353. 'showposts' => 10,
  354. ) ) );
  355. if ( !$posts )
  356. echo '<i>' . __( 'No recent posts', 'redirector' ) . '</i>';
  357. ?>
  358. <h2><?php _e( 'Most recent posts', 'redirector' ); ?></h2>
  359. <?php $this->list_posts( $posts );
  360. } // end recent_posts
  361. /**
  362. * Save as post meta
  363. *
  364. * @access public
  365. * @param int $post_id Post ID
  366. * @since v3.0.0
  367. * @author Ralf Hortt
  368. **/
  369. public function save_post( $post_id )
  370. {
  371. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
  372. return;
  373. if ( !isset( $_POST['redirector_nonce'] ) || !wp_verify_nonce( $_POST['redirector_nonce'], 'redirector' ) )
  374. return;
  375. if ( isset( $_POST['redirect-type'] ) && '' != $_POST['redirect-type'] ) :
  376. $options = array(
  377. 'type' => sanitize_text_field( $_POST['redirect-type'] ),
  378. );
  379. switch ( $_POST['redirect-type'] ) :
  380. // Save post id
  381. case 'post' :
  382. if ( '' != $_POST['redirector-post-id'] )
  383. $options['post_id'] = intval( $_POST['redirector-post-id'] );
  384. else
  385. unset( $options['type'] );
  386. break;
  387. // Save redirect url
  388. case 'url' :
  389. if ( '' != $_POST['redirector-url'] )
  390. $options['url'] = sanitize_url( $_POST['redirector-url'] );
  391. else
  392. unset( $options['type'] );
  393. break;
  394. // Unset redirect if no child exists
  395. case 'first-child' :
  396. if ( '' == $this->get_first_child_title( $post_id ) )
  397. unset( $options['type'] );
  398. break;
  399. endswitch;
  400. $options['status'] = ( 0 === intval( $_POST['redirect-status'] ) ) ? 302 : intval( $_POST['redirect-status'] );
  401. $options = apply_filters( 'redirector-meta', $options );
  402. if ( isset( $options['type'] ) )
  403. update_post_meta( $post_id, '_redirector', $options );
  404. else
  405. delete_post_meta( $post_id, '_redirector' );
  406. else :
  407. delete_post_meta( $post_id, '_redirector' );
  408. endif;
  409. } // end save_post
  410. /**
  411. * Search posts
  412. *
  413. * @access public
  414. * @since v.3.0.0
  415. * @author Ralf Hortt
  416. **/
  417. public function search_posts()
  418. {
  419. if ( !wp_verify_nonce( $_POST['nonce'], 'redirector-search-nonce' ) )
  420. return;
  421. $post_types = get_post_types( array( 'public' => true ), 'objects' );
  422. $post_types = array_keys( $post_types );
  423. $query = apply_filters( 'redirector-search-query', array(
  424. 'post_type' => $post_types,
  425. 'suppress_filters' => true,
  426. 'update_post_term_cache' => false,
  427. 'update_post_meta_cache' => false,
  428. 'post_status' => 'publish',
  429. 'posts_per_page' => -1,
  430. 's' => sanitize_text_field( $_REQUEST['search'] ),
  431. ) );
  432. $query = new WP_Query( $query );
  433. $response = array();
  434. ob_start();
  435. printf( '<h2>' . __( 'Search Result for ā€ž%sā€œ', 'redirector' ) . '</h2>', sanitize_text_field( $_REQUEST['search'] ) );
  436. $this->list_posts( $query->posts );
  437. $response['output'] = ob_get_contents();
  438. ob_end_clean();
  439. wp_reset_query();
  440. die( json_encode( $response ) );
  441. } // end search_posts
  442. } // end Redirector_Admin
  443. new Redirector_Admin();