287 lines
6.2 KiB
PHP
287 lines
6.2 KiB
PHP
<?php
|
|
/**
|
|
* WPSEO plugin file.
|
|
*
|
|
* @package WPSEO\Admin\Export
|
|
*/
|
|
|
|
/**
|
|
* Class WPSEO_Export
|
|
*
|
|
* Class with functionality to export the WP SEO settings
|
|
*/
|
|
class WPSEO_Export {
|
|
|
|
const ZIP_FILENAME = 'yoast-seo-settings-export.zip';
|
|
const INI_FILENAME = 'settings.ini';
|
|
|
|
const NONCE_ACTION = 'wpseo_export';
|
|
const NONCE_NAME = 'wpseo_export_nonce';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $export = '';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $error = '';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
public $export_zip_url = '';
|
|
|
|
/**
|
|
* @var boolean
|
|
*/
|
|
public $success;
|
|
|
|
/**
|
|
* Whether or not the export will include taxonomy metadata
|
|
*
|
|
* @var boolean
|
|
*/
|
|
private $include_taxonomy;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $dir = array();
|
|
|
|
|
|
/**
|
|
* Class constructor
|
|
*
|
|
* @param boolean $include_taxonomy Whether to include the taxonomy metadata the plugin creates.
|
|
*/
|
|
public function __construct( $include_taxonomy = false ) {
|
|
$this->include_taxonomy = $include_taxonomy;
|
|
$this->dir = wp_upload_dir();
|
|
|
|
$this->export_settings();
|
|
}
|
|
|
|
/**
|
|
* Returns true when the property error has a value.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function has_error() {
|
|
return ( $this->error !== '' );
|
|
}
|
|
|
|
/**
|
|
* Sets the error hook, to display the error to the user.
|
|
*/
|
|
public function set_error_hook() {
|
|
/* translators: %1$s expands to Yoast SEO */
|
|
$message = sprintf( __( 'Error creating %1$s export: ', 'wordpress-seo' ), 'Yoast SEO' ) . $this->error;
|
|
|
|
printf(
|
|
'<div class="notice notice-error"><p>%1$s</p></div>',
|
|
$message
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Exports the current site's WP SEO settings.
|
|
*/
|
|
private function export_settings() {
|
|
|
|
$this->export_header();
|
|
|
|
foreach ( WPSEO_Options::get_option_names() as $opt_group ) {
|
|
$this->write_opt_group( $opt_group );
|
|
}
|
|
|
|
$this->taxonomy_metadata();
|
|
|
|
if ( ! $this->write_settings_file() ) {
|
|
$this->error = __( 'Could not write settings to file.', 'wordpress-seo' );
|
|
|
|
return;
|
|
}
|
|
|
|
if ( $this->zip_file() ) {
|
|
// Just exit, because there is a download being served.
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes the header of the export file.
|
|
*/
|
|
private function export_header() {
|
|
$header = sprintf(
|
|
/* translators: %1$s expands to Yoast SEO, %2$s expands to Yoast.com */
|
|
esc_html__( 'This is a settings export file for the %1$s plugin by %2$s', 'wordpress-seo' ),
|
|
'Yoast SEO',
|
|
'Yoast.com'
|
|
);
|
|
$this->write_line( '; ' . $header . ' - ' . esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/1yd' ) ) );
|
|
if ( $this->include_taxonomy ) {
|
|
$this->write_line( '; ' . __( 'This export includes taxonomy metadata', 'wordpress-seo' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes a line to the export
|
|
*
|
|
* @param string $line Line string.
|
|
* @param boolean $newline_first Boolean flag whether to prepend with new line.
|
|
*/
|
|
private function write_line( $line, $newline_first = false ) {
|
|
if ( $newline_first ) {
|
|
$this->export .= PHP_EOL;
|
|
}
|
|
$this->export .= $line . PHP_EOL;
|
|
}
|
|
|
|
/**
|
|
* Writes an entire option group to the export
|
|
*
|
|
* @param string $opt_group Option group name.
|
|
*/
|
|
private function write_opt_group( $opt_group ) {
|
|
|
|
$this->write_line( '[' . $opt_group . ']', true );
|
|
|
|
$options = get_option( $opt_group );
|
|
|
|
if ( ! is_array( $options ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $options as $key => $elem ) {
|
|
if ( is_array( $elem ) ) {
|
|
$count = count( $elem );
|
|
for ( $i = 0; $i < $count; $i ++ ) {
|
|
$this->write_setting( $key . '[]', $elem[ $i ] );
|
|
}
|
|
}
|
|
else {
|
|
$this->write_setting( $key, $elem );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes a settings line to the export
|
|
*
|
|
* @param string $key Key string.
|
|
* @param string $val Value string.
|
|
*/
|
|
private function write_setting( $key, $val ) {
|
|
if ( is_string( $val ) ) {
|
|
$val = '"' . $val . '"';
|
|
}
|
|
$this->write_line( $key . ' = ' . $val );
|
|
}
|
|
|
|
/**
|
|
* Adds the taxonomy meta data if there is any
|
|
*/
|
|
private function taxonomy_metadata() {
|
|
if ( $this->include_taxonomy ) {
|
|
$taxonomy_meta = get_option( 'wpseo_taxonomy_meta' );
|
|
if ( is_array( $taxonomy_meta ) ) {
|
|
$this->write_line( '[wpseo_taxonomy_meta]', true );
|
|
$this->write_setting( 'wpseo_taxonomy_meta', urlencode( wp_json_encode( $taxonomy_meta ) ) );
|
|
}
|
|
else {
|
|
$this->write_line( '; ' . __( 'No taxonomy metadata found', 'wordpress-seo' ), true );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes the settings to our temporary settings.ini file
|
|
*
|
|
* @return boolean unsigned
|
|
*/
|
|
private function write_settings_file() {
|
|
$handle = fopen( $this->dir['path'] . '/' . self::INI_FILENAME, 'w' );
|
|
if ( ! $handle ) {
|
|
return false;
|
|
}
|
|
|
|
$res = fwrite( $handle, $this->export );
|
|
if ( ! $res ) {
|
|
return false;
|
|
}
|
|
|
|
fclose( $handle );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Zips the settings ini file
|
|
*
|
|
* @return bool|null
|
|
*/
|
|
private function zip_file() {
|
|
$is_zip_created = $this->create_zip();
|
|
|
|
// The settings.ini isn't needed, because it's in the zipfile.
|
|
$this->remove_settings_ini();
|
|
|
|
if ( ! $is_zip_created ) {
|
|
$this->error = __( 'Could not zip settings-file.', 'wordpress-seo' );
|
|
|
|
return false;
|
|
}
|
|
|
|
$this->serve_settings_export();
|
|
$this->remove_zip();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Creates the zipfile and returns true if it created successful.
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function create_zip() {
|
|
chdir( $this->dir['path'] );
|
|
$zip = new PclZip( './' . self::ZIP_FILENAME );
|
|
if ( 0 === $zip->create( './' . self::INI_FILENAME ) ) {
|
|
return false;
|
|
}
|
|
|
|
return file_exists( self::ZIP_FILENAME );
|
|
}
|
|
|
|
/**
|
|
* Downloads the zip file.
|
|
*/
|
|
private function serve_settings_export() {
|
|
// Clean any content that has been already output. For example by other plugins or faulty PHP files.
|
|
if ( ob_get_contents() ) {
|
|
ob_clean();
|
|
}
|
|
header( 'Content-Type: application/octet-stream; charset=utf-8' );
|
|
header( 'Content-Transfer-Encoding: Binary' );
|
|
header( 'Content-Disposition: attachment; filename=' . self::ZIP_FILENAME );
|
|
header( 'Content-Length: ' . filesize( self::ZIP_FILENAME ) );
|
|
|
|
readfile( self::ZIP_FILENAME );
|
|
}
|
|
|
|
/**
|
|
* Removes the settings ini file.
|
|
*/
|
|
private function remove_settings_ini() {
|
|
unlink( './' . self::INI_FILENAME );
|
|
}
|
|
|
|
/**
|
|
* Removes the files because they are already downloaded.
|
|
*/
|
|
private function remove_zip() {
|
|
unlink( './' . self::ZIP_FILENAME );
|
|
}
|
|
}
|