File "class-import-row.php"
Full Path: /home/diablzlo/glucosebalnce.com/wp-content/plugins/seo-by-rank-math-pro/includes/admin/csv-import-export/class-import-row.php
File size: 19.06 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* The CSV Import class.
*
* @since 1.0
* @package RankMathPro
* @subpackage RankMathPro\Admin
* @author Rank Math <support@rankmath.com>
*/
namespace RankMathPro\Admin\CSV_Import_Export;
use RankMath\Helper;
use RankMath\Helpers\Arr;
use RankMath\Redirections\DB;
use RankMath\Redirections\Cache;
use RankMath\Redirections\Redirection;
defined( 'ABSPATH' ) || exit;
/**
* CSV Importer class.
*
* @codeCoverageIgnore
*/
class Import_Row {
/**
* Row data.
*
* @var array
*/
private $data = [];
/**
* Import settings.
*
* @var array
*/
private $settings = [];
/**
* Columns.
*
* @var array
*/
private $columns = [];
/**
* Redirection.
*
* @var array
*/
private $redirection = [];
/**
* Object URI.
*
* @var string
*/
private $object_uri = '';
/**
* Facebook and Twitter thumbnail.
*
* @var array
*/
private $thumbnail = [];
/**
* The meta data to be updated or deleted.
*
* @var array|false
*/
public $meta_data = [];
/**
* Constructor.
*
* @param array $data Row data.
* @param array $settings Import settings.
* @param bool $should_query_db Whether to query the database. If false, the prepared meta data will only be stored in $this->meta_data.
*
* @return void
*/
public function __construct( $data, $settings, $should_query_db = true ) {
$this->data = $data;
$this->settings = $settings;
if ( $should_query_db ) {
$this->meta_data = false;
}
foreach ( $this->data as $key => $value ) {
$clear_method = "clear_{$key}";
$clear_method_exists = method_exists( $this, $clear_method );
// Skip empty or n/a.
if ( empty( $value ) || $this->is_not_applicable( $value ) ) {
if ( 'redirect_to' !== $key && empty( $value ) && $clear_method_exists ) {
$this->$clear_method(); // Clear meta if value read from CSV is empty. See issue #1851.
}
continue;
}
if ( $this->is_clear_command( $value ) && $clear_method_exists ) {
$this->$clear_method();
continue;
}
if ( 'false' !== $this->settings['no_overwrite'] ) {
$is_empty_method = "is_empty_{$key}";
if ( ! method_exists( $this, $is_empty_method ) || ! $this->$is_empty_method() ) {
continue;
}
}
$import_method = "import_{$key}";
if ( method_exists( $this, $import_method ) ) {
$this->$import_method( $value );
}
}
/**
* Do custom action after importing a row.
*/
do_action( 'rank_math/admin/csv_import_row', $data, $settings, $this );
}
/**
* Check if given column value is empty or not applicable.
*
* @param mixed $value Column value.
* @return bool
*/
public function is_not_applicable( $value ) {
return $value === $this->settings['not_applicable_value'];
}
/**
* Check if given column value is the delete command.
*
* @param mixed $value Column value.
* @return bool
*/
public function is_clear_command( $value ) {
return $value === $this->settings['clear_command'];
}
/**
* Magic getter.
*
* Return column value if is set and column name is in allowed columns list.
*
* @param string $property Property we want to get.
* @return string
*/
public function __get( $property ) {
if ( in_array( $property, $this->get_columns(), true ) && isset( $this->data[ $property ] ) ) {
return $this->data[ $property ];
}
return '';
}
/**
* Get CSV columns.
*
* @return array
*/
public function get_columns() {
if ( ! empty( $this->columns ) ) {
return $this->columns;
}
$this->columns = CSV_Import_Export::get_columns();
return $this->columns;
}
/**
* Clear SEO Title column.
*
* @return void
*/
public function clear_seo_title() {
$this->delete_meta( 'title' );
}
/**
* Clear SEO Description column.
*
* @return void
*/
public function clear_seo_description() {
$this->delete_meta( 'description' );
}
/**
* Clear Focus Keyword column.
*
* @return void
*/
public function clear_focus_keyword() {
$this->delete_meta( 'focus_keyword' );
}
/**
* Clear Robots column.
*
* @return void
*/
public function clear_robots() {
$this->delete_meta( 'robots' );
}
/**
* Clear Advanced Robots column.
*
* @return void
*/
public function clear_advanced_robots() {
$this->delete_meta( 'advanced_robots' );
}
/**
* Clear Canonical URL column.
*
* @return void
*/
public function clear_canonical_url() {
$this->delete_meta( 'canonical_url' );
}
/**
* Clear Primary Term column.
*
* @return void
*/
public function clear_primary_term() {
$this->delete_meta( 'primary_category' );
}
/**
* Clear Schema Data column. Schema data must be valid JSON.
*
* @return void
*/
public function clear_schema_data() {
$current_meta = $this->get_meta();
foreach ( $current_meta as $key => $value ) {
if ( substr( $key, 0, 17 ) === 'rank_math_schema_' ) {
// Cut off "rank_math_" prefix.
$this->delete_meta( substr( $key, 10 ) );
}
}
}
/**
* Clear FB Thumbnail column.
*
* @return void
*/
public function clear_social_facebook_thumbnail() {
$this->delete_meta( 'facebook_image' );
$this->delete_meta( 'facebook_image_id' );
}
/**
* Clear FB Title column.
*
* @return void
*/
public function clear_social_facebook_title() {
$this->delete_meta( 'facebook_title' );
}
/**
* Clear FB Description column.
*
* @return void
*/
public function clear_social_facebook_description() {
$this->delete_meta( 'facebook_description' );
}
/**
* Clear Twitter Thumbnail column.
*
* @return void
*/
public function clear_social_twitter_thumbnail() {
$this->delete_meta( 'twitter_image' );
$this->delete_meta( 'twitter_image_id' );
}
/**
* Clear Twitter Title column.
*
* @return void
*/
public function clear_social_twitter_title() {
$this->delete_meta( 'twitter_title' );
}
/**
* Clear Twitter Description column.
*
* @return void
*/
public function clear_social_twitter_description() {
$this->delete_meta( 'twitter_description' );
}
/**
* Clear Redirection URL column. Only if 'redirect_type' column is set, too.
*
* @return void
*/
public function clear_redirect_to() {
if ( ! $this->is_empty_redirect_to() ) {
DB::delete( $this->get_redirection()['id'] );
}
}
/**
* Import slug column.
*
* @param string $value Column value.
* @return void
*/
public function import_slug( $value ) {
switch ( $this->object_type ) {
case 'post':
wp_update_post(
[
'ID' => $this->id,
'post_name' => $value,
]
);
break;
case 'term':
global $wpdb;
$wpdb->update(
$wpdb->terms,
[ 'slug' => sanitize_title( $value ) ], // Update.
[ 'term_id' => sanitize_title( $value ) ], // Where.
[ '%s' ], // Format.
[ '%d' ] // Where format.
);
break;
case 'user':
update_user_meta( $this->id, 'rank_math_permalink', $value );
break;
}
// Refresh URI.
$this->get_object_uri( true );
}
/**
* Import SEO Title column.
*
* @param string $value Column value.
* @return void
*/
public function import_seo_title( $value ) {
$this->update_meta( 'title', $value );
}
/**
* Import SEO Description column.
*
* @param string $value Column value.
* @return void
*/
public function import_seo_description( $value ) {
$this->update_meta( 'description', $value );
}
/**
* Import Is Pillar Content column.
*
* @param string $value Column value.
* @return void
*/
public function import_is_pillar_content( $value ) {
$lcvalue = strtolower( $value );
if ( 'yes' === $lcvalue ) {
$this->update_meta( 'pillar_content', 'on' );
} elseif ( 'no' === $lcvalue ) {
$this->delete_meta( 'pillar_content' );
}
}
/**
* Import Focus Keyword column.
*
* @param string $value Column value.
* @return void
*/
public function import_focus_keyword( $value ) {
$this->update_meta( 'focus_keyword', $value );
}
/**
* Import Robots column.
*
* @param string $value Column value.
* @return void
*/
public function import_robots( $value ) {
$this->update_meta( 'robots', Arr::from_string( $value ) );
}
/**
* Import Advanced Robots column.
*
* @param string $value Column value.
* @return void
*/
public function import_advanced_robots( $value ) {
$robots = [];
$robots_rules = Arr::from_string( $value );
foreach ( $robots_rules as $robots_rule ) {
$parts = Arr::from_string( $robots_rule, '=' );
if ( count( $parts ) === 2 ) {
$robots[ $parts[0] ] = $parts[1];
}
}
$this->update_meta( 'advanced_robots', $robots );
}
/**
* Import Canonical URL column.
*
* @param string $value Column value.
* @return void
*/
public function import_canonical_url( $value ) {
$this->update_meta( 'canonical_url', $value );
}
/**
* Import Primary Term column.
*
* @param string $value Column value.
* @return void
*/
public function import_primary_term( $value ) {
$term_id = Importer::get_term_id( $value );
if ( ! $term_id ) {
return;
}
$this->update_meta( 'primary_category', $term_id );
}
/**
* Import Schema Data column. Schema data must be valid JSON.
*
* @param string $value Column value.
* @return void
*/
public function import_schema_data( $value ) {
$value = preg_replace( '/u([\da-fA-F]{4})/', '\\u$1', $value );
$value = json_decode( $value, true );
if ( ! $value ) {
return;
}
foreach ( $value as $key => $value ) {
$meta_key = 'schema_' . $key;
$this->update_meta( $meta_key, $value );
}
}
/**
* Import FB Thumbnail column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_facebook_thumbnail( $value ) {
$details = $this->thumbnail_attachment_details( $value );
if ( empty( $details ) ) {
return;
}
$this->update_meta( 'facebook_image', $details['url'] );
$this->update_meta( 'facebook_image_id', $details['id'] );
}
/**
* Import FB Title column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_facebook_title( $value ) {
$this->update_meta( 'facebook_title', $value );
}
/**
* Import FB Description column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_facebook_description( $value ) {
$this->update_meta( 'facebook_description', $value );
}
/**
* Import Twitter Thumbnail column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_twitter_thumbnail( $value ) {
$details = $this->thumbnail_attachment_details( $value );
if ( empty( $details ) ) {
return;
}
$this->update_meta( 'twitter_image', $details['url'] );
$this->update_meta( 'twitter_image_id', $details['id'] );
$this->update_meta( 'twitter_use_facebook', 'off' );
}
/**
* Import Twitter Title column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_twitter_title( $value ) {
$this->update_meta( 'twitter_title', $value );
$this->update_meta( 'twitter_use_facebook', 'off' );
}
/**
* Import Twitter Description column.
*
* @param string $value Column value.
* @return void
*/
public function import_social_twitter_description( $value ) {
$this->update_meta( 'twitter_description', $value );
$this->update_meta( 'twitter_use_facebook', 'off' );
}
/**
* Import Redirection URL column. Only if 'redirect_type' column is set, too.
*
* @return void
*/
public function import_redirect_to() {
if ( empty( $this->data['redirect_type'] ) ) {
return;
}
if ( ! $this->is_empty_redirect_to() ) {
DB::delete( $this->get_redirection()['id'] );
}
$redirection = Redirection::from(
[
'id' => '',
'url_to' => $this->redirect_to,
'sources' => [
[
'pattern' => $this->get_object_uri(),
'comparison' => 'exact',
],
],
'header_code' => $this->redirect_type,
]
);
$redirection->save();
}
/**
* Check if empty: SEO Title
*
* @return bool
*/
public function is_empty_seo_title() {
return ! $this->get_meta( 'title' );
}
/**
* Check if empty: SEO Description
*
* @return bool
*/
public function is_empty_seo_description() {
return ! $this->get_meta( 'description' );
}
/**
* Check if empty: Is Pillar Content column.
* We return true so this will always be overwritten.
*
* @return bool
*/
public function is_empty_is_pillar_content() {
return true;
}
/**
* Check if empty: Focus Keyword column.
*
* @return bool
*/
public function is_empty_focus_keyword() {
return ! $this->get_meta( 'focus_keyword' );
}
/**
* Check if empty: Robots column.
*
* @return bool
*/
public function is_empty_robots() {
return empty( $this->get_meta( 'robots' ) );
}
/**
* Check if empty: Advanced Robots column.
*
* @return bool
*/
public function is_empty_advanced_robots() {
return empty( $this->get_meta( 'advanced_robots' ) );
}
/**
* Check if empty: Canonical URL column.
*
* @return bool
*/
public function is_empty_canonical_url() {
return ! $this->get_meta( 'canonical_url' );
}
/**
* Check if empty: Primary Term column.
*
* @return bool
*/
public function is_empty_primary_term() {
return empty( $this->get_meta( 'primary_category' ) );
}
/**
* Check if empty: Schema Data column.
* We return true so this will always be overwritten.
*
* @return bool
*/
public function is_empty_schema_data() {
return true;
}
/**
* Check if empty: FB Thumbnail column.
*
* @return bool
*/
public function is_empty_social_facebook_thumbnail() {
return ! $this->get_meta( 'facebook_image' );
}
/**
* Check if empty: FB Title column.
*
* @return bool
*/
public function is_empty_social_facebook_title() {
return ! $this->get_meta( 'facebook_title' );
}
/**
* Check if empty: FB Description column.
*
* @return bool
*/
public function is_empty_social_facebook_description() {
return ! $this->get_meta( 'facebook_description' );
}
/**
* Check if empty: Twitter Thumbnail column.
*
* @return bool
*/
public function is_empty_social_twitter_thumbnail() {
return ! $this->get_meta( 'twitter_image' );
}
/**
* Check if empty: Twitter Title column.
*
* @return bool
*/
public function is_empty_social_twitter_title() {
return ! $this->get_meta( 'twitter_title' );
}
/**
* Check if empty: Twitter Description column.
*
* @return bool
*/
public function is_empty_social_twitter_description() {
return ! $this->get_meta( 'twitter_description' );
}
/**
* Check if empty: Redirect URL.
*
* @return bool
*/
public function is_empty_redirect_to() {
return ! (bool) $this->get_redirection()['id'];
}
/**
* Get redirection for object.
*
* @return mixed
*/
public function get_redirection() {
if ( isset( $this->redirection ) ) {
return $this->redirection;
}
$object_type = $this->object_type;
$object_id = $this->id;
$this->get_object_uri();
$redirection = Cache::get_by_object_id( $object_id, $object_type );
$redirection = $redirection ? DB::get_redirection_by_id( $redirection->redirection_id, 'active' ) : [
'id' => '',
'url_to' => '',
'header_code' => Helper::get_settings( 'general.redirections_header_code' ),
];
$this->redirection = $redirection;
return $redirection;
}
/**
* Get object URI.
*
* @param bool $refresh Force refresh.
*
* @return string
*/
public function get_object_uri( $refresh = false ) {
if ( isset( $this->object_uri ) && ! $refresh ) {
return $this->object_uri;
}
$url = 'term' === $this->object_type ? get_term_link( (int) $this->id ) : get_permalink( $this->id );
if ( empty( $url ) || is_wp_error( $url ) ) {
return false;
}
$url = wp_parse_url( $url, PHP_URL_PATH );
$this->object_uri = trim( $url, '/' );
return $this->object_uri;
}
/**
* Update object meta.
*
* @param string $key Meta key.
* @param mixed $value Meta value.
* @return void
*/
public function update_meta( $key, $value ) {
if ( false === $this->meta_data ) {
$update_meta = "update_{$this->object_type}_meta";
$update_meta( $this->id, 'rank_math_' . $key, $value );
return;
}
$this->meta_data['update'][] = [
$this->object_type . '_id' => $this->id,
'meta_key' => 'rank_math_' . $key,
'meta_value' => maybe_serialize( $value ),
];
}
/**
* Get object meta.
*
* @param string $key Meta key.
* @return bool
*/
public function get_meta( $key = '' ) {
$get_meta = "get_{$this->object_type}_meta";
return $get_meta( $this->id, $key ? 'rank_math_' . $key : '', (bool) $key );
}
/**
* Delete object meta.
*
* @param string $key Meta key.
* @return void
*/
public function delete_meta( $key ) {
if ( false === $this->meta_data ) {
$delete_meta = "delete_{$this->object_type}_meta";
$delete_meta( $this->id, 'rank_math_' . $key );
return;
}
$this->meta_data['delete'][] = [
$this->object_type . '_id' => $this->id,
'meta_key' => 'rank_math_' . $key,
];
}
/**
* Gets the file details while downloading and saving the image file if it doesn't exist on current server.
*
* @param string $url The URL string to the file.
*
* @returns array The attachment id and URL.
*/
private function thumbnail_attachment_details( $url ) {
if ( isset( $this->thumbnail[ $url ] ) ) {
return $this->thumbnail[ $url ];
}
$dir = wp_get_upload_dir();
if ( Helper::starts_with( $dir['baseurl'], $url ) ) {
$this->thumbnail[ $url ] = [
'id' => attachment_url_to_postid( $url ),
'url' => $url,
];
return $this->thumbnail[ $url ];
}
// Attempt and download the remote file!
$tmp_file_name = download_url( $url );
if ( is_wp_error( $tmp_file_name ) ) {
return [];
}
$path = wp_parse_url( $url, PHP_URL_PATH );
$file_name = basename( $path );
$uploads = wp_upload_dir();
$unique_name = wp_unique_filename( $uploads['path'], $file_name );
// Move the downloaded file to the uploads dir.
$uploads_file_path = $uploads['path'] . '/' . $unique_name;
// Use copy and unlink because rename breaks streams.
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
@copy( $tmp_file_name, $uploads_file_path );
wp_delete_file( $tmp_file_name );
$wp_filetype = wp_check_filetype( $file_name, null );
$attachment = [
'guid' => $uploads['url'] . '/' . $unique_name,
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name( $unique_name ),
'post_content' => '',
'post_status' => 'inherit',
];
$attachment_id = wp_insert_attachment( $attachment );
// Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
require_once ABSPATH . 'wp-admin/includes/image.php'; // @phpstan-ignore-line
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata( $attachment_id, $uploads_file_path );
update_post_meta( $attachment_id, '_wp_attached_file', $attach_data['file'] );
wp_update_attachment_metadata( $attachment_id, $attach_data );
$this->thumbnail[ $url ] = [
'id' => $attachment_id,
'url' => $attachment['guid'],
];
return $this->thumbnail[ $url ];
}
}