Advertisement
Guest User

class-import-export.php

a guest
May 13th, 2019
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.50 KB | None | 0 0
  1. <?php
  2. /**
  3. * The Import Export Class
  4. *
  5. * @since 0.9.0
  6. * @package RankMath
  7. * @subpackage RankMath\Admin
  8. * @author Rank Math <support@rankmath.com>
  9. */
  10.  
  11. namespace RankMath\Admin;
  12.  
  13. use RankMath\Runner;
  14. use RankMath\Traits\Ajax;
  15. use RankMath\Traits\Hooker;
  16. use RankMath\Helper as GlobalHelper;
  17. use RankMath\Admin\Importers\Detector;
  18. use MyThemeShop\Admin\Page;
  19. use MyThemeShop\Helpers\WordPress;
  20.  
  21. defined( 'ABSPATH' ) || exit;
  22.  
  23. /**
  24. * Import_Export class.
  25. */
  26. class Import_Export implements Runner {
  27.  
  28. use Hooker, Ajax;
  29.  
  30. /**
  31. * Register hooks.
  32. */
  33. public function hooks() {
  34. $this->action( 'init', 'register_page', 1 );
  35. $this->action( 'rank_math/importers/settings/pre_import', 'run_backup', 10, 0 );
  36.  
  37. $this->ajax( 'create_backup', 'create_backup' );
  38. $this->ajax( 'delete_backup', 'delete_backup' );
  39. $this->ajax( 'restore_backup', 'restore_backup' );
  40. $this->ajax( 'clean_plugin', 'clean_plugin' );
  41. $this->ajax( 'import_plugin', 'import_plugin' );
  42. }
  43.  
  44. /**
  45. * Register admin pages for plugin.
  46. */
  47. public function register_page() {
  48. $uri = rank_math()->plugin_url() . 'assets/admin/';
  49. new Page( 'rank-math-import-export', esc_html__( 'Import &amp; Export', 'rank-math' ), [
  50. 'position' => 99,
  51. 'parent' => 'rank-math',
  52. 'render' => Admin_Helper::get_view( 'import-export/main' ),
  53. 'onsave' => [ $this, 'handler' ],
  54. 'classes' => [ 'rank-math-page' ],
  55. 'assets' => [
  56. 'styles' => [
  57. 'cmb2-styles' => '',
  58. 'rank-math-common' => '',
  59. 'rank-math-cmb2' => '',
  60. ],
  61. 'scripts' => [ 'rank-math-import-export' => $uri . 'js/import-export.js' ],
  62. ],
  63. ]);
  64.  
  65. GlobalHelper::add_json( 'importConfirm', esc_html__( 'Are you sure you want to import settings into Rank Math? Don\'t worry, your current configuration will be saved as a backup.', 'rank-math' ) );
  66. GlobalHelper::add_json( 'restoreConfirm', esc_html__( 'Are you sure you want to restore this backup? Your current configuration will be overwritten.', 'rank-math' ) );
  67. GlobalHelper::add_json( 'deleteBackupConfirm', esc_html__( 'Are you sure you want to delete this backup?', 'rank-math' ) );
  68. GlobalHelper::add_json( 'cleanPluginConfirm', esc_html__( 'Are you sure you want erase traces of plugin?', 'rank-math' ) );
  69. }
  70.  
  71. /**
  72. * Handle import or export.
  73. */
  74. public function handler() {
  75.  
  76. if ( ! isset( $_POST['object_id'] ) ) {
  77. return;
  78. }
  79.  
  80. if ( 'export-plz' === $_POST['object_id'] && check_admin_referer( 'rank-math-export-settings' ) ) {
  81. $this->export();
  82. }
  83.  
  84. if ( isset( $_FILES['import-me'] ) && 'import-plz' === $_POST['object_id'] && check_admin_referer( 'rank-math-import-settings' ) ) {
  85. $this->import();
  86. }
  87. }
  88.  
  89. /**
  90. * Handles AJAX plugin run clean.
  91. */
  92. public function clean_plugin() {
  93.  
  94. $this->verify_nonce( 'rank-math-ajax-nonce' );
  95.  
  96. $result = Detector::run_by_slug( $_POST['pluginSlug'], 'cleanup' );
  97.  
  98. if ( $result['status'] ) {
  99. /* translators: Plugin name */
  100. $this->success( sprintf( esc_html__( 'Cleanup of %s data successfully done.', 'rank-math' ), $result['importer']->get_plugin_name() ) );
  101. }
  102.  
  103. /* translators: Plugin name */
  104. $this->error( sprintf( esc_html__( 'Cleanup of %s data failed.', 'rank-math' ), $result['importer']->get_plugin_name() ) );
  105. }
  106.  
  107. /**
  108. * Handles AJAX plugin run import.
  109. */
  110. public function import_plugin() {
  111.  
  112. $this->verify_nonce( 'rank-math-ajax-nonce' );
  113.  
  114. $this->has_cap_ajax( 'general' );
  115.  
  116. $perform = isset( $_POST['perform'] ) ? filter_input( INPUT_POST, 'perform' ) : false;
  117. if ( ! $perform || ! in_array( $perform, [ 'settings', 'postmeta', 'termmeta', 'usermeta', 'redirections', 'deactivate' ] ) ) {
  118. $this->error( esc_html__( 'Action not allowed.', 'rank-math' ) );
  119. }
  120.  
  121. try {
  122. $result = Detector::run_by_slug( $_POST['pluginSlug'], 'import', $perform );
  123. $this->success( $result );
  124. } catch ( \Exception $e ) {
  125. $this->error( $e->getMessage() );
  126. }
  127.  
  128. }
  129.  
  130. /**
  131. * Handles AJAX create backup.
  132. */
  133. public function create_backup() {
  134.  
  135. $this->verify_nonce( 'rank-math-ajax-nonce' );
  136.  
  137. $key = $this->run_backup();
  138. if ( is_null( $key ) ) {
  139. $this->error( esc_html__( 'Unable to create backup this time.', 'rank-math' ) );
  140. }
  141.  
  142. $this->success([
  143. 'key' => $key,
  144. /* translators: Backup formatted date */
  145. 'backup' => sprintf( esc_html__( 'Backup: %s', 'rank-math' ), date( 'M jS Y, H:i a', $key ) ),
  146. 'message' => esc_html__( 'Backup created successfully.', 'rank-math' ),
  147. ]);
  148. }
  149.  
  150. /**
  151. * Handles AJAX delete backup.
  152. */
  153. public function delete_backup() {
  154.  
  155. $this->verify_nonce( 'rank-math-ajax-nonce' );
  156.  
  157. $key = isset( $_POST['key'] ) ? $_POST['key'] : false;
  158. if ( ! $key ) {
  159. $this->error( esc_html__( 'No backup key found to delete.', 'rank-math' ) );
  160. }
  161.  
  162. $this->run_backup( 'delete', $key );
  163. $this->success( esc_html__( 'Backup successfully deleted.', 'rank-math' ) );
  164. }
  165.  
  166. /**
  167. * Handles AJAX restore backup.
  168. */
  169. public function restore_backup() {
  170.  
  171. $this->verify_nonce( 'rank-math-ajax-nonce' );
  172.  
  173. $key = isset( $_POST['key'] ) ? $_POST['key'] : false;
  174. if ( ! $key ) {
  175. $this->error( esc_html__( 'No backup key found to restore.', 'rank-math' ) );
  176. }
  177.  
  178. if ( ! $this->run_backup( 'restore', $key ) ) {
  179. $this->error( esc_html__( 'Backup does not exist.', 'rank-math' ) );
  180. }
  181.  
  182. $this->success( esc_html__( 'Backup restored successfully.', 'rank-math' ) );
  183. }
  184.  
  185. /**
  186. * Run backup actions
  187. *
  188. * @param string $action Action to perform.
  189. * @param array $key Key to backup.
  190. * @return mixed
  191. */
  192. public function run_backup( $action = 'add', $key = null ) {
  193. $backups = get_option( 'rank_math_backups', [] );
  194.  
  195. // Restore.
  196. if ( 'restore' === $action ) {
  197. if ( ! isset( $backups[ $key ] ) ) {
  198. return false;
  199. }
  200.  
  201. $this->do_import_data( $backups[ $key ], true );
  202.  
  203. return true;
  204. }
  205.  
  206. // Add.
  207. if ( 'add' === $action ) {
  208. $key = current_time( 'U' );
  209. $backups = [ $key => $this->get_export_data() ] + $backups;
  210. }
  211.  
  212. // Delete.
  213. if ( 'delete' === $action && isset( $backups[ $key ] ) ) {
  214. unset( $backups[ $key ] );
  215. }
  216.  
  217. update_option( 'rank_math_backups', $backups );
  218.  
  219. return $key;
  220. }
  221.  
  222. /**
  223. * Handle export.
  224. */
  225. private function export() {
  226. $panels = $_POST['panels'];
  227. $data = $this->get_export_data( $panels );
  228. $filename = 'rank-math-settings-' . date( 'Y-m-d-H-i-s' ) . '.txt';
  229.  
  230. header( 'Content-Type: application/txt' );
  231. header( 'Content-Disposition: attachment; filename=' . $filename );
  232. header( 'Cache-Control: no-cache, no-store, must-revalidate' );
  233. header( 'Pragma: no-cache' );
  234. header( 'Expires: 0' );
  235.  
  236. echo wp_json_encode( $data );
  237. exit;
  238. }
  239.  
  240. /**
  241. * Handle import.
  242. */
  243. private function import() {
  244.  
  245. // Handle file upload.
  246. $file = wp_handle_upload( $_FILES['import-me'] );
  247. if ( is_wp_error( $file ) ) {
  248. GlobalHelper::add_notification( esc_html__( 'Settings could not be imported:', 'rank-math' ) . ' ' . $file->get_error_message(), [ 'type' => 'error' ] );
  249. return false;
  250. }
  251.  
  252. if ( is_array( $file ) && isset( $file['error'] ) ) {
  253. GlobalHelper::add_notification( esc_html__( 'Settings could not be imported:', 'rank-math' ) . ' ' . $file['error'], [ 'type' => 'error' ] );
  254. return false;
  255. }
  256.  
  257. if ( ! isset( $file['file'] ) ) {
  258. GlobalHelper::add_notification( esc_html__( 'Settings could not be imported:', 'rank-math' ) . ' ' . esc_html__( 'Upload failed.', 'rank-math' ), [ 'type' => 'error' ] );
  259. return false;
  260. }
  261.  
  262. // Parse Options.
  263. $wp_filesystem = WordPress::get_filesystem();
  264. $settings = $wp_filesystem->get_contents( $file['file'] );
  265. $settings = json_decode( $settings, true );
  266.  
  267. \unlink( $file['file'] );
  268.  
  269. if ( $this->do_import_data( $settings ) ) {
  270. GlobalHelper::add_notification( esc_html__( 'Settings successfully imported. Your old configuration has been saved as a backup.', 'rank-math' ), 'success' );
  271. return;
  272. }
  273.  
  274. GlobalHelper::add_notification( esc_html__( 'No settings found to be imported.', 'rank-math' ), [ 'type' => 'info' ] );
  275. }
  276.  
  277. /**
  278. * Does import data.
  279. *
  280. * @param array $data Import data.
  281. * @param bool $suppress_hooks Suppress hooks or not.
  282. * @return bool
  283. */
  284. private function do_import_data( array $data, $suppress_hooks = false ) {
  285.  
  286. $this->run_import_hooks( 'pre_import', $data, $suppress_hooks );
  287.  
  288. // Import options.
  289. $down = $this->set_options( $data );
  290.  
  291. // Import capabilities.
  292. if ( isset( $data['role-manager'] ) && ! empty( $data['role-manager'] ) ) {
  293. $down = true;
  294. GlobalHelper::set_capabilities( $data['role-manager'] );
  295. }
  296.  
  297. // Import redirections.
  298. if ( isset( $data['redirections'] ) && ! empty( $data['redirections'] ) ) {
  299. $down = true;
  300. $this->set_redirections( $data['redirections'] );
  301. }
  302.  
  303. $this->run_import_hooks( 'after_import', $data, $suppress_hooks );
  304.  
  305. return $down;
  306. }
  307.  
  308. /**
  309. * Set options from data.
  310. *
  311. * @param array $data An array of data.
  312. */
  313. private function set_options( $data ) {
  314. $set = false;
  315. $hash = [
  316. 'modules' => 'rank_math_modules',
  317. 'general' => 'rank-math-options-general',
  318. 'titles' => 'rank-math-options-titles',
  319. 'sitemap' => 'rank-math-options-sitemap',
  320. ];
  321.  
  322. foreach ( $hash as $key => $option_key ) {
  323. if ( ! empty( $data[ $key ] ) ) {
  324. $set = true;
  325. update_option( $option_key, $data[ $key ] );
  326. }
  327. }
  328.  
  329. return $set;
  330. }
  331.  
  332. /**
  333. * Set redirections.
  334. *
  335. * @param array $redirections An array of redirections to import.
  336. */
  337. private function set_redirections( $redirections ) {
  338. foreach ( $redirections as $key => $redirection ) {
  339. $matched = \RankMath\Redirections\DB::match_redirections_source( $redirection['sources'] );
  340. if ( ! empty( $matched ) ) {
  341. continue;
  342. }
  343.  
  344. \RankMath\Redirections\DB::add(
  345. [
  346. 'url_to' => $redirection['url_to'],
  347. 'sources' => unserialize( $redirection['sources'] ),
  348. 'header_code' => $redirection['header_code'],
  349. 'hits' => $redirection['hits'],
  350. 'created' => $redirection['created'],
  351. 'updated' => $redirection['updated'],
  352. ]
  353. );
  354. }
  355. }
  356.  
  357. /**
  358. * Run import hooks
  359. *
  360. * @param string $hook Hook to fire.
  361. * @param array $data Import data.
  362. * @param bool $suppress Suppress hooks or not.
  363. */
  364. private function run_import_hooks( $hook, $data, $suppress ) {
  365. if ( ! $suppress ) {
  366. /**
  367. * Fires while importing settings.
  368. *
  369. * @since 0.9.0
  370. *
  371. * @param array $data Import data.
  372. */
  373. $this->do_action( 'importers/settings/' . $hook, $data );
  374. }
  375. }
  376.  
  377. /**
  378. * Gets export data.
  379. *
  380. * @param array $panels Which panels do you want to export. It will export all panels if this param is empty.
  381. * @return array
  382. */
  383. private function get_export_data( array $panels = [] ) {
  384. if ( ! $panels ) {
  385. $panels = [ 'general', 'titles', 'sitemap', 'role-manager', 'redirections' ];
  386. }
  387.  
  388. $settings = rank_math()->settings->all_raw();
  389.  
  390. foreach ( $panels as $panel ) {
  391. if ( isset( $settings[ $panel ] ) ) {
  392. $data[ $panel ] = $settings[ $panel ];
  393. }
  394. }
  395.  
  396. if ( \in_array( 'role-manager', $panels ) ) {
  397. $data['role-manager'] = GlobalHelper::get_roles_capabilities();
  398. }
  399.  
  400. $data['modules'] = rank_math()->manager->get_active_modules();
  401.  
  402. if ( \in_array( 'redirections', $panels ) ) {
  403. $items = \RankMath\Redirections\DB::get_redirections( [ 'limit' => 1000 ] );
  404.  
  405. $data['redirections'] = $items['redirections'];
  406. }
  407.  
  408. return $data;
  409. }
  410. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement