WPSEO_Export

Class WPSEO_Export.

Defined (1)

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

/admin/class-export.php  
  1. class WPSEO_Export { 
  2.  
  3. const ZIP_FILENAME = 'yoast-seo-settings-export.zip'; 
  4. const INI_FILENAME = 'settings.ini'; 
  5.  
  6. const NONCE_ACTION = 'wpseo_export'; 
  7. const NONCE_NAME = 'wpseo_export_nonce'; 
  8.  
  9. /** 
  10. * @var string 
  11. */ 
  12. private $export = ''; 
  13.  
  14. /** 
  15. * @var string 
  16. */ 
  17. private $error = ''; 
  18.  
  19. /** 
  20. * @var string 
  21. */ 
  22. public $export_zip_url = ''; 
  23.  
  24. /** 
  25. * @var boolean 
  26. */ 
  27. public $success; 
  28.  
  29. /** 
  30. * Whether or not the export will include taxonomy metadata 
  31. * @var boolean 
  32. */ 
  33. private $include_taxonomy; 
  34.  
  35. /** 
  36. * @var array 
  37. */ 
  38. private $dir = array(); 
  39.  
  40.  
  41. /** 
  42. * Class constructor 
  43. * @param boolean $include_taxonomy Whether to include the taxonomy metadata the plugin creates. 
  44. */ 
  45. public function __construct( $include_taxonomy = false ) { 
  46. $this->include_taxonomy = $include_taxonomy; 
  47. $this->dir = wp_upload_dir(); 
  48.  
  49. $this->export_settings(); 
  50.  
  51. /** 
  52. * Returns true when the property error has a value. 
  53. * @return bool 
  54. */ 
  55. public function has_error() { 
  56. return ( $this->error !== '' ); 
  57.  
  58. /** 
  59. * Sets the error hook, to display the error to the user. 
  60. */ 
  61. public function set_error_hook() { 
  62. $class = 'notice notice-error'; 
  63. $message = sprintf( __( 'Error creating %1$s export: ', 'wordpress-seo' ), 'Yoast SEO' ) . $this->error; 
  64.  
  65. printf( '<div class="%1$s"><p>%2$s</p></div>', $class, $message ); 
  66.  
  67. /** 
  68. * Exports the current site's WP SEO settings. 
  69. */ 
  70. private function export_settings() { 
  71.  
  72. $this->export_header(); 
  73.  
  74. foreach ( WPSEO_Options::get_option_names() as $opt_group ) { 
  75. $this->write_opt_group( $opt_group ); 
  76.  
  77. $this->taxonomy_metadata(); 
  78.  
  79. if ( ! $this->write_settings_file() ) { 
  80. $this->error = __( 'Could not write settings to file.', 'wordpress-seo' ); 
  81.  
  82. return; 
  83.  
  84. if ( $this->zip_file() ) { 
  85. // Just exit, because there is a download being served. 
  86. exit; 
  87.  
  88. /** 
  89. * Writes the header of the export file. 
  90. */ 
  91. private function export_header() { 
  92. /** translators: %1$s expands to Yoast SEO */ 
  93. $this->write_line( '; ' . sprintf( __( 'This is a settings export file for the %1$s plugin by Yoast.com', 'wordpress-seo' ), 'Yoast SEO' ) . ' - https://yoast.com/wordpress/plugins/seo/' ); 
  94. if ( $this->include_taxonomy ) { 
  95. $this->write_line( '; ' . __( 'This export includes taxonomy metadata', 'wordpress-seo' ) ); 
  96.  
  97. /** 
  98. * Writes a line to the export 
  99. * @param string $line Line string. 
  100. * @param boolean $newline_first Boolean flag whether to prepend with new line. 
  101. */ 
  102. private function write_line( $line, $newline_first = false ) { 
  103. if ( $newline_first ) { 
  104. $this->export .= PHP_EOL; 
  105. $this->export .= $line . PHP_EOL; 
  106.  
  107. /** 
  108. * Writes an entire option group to the export 
  109. * @param string $opt_group Option group name. 
  110. */ 
  111. private function write_opt_group( $opt_group ) { 
  112.  
  113. $this->write_line( '[' . $opt_group . ']', true ); 
  114.  
  115. $options = get_option( $opt_group ); 
  116.  
  117. if ( ! is_array( $options ) ) { 
  118. return; 
  119.  
  120. foreach ( $options as $key => $elem ) { 
  121. if ( is_array( $elem ) ) { 
  122. $count = count( $elem ); 
  123. for ( $i = 0; $i < $count; $i ++ ) { 
  124. $this->write_setting( $key . '[]', $elem[ $i ] ); 
  125. else { 
  126. $this->write_setting( $key, $elem ); 
  127.  
  128. /** 
  129. * Writes a settings line to the export 
  130. * @param string $key Key string. 
  131. * @param string $val Value string. 
  132. */ 
  133. private function write_setting( $key, $val ) { 
  134. if ( is_string( $val ) ) { 
  135. $val = '"' . $val . '"'; 
  136. $this->write_line( $key . ' = ' . $val ); 
  137.  
  138. /** 
  139. * Adds the taxonomy meta data if there is any 
  140. */ 
  141. private function taxonomy_metadata() { 
  142. if ( $this->include_taxonomy ) { 
  143. $taxonomy_meta = get_option( 'wpseo_taxonomy_meta' ); 
  144. if ( is_array( $taxonomy_meta ) ) { 
  145. $this->write_line( '[wpseo_taxonomy_meta]', true ); 
  146. $this->write_setting( 'wpseo_taxonomy_meta', urlencode( wp_json_encode( $taxonomy_meta ) ) ); 
  147. else { 
  148. $this->write_line( '; ' . __( 'No taxonomy metadata found', 'wordpress-seo' ), true ); 
  149.  
  150. /** 
  151. * Writes the settings to our temporary settings.ini file 
  152. * @return boolean unsigned 
  153. */ 
  154. private function write_settings_file() { 
  155. $handle = fopen( $this->dir['path'] . '/' . self::INI_FILENAME, 'w' ); 
  156. if ( ! $handle ) { 
  157. return false; 
  158.  
  159. $res = fwrite( $handle, $this->export ); 
  160. if ( ! $res ) { 
  161. return false; 
  162.  
  163. fclose( $handle ); 
  164.  
  165. return true; 
  166.  
  167. /** 
  168. * Zips the settings ini file 
  169. * @return bool|null 
  170. */ 
  171. private function zip_file() { 
  172. $is_zip_created = $this->create_zip(); 
  173.  
  174. // The settings.ini isn't needed, because it's in the zipfile. 
  175. $this->remove_settings_ini(); 
  176.  
  177. if ( ! $is_zip_created ) { 
  178. $this->error = __( 'Could not zip settings-file.', 'wordpress-seo' ); 
  179.  
  180. return false; 
  181.  
  182. $this->serve_settings_export(); 
  183. $this->remove_zip(); 
  184.  
  185. return true; 
  186.  
  187. /** 
  188. * Creates the zipfile and returns true if it created successful. 
  189. * @return bool 
  190. */ 
  191. private function create_zip() { 
  192. chdir( $this->dir['path'] ); 
  193. $zip = new PclZip( './' . self::ZIP_FILENAME ); 
  194. if ( 0 === $zip->create( './' . self::INI_FILENAME ) ) { 
  195. return false; 
  196.  
  197. return file_exists( self::ZIP_FILENAME ); 
  198.  
  199. /** 
  200. * Downloads the zip file. 
  201. */ 
  202. private function serve_settings_export() { 
  203. // Clean any content that has been already output. For example by other plugins or faulty PHP files. 
  204. if ( ob_get_contents() ) { 
  205. ob_clean(); 
  206. header( 'Content-Type: application/octet-stream; charset=utf-8' ); 
  207. header( 'Content-Transfer-Encoding: Binary' ); 
  208. header( 'Content-Disposition: attachment; filename=' . self::ZIP_FILENAME ); 
  209. header( 'Content-Length: ' . filesize( self::ZIP_FILENAME ) ); 
  210.  
  211. readfile( self::ZIP_FILENAME ); 
  212.  
  213. /** 
  214. * Removes the settings ini file. 
  215. */ 
  216. private function remove_settings_ini() { 
  217. unlink( './' . self::INI_FILENAME ); 
  218.  
  219. /** 
  220. * Removes the files because they are already downloaded. 
  221. */ 
  222. private function remove_zip() { 
  223. unlink( './' . self::ZIP_FILENAME );