All_in_One_SEO_Pack_Importer_Exporter

Class All_in_One_SEO_Pack_Importer_Exporter.

Defined (1)

The class is defined in the following location(s).

/modules/aioseop_importer_exporter.php  
  1. class All_in_One_SEO_Pack_Importer_Exporter extends All_in_One_SEO_Pack_Module { 
  2.  
  3.  
  4. /** 
  5. * All_in_One_SEO_Pack_Importer_Exporter constructor. 
  6. */ 
  7. function __construct() { 
  8. $this->name = __( 'Importer & Exporter', 'all-in-one-seo-pack' ); // Human-readable name of the module 
  9. $this->prefix = 'aiosp_importer_exporter_'; // option prefix 
  10. $this->file = __FILE__; 
  11. parent::__construct(); 
  12. $help_text = Array( 
  13. 'import_submit' => __( 
  14. "Select a valid All in One SEO Pack ini file and click 'Import' to import options from a previous state or install of All in One SEO Pack.<br /><a href='http://semperplugins.com/documentation/importer-exporter-module/' target='_blank'>Click here for documentation on this setting</a>",  
  15. 'all-in-one-seo-pack' 
  16. ),  
  17. 'export_choices' => __( 
  18. "You may choose to export settings from active modules, and content from post data.<br /><a href='http://semperplugins.com/documentation/importer-exporter-module/' target='_blank'>Click here for documentation on this setting</a>",  
  19. 'all-in-one-seo-pack' 
  20. ),  
  21. 'export_post_types' => __( 
  22. "Select which Post Types you want to export your All in One SEO Pack meta data for.<br /><a href='http://semperplugins.com/documentation/importer-exporter-module/' target='_blank'>Click here for documentation on this setting</a>",  
  23. 'all-in-one-seo-pack' 
  24. ),  
  25. ); 
  26. $this->warnings = Array(); 
  27. $this->default_options = array( 
  28. 'import_submit' => Array( 
  29. 'name' => __( 'Import', 'all-in-one-seo-pack' ),  
  30. 'default' => '',  
  31. 'type' => 'file',  
  32. 'save' => false,  
  33. ),  
  34. 'export_choices' => Array( 
  35. 'name' => __( 'Export Settings', 'all-in-one-seo-pack' ),  
  36. 'type' => 'multicheckbox',  
  37. 'initial_options' => Array( 
  38. 1 => 'General Settings',  
  39. 2 => 'Post Data',  
  40. ),  
  41. ),  
  42. 'export_post_types' => Array( 
  43. 'name' => __( 'Export Post Types:', 'all-in-one-seo-pack' ),  
  44. 'default' => Array( 
  45. 'post' => 'post',  
  46. 'page' => 'page',  
  47. ),  
  48. 'type' => 'multicheckbox',  
  49. 'initial_options' => $this->get_post_type_titles( 
  50. Array( '_builtin' => false ) 
  51. ),  
  52. ),  
  53. 'import_export_help' => Array( 
  54. 'type' => 'html',  
  55. 'label' => 'none',  
  56. 'default' => __( 
  57. 'Note: If General Settings is checked, the 
  58. General Settings, the Feature Manager settings,  
  59. and the following currently active modules will 
  60. have their settings data exported:',  
  61. 'all-in-one-seo-pack' 
  62. ) . '<br />',  
  63. ),  
  64. ); 
  65. if ( ! empty( $help_text ) ) { 
  66. foreach ( $help_text as $k => $v ) { 
  67. $this->default_options[ $k ]['help_text'] = $v; 
  68. $this->layout = Array( 
  69. 'default' => Array( 
  70. 'name' => $this->name,  
  71. 'help_link' => 'http://semperplugins.com/documentation/importer-exporter-module/',  
  72. 'options' => array_keys( $this->default_options ),  
  73. ),  
  74. ); 
  75.  
  76. // load initial options / set defaults 
  77. add_action( 'admin_init', Array( $this, 'debug_post_types' ), 5 ); 
  78.  
  79.  
  80. function settings_page_init() { 
  81. add_filter( 
  82. $this->prefix . 'submit_options',  
  83. Array( $this, 'filter_submit' ) 
  84. ); 
  85.  
  86.  
  87. /** 
  88. * @param $submit 
  89. * @return array 
  90. */ 
  91. function filter_submit( $submit ) { 
  92. $submit['Submit']['value'] = __( 
  93. 'Import',  
  94. 'all-in-one-seo-pack' 
  95. . ' »'; 
  96.  
  97. return Array( 
  98. 'export_submit' => Array( 
  99. 'type' => 'submit',  
  100. 'class' => 'button-primary',  
  101. 'value' => __( 'Export', 'all-in-one-seo-pack' ) . ' »',  
  102. ),  
  103. ) + $submit; 
  104.  
  105.  
  106. function debug_post_types() { 
  107. $post_types = $this->get_post_type_titles(); 
  108. $rempost = array( 
  109. 'attachment' => 1,  
  110. 'revision' => 1,  
  111. 'nav_menu_item' => 1,  
  112. ); 
  113. $this->default_options['export_post_types']['initial_options'] = array_diff_key( 
  114. $post_types,  
  115. $rempost 
  116. ); 
  117. global $aioseop_modules; 
  118. if ( ! empty( $aioseop_modules ) ) { 
  119. $modules = $aioseop_modules->get_loaded_module_list(); 
  120. if ( ! empty( $modules ) && ! empty( $modules['feature_manager'] ) ) { 
  121. unset( $modules['feature_manager'] ); 
  122. if ( ! empty( $modules ) ) { 
  123. $this->default_options['import_export_help']['default'] .= "<ul>\n"; 
  124. foreach ( $modules as $m ) { 
  125. $module = $aioseop_modules->return_module( $m ); 
  126. $this->default_options['import_export_help']['default'] .= 
  127. "\t<li>" . $module->name . "</li>\n"; 
  128. $this->default_options['import_export_help']['default'] .= "\n</ul>\n"; 
  129. } else { 
  130. $this->default_options['import_export_help']['default'] .= '<br />' 
  131. . __( 
  132. 'There are no other modules currently loaded!',  
  133. 'all-in-one-seo-pack' 
  134. ); 
  135. $this->default_options['import_export_help']['default'] .= '<br />' 
  136. . __( 
  137. 'You may change this by activating or deactivating 
  138. modules in the Feature Manager.',  
  139. 'all-in-one-seo-pack' 
  140. ); 
  141. $this->update_options(); 
  142. if ( ! empty( $_REQUEST['export_submit'] ) ) { 
  143. $this->do_importer_exporter(); 
  144. } else { 
  145. add_action( 
  146. $this->prefix . 'settings_update',  
  147. Array( $this, 'do_importer_exporter' ) 
  148. ); 
  149.  
  150.  
  151. /** 
  152. * @param $args 
  153. * @return string 
  154. */ 
  155. function importer_exporter_export( $args ) { 
  156.  
  157. // Adds all settings to settings file 
  158. $name = $this->get_option_name(); 
  159. $buf = '[' . $this->get_option_name() . "]\n"; 
  160. if ( ! empty( $this->options ) ) { 
  161. foreach ( $this->options as $key => $value ) { 
  162. $buf .= "$key = '" . str_replace( 
  163. "'",  
  164. "\'",  
  165. trim( serialize( $value ) ) 
  166. ) . "'\n"; 
  167.  
  168. return $buf; 
  169.  
  170.  
  171. function show_import_warnings() { 
  172.  
  173. echo '<div class="error fade" style="width:52%">'; 
  174.  
  175. if ( is_array( $this->warnings ) ) { 
  176. foreach ( $this->warnings as $warning ) { 
  177. echo "<p>" . esc_html( $warning ) . "</p>"; 
  178. echo '</div>'; 
  179.  
  180.  
  181. /** 
  182. * @param $array 
  183. * @return array 
  184. */ 
  185. function parse_ini_helper( $array ) { 
  186. $returnArray = array(); 
  187. if ( is_array( $array ) ) { 
  188. foreach ( $array as $key => $value ) { 
  189. $e = explode( ':', $key ); 
  190. if ( ! empty( $e[1] ) ) { 
  191. $x = array(); 
  192. foreach ( $e as $tk => $tv ) { 
  193. $x[ $tk ] = trim( $tv ); 
  194. $x = array_reverse( $x, true ); 
  195. foreach ( $x as $k => $v ) { 
  196. $c = $x[0]; 
  197. if ( empty( $returnArray[ $c ] ) ) { 
  198. $returnArray[ $c ] = array(); 
  199. if ( isset( $returnArray[ $x[1] ] ) ) { 
  200. $returnArray[ $c ] = array_merge( 
  201. $returnArray[ $c ], $returnArray[ $x[1] ] 
  202. ); 
  203. if ( $k === 0 ) { 
  204. $returnArray[ $c ] = array_merge( 
  205. $returnArray[ $c ], $array[ $key ] 
  206. ); 
  207. } else { 
  208. $returnArray[ $key ] = $array[ $key ]; 
  209.  
  210. return $returnArray; 
  211.  
  212.  
  213. /** 
  214. * @param $array 
  215. * @return array 
  216. */ 
  217. function recursive_parse( $array ) { 
  218. $returnArray = array(); 
  219. if ( is_array( $array ) ) { 
  220. foreach ( $array as $key => $value ) { 
  221. if ( is_array( $value ) ) { 
  222. $array[ $key ] = $this->recursive_parse( $value ); 
  223. $x = explode( '.', $key ); 
  224. if ( ! empty( $x[1] ) ) { 
  225. $x = array_reverse( $x, true ); 
  226. if ( isset( $returnArray[ $key ] ) ) { 
  227. unset( $returnArray[ $key ] ); 
  228. if ( ! isset( $returnArray[ $x[0] ] ) ) { 
  229. $returnArray[ $x[0] ] = array(); 
  230. $first = true; 
  231. foreach ( $x as $k => $v ) { 
  232. if ( $first === true ) { 
  233. $b = $array[ $key ]; 
  234. $first = false; 
  235. $b = array( $v => $b ); 
  236. $returnArray[ $x[0] ] = array_merge_recursive( 
  237. $returnArray[ $x[0] ], $b[ $x[0] ] 
  238. ); 
  239. } else { 
  240. $returnArray[ $key ] = $array[ $key ]; 
  241.  
  242. return $returnArray; 
  243.  
  244.  
  245. /** 
  246. * @param $assoc_arr 
  247. * @param bool $has_sections 
  248. * @return string 
  249. */ 
  250. function get_ini_file( $assoc_arr, $has_sections = true ) { 
  251. $content = ''; 
  252. if ( $has_sections ) { 
  253. foreach ( $assoc_arr as $key => $elem ) { 
  254. $content .= '[' . $key . "]\n"; 
  255. foreach ( $elem as $key2 => $elem2 ) { 
  256. if ( is_array( $elem2 ) ) { 
  257. for ( $i = 0; $i < count( $elem2 ); $i ++ ) { 
  258. $content .= $key2 . "[] = \"" . $elem2[ $i ] . "\"\n"; 
  259. } else if ( $elem2 == '' ) { 
  260. $content .= $key2 . " = \n"; 
  261. } else { 
  262. $content .= $key2 . " = \"" . $elem2 . "\"\n"; 
  263. } else { 
  264. foreach ( $assoc_arr as $key => $elem ) { 
  265. if ( is_array( $elem ) ) { 
  266. for ( $i = 0; $i < count( $elem ); $i ++ ) { 
  267. $content .= $key2 . "[] = \"" . $elem[ $i ] . "\"\n"; 
  268. } else if ( $elem == '' ) { 
  269. $content .= $key2 . " = \n"; 
  270. } else { 
  271. $content .= $key2 . " = \"" . $elem . "\"\n"; 
  272.  
  273. return $content; 
  274.  
  275.  
  276. /** 
  277. * @param $string 
  278. * @return array 
  279. */ 
  280. function parse_ini_advanced( $string ) { 
  281. return $this->recursive_parse( 
  282. $this->parse_ini_helper( 
  283. parse_ini_string( $string, true ) 
  284. ); 
  285.  
  286.  
  287. function do_importer_exporter() { 
  288. $submit = null; 
  289. $count = 0; 
  290. $post_exists = null; 
  291. $post_warning = null; 
  292. global $aioseop_options, $aiosp, $aioseop_module_list; 
  293. if ( isset( $_REQUEST['nonce-aioseop'] ) ) { 
  294. $nonce = $_REQUEST['nonce-aioseop']; 
  295. $post_fields = Array( 
  296. 'keywords',  
  297. 'description',  
  298. 'title',  
  299. 'meta',  
  300. 'disable',  
  301. 'disable',  
  302. 'disable_analytics',  
  303. 'titleatr',  
  304. 'menulabel',  
  305. 'togglekeywords',  
  306. ); 
  307. if ( ! empty( $_FILES['aiosp_importer_exporter_import_submit']['tmp_name'] ) ) { 
  308. $submit = 'Import'; 
  309. if ( ! empty( $_REQUEST['export_submit'] ) ) { 
  310. $submit = 'Export'; 
  311. if ( ( $submit != null ) && wp_verify_nonce( $nonce, 'aioseop-nonce' ) ) { 
  312. switch ( $submit ) { 
  313. case 'Import': 
  314. try { 
  315. // Parses export file 
  316. $file = $this->get_sanitized_file( 
  317. $_FILES['aiosp_importer_exporter_import_submit']['tmp_name'] 
  318. ); 
  319. $section = Array(); 
  320. $section_label = null; 
  321. foreach ( $file as $line_number => $line ) { 
  322. $line = trim( $line ); 
  323. $matches = Array(); 
  324. if ( empty( $line ) ) { 
  325. continue; 
  326. if ( $line[0] == ';' ) { 
  327. continue; 
  328. if ( preg_match( "/^\[(\S+)\]$/", $line, $label ) ) { 
  329. $section_label = strval( $label[1] ); 
  330. if ( $section_label == 'post_data' ) { 
  331. $count ++; 
  332. if ( ! isset( $section[ $section_label ] ) ) { 
  333. $section[ $section_label ] = Array(); 
  334. } elseif ( preg_match( "/^(\S+)\s*=\s*'(.*)'$/", $line, $matches ) ) { 
  335. if ( $section_label == 'post_data' ) { 
  336. $section[ $section_label ][ $count ][ $matches[1] ] = $matches[2]; 
  337. } else { 
  338. $section[ $section_label ][ $matches[1] ] = $matches[2]; 
  339. } elseif ( preg_match( "/^(\S+)\s*=\s*NULL$/", $line, $matches ) ) { 
  340. if ( $section_label == 'post_data' ) { 
  341. $section[ $section_label ][ $count ][ $matches[1] ] = null; 
  342. } else { 
  343. $section[ $section_label ][ $matches[1] ] = null; 
  344. } else { 
  345. $this->warnings[] = sprintf( 
  346. __( 
  347. '<b>Warning:</b> Line not matched: <b>"%s"</b>, On Line: <b>%s</b>',  
  348. 'all-in-one-seo-pack' 
  349. ),  
  350. $line,  
  351. $line_number 
  352. ); 
  353.  
  354. // Updates Plugin Settings 
  355. if ( is_array( $section ) ) { 
  356. foreach ( $section as $label => $module_options ) { 
  357. if ( is_array( $module_options ) ) { 
  358. foreach ( $module_options as $key => $value ) { 
  359.  
  360. // Updates Post Data 
  361. if ( $label == 'post_data' ) { 
  362. $post_exists = post_exists( 
  363. $module_options[ $key ]['post_title'],  
  364. '',  
  365. $module_options[ $key ]['post_date'] 
  366. ); 
  367. $target = get_post( $post_exists ); 
  368. if ( ( ! empty( $module_options[ $key ]['post_type'] ) ) 
  369. && $post_exists != null 
  370. ) { 
  371. if ( is_array( $value ) ) { 
  372. foreach ( $value as $field_name => $field_value ) { 
  373. if ( substr( $field_name, 1, 7 ) == 'aioseop' ) { 
  374. if ( $value ) { 
  375. update_post_meta( 
  376. $target->ID,  
  377. $field_name,  
  378. maybe_unserialize( $field_value ) 
  379. ); 
  380. } else { 
  381. delete_post_meta( 
  382. $target->ID,  
  383. $field_name 
  384. ); 
  385. $post_exists = null; 
  386. } else { 
  387. $target_title = $module_options[ $key ]['post_title']; 
  388. $post_warning = sprintf( 
  389. __( 
  390. '<b>Warning:</b> This following post could not be found: <b>"%s"</b>',  
  391. 'all-in-one-seo-pack' 
  392. ),  
  393. $target_title 
  394. ); 
  395. if ( $post_warning != null ) { 
  396. $this->warnings[] = $post_warning; 
  397. $post_warning = null; 
  398.  
  399. // Updates Module Settings 
  400. } else { 
  401. $module_options[ $key ] = str_replace( 
  402. Array( "\'", '\n', '\r' ),  
  403. Array( "'", "\n", "\r" ),  
  404. maybe_unserialize( $value ) 
  405. ); 
  406.  
  407. // Updates Module Settings 
  408. $this->update_class_option( 
  409. $module_options,  
  410. $label 
  411. ); 
  412. } catch ( Exception $e ) { 
  413. $this->warnings[] = $e->getMessage(); 
  414.  
  415. // Shows all errors found 
  416. if ( ! empty( $this->warnings ) ) { 
  417. add_action( 
  418. $this->prefix . 'settings_header',  
  419. Array( $this, 'show_import_warnings' ),  
  420. ); 
  421.  
  422. break; 
  423. case 'Export': 
  424.  
  425. // Creates Files Contents 
  426. $settings_file = 'settings_aioseop.ini'; 
  427. $buf = '; ' . __( 
  428. 'Settings export file for All in One SEO Pack', ' 
  429. all-in-one-seo-pack' 
  430. ) . "\n"; 
  431.  
  432. // Adds all settings to settings file 
  433. $buf = $aiosp->settings_export( $buf ); 
  434. $buf = apply_filters( 'aioseop_export_settings', $buf ); 
  435.  
  436. // Sends File to browser 
  437. $strlength = strlen( $buf ); 
  438. header( 'Content-type: application/ini' ); 
  439. header( 
  440. "Content-Disposition: 
  441. attachment; filename=$settings_file" 
  442. ); 
  443. header( 'Content-Length: ' . $strlength ); 
  444. echo $buf; 
  445. die(); 
  446. break; 
  447.  
  448.  
  449. function settings_update() { 
  450.  
  451. /** 
  452. * Returns sanitized imported file. 
  453. * @since 
  454. * @param string $filename Path to where the uploaded file is located. 
  455. * @return array Sanitized file as array. 
  456. * @throws Exception 
  457. */ 
  458. private function get_sanitized_file( $filename ) { 
  459. $file = file( $filename ); 
  460. for ( $i = count( $file ) - 1; $i >= 0; -- $i ) { 
  461. // Remove insecured lines 
  462. if ( preg_match( '/\<(\?php|script)/', $file[ $i ] ) ) { 
  463. throw new Exception( __( 
  464. '<b>Security warning:</b> Your file looks compromised. Please check the file for any script-injection.',  
  465. 'all-in-one-seo-pack' 
  466. ) ); 
  467. // Apply security filters 
  468. $file[ $i ] = strip_tags( trim( $file[ $i ] ) ); 
  469. // Remove empty lines 
  470. if ( empty( $file[ $i ] ) ) { 
  471. unset( $file[ $i ] ); 
  472.  
  473. return $file;