Current File : /home/pacjaorg/www/copwordpres/wp-content/plugins/download-monitor/src/FileManager.php
<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
} // Exit if accessed directly

if ( ! class_exists( 'DLM_File_Manager' ) ) {
	/**
	 * DLM_File_Manager class.
	 *
	 * Class used to handle file operations and data.
	 */
	class DLM_File_Manager {

		/**
		 * Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep.
		 * The depth of the recursiveness can be controlled by the $levels param.
		 *
		 * @access public
		 *
		 * @param  string  $folder  (default: '')
		 *
		 * @return array|bool
		 */
		public function list_files( $folder = '' ) {
			if ( empty( $folder ) ) {
				return false;
			}

			// A listing of all files and dirs in $folder, excepting . and ..
			// By default, the sorted order is alphabetical in ascending order
			$files = array_diff( scandir( $folder ), array( '..', '.' ) );

			$dlm_files = array();

			foreach ( $files as $file ) {
				$dlm_files[] = array(
					'type' => ( is_dir( $folder . '/' . $file ) ? 'folder'
						: 'file' ),
					'path' => $folder . '/' . $file,
				);
			}

			return $dlm_files;
		}

		/**
		 * Parse a file path and return the new path and whether it's remote
		 *
		 * @param  string  $file_path
		 *
		 * @return array
		 */
		public function parse_file_path( $file_path ) {
			$remote_file      = true;
			$parsed_file_path = parse_url( $file_path );
			$wp_uploads       = wp_upload_dir();
			$wp_uploads_dir   = $wp_uploads['basedir'];
			$wp_uploads_url   = $wp_uploads['baseurl'];
			$allowed_paths    = $this->get_allowed_paths();
			$common_path
			                  = DLM_Utils::longest_common_path( $allowed_paths );

			if ( false !== strpos( $file_path, '127.0.0.1' ) ) {
				$file_path        = untrailingslashit( $common_path )
				                    . $parsed_file_path['path'];
				$parsed_file_path = parse_url( $file_path );
			}

			// Fix for plugins that modify the uploads dir
			// add filter in order to return files
			if ( apply_filters( 'dlm_check_file_paths',
				false,
				$file_path,
				$remote_file )
			) {
				return array( $file_path, $remote_file );
			}

			// Check if relative path or absolute path, as the file_exists function needs an absolute path
			// So that we do not trigger warnings/errors with open_basedir restrictions.
			$file_check['exists']   = false;
			$file_check['relative'] = false;

			if ( isset( $parsed_file_path['path'] ) ) {
				// Check if common path is contained within the file path, if it doesn't it is a relative path,
				// or it is a non-allowed file.
				if ( $common_path && strlen( $common_path ) > 1
				     && false === strpos( $parsed_file_path['path'],
						$common_path )
				) {
					if ( is_file( realpath( trailingslashit( $common_path )
					                        . $parsed_file_path['path'] ) )
					) { // Check if it's a relative path, so add the common path to it.
						$file_check['exists']   = true;
						$file_check['relative'] = true;
					} elseif ( file_exists( $parsed_file_path['path'] ) ) { // Check if it's an absolute path, most probably a non-allowed file.
						$file_check['exists'] = true;
					}
				} else {
					// If common path is included in the file path, check if the file exists.
					if ( file_exists( $parsed_file_path['path'] ) ) {
						$file_check['exists'] = true;
					}
				}
			}

			// Check file path
			if ( ( ! isset( $parsed_file_path['scheme'] )
			       || ! in_array( $parsed_file_path['scheme'], array(
						'http',
						'https',
						'ftp',
					) ) )
			     && $file_check['exists']
			) {
				/** The file lies in the server */
				$remote_file = false;
				// If it's relative we need to make it absolute.
				if ( $file_check['relative'] ) {
					$file_path = trailingslashit( $common_path )
					             . $parsed_file_path['path'];
					$file_path = realpath( $file_path );
				}
			} elseif ( strpos( $wp_uploads_dir, '://' ) !== false ) {
				/**
				 * This is a file located on a network drive.
				 * WordPress VIP is a providor that uses network drive paths
				 * Only allow if root (vip://) is predefined in Settings > Misc > Other downloads path
				 * Example of path: vip://wp-content/upload...
				 **/
				$remote_file = false;
				$path        = array_reduce( $allowed_paths,
					function ( $carry, $path ) use (
						$wp_uploads_dir,
						$wp_uploads_url,
						$file_path
					) {
						return strpos( $path, '://' ) !== false
						       && strpos( $wp_uploads_dir, $path ) !== false
							? trim( str_replace( $wp_uploads_url,
								$wp_uploads_dir,
								$file_path ) )
							: $carry;
					},
					false );

				// realpath() will return false on network drive paths, so just check if exists
				$file_path = file_exists( $path ) ? $path
					: realpath( $file_path );
			} elseif ( strpos( $file_path, $wp_uploads_url ) !== false ) {
				/** This is a local file given by URL, so we need to figure out the path */
				$remote_file = false;
				$file_path   = trim( str_replace( $wp_uploads_url,
					$wp_uploads_dir,
					$file_path ) );
				$file_path   = realpath( $file_path );
			} elseif ( is_multisite()
			           && ( ( strpos( $file_path,
							network_site_url( '/', 'http' ) ) !== false )
			                || ( strpos( $file_path,
							network_site_url( '/', 'https' ) ) !== false ) )
			) {
				/** This is a local file outside wp-content so figure out the path */
				$remote_file = false;
				// Try to replace network url
				$file_path = str_replace( network_site_url( '/', 'https' ),
					ABSPATH,
					$file_path );
				$file_path = str_replace( network_site_url( '/', 'http' ),
					ABSPATH,
					$file_path );
				// Try to replace upload URL
				$file_path = str_replace( $wp_uploads_url,
					$wp_uploads_dir,
					$file_path );
				$file_path = realpath( $file_path );
			} elseif ( strpos( $file_path, site_url( '/', 'http' ) ) !== false
			           || strpos( $file_path, site_url( '/', 'https' ) )
			              !== false
			) {
				/** This is a local file outside wp-content so figure out the path */
				$remote_file = false;
				$file_path   = str_replace( site_url( '/', 'https' ),
					ABSPATH,
					$file_path );
				$file_path   = str_replace( site_url( '/', 'http' ),
					ABSPATH,
					$file_path );
				$file_path   = realpath( $file_path );
			} elseif ( file_exists( ABSPATH . $file_path ) ) {
				/** Path needs an abspath to work */
				$remote_file = false;
				$file_path   = ABSPATH . $file_path;
				$file_path   = realpath( $file_path );
			} elseif ( '' === $common_path || strlen( $common_path ) === 1 ) {
				foreach ( $allowed_paths as $path ) {
					if ( file_exists( $path . $file_path ) ) {
						$remote_file = false;
						$file_path   = $path . $file_path;
						$file_path   = realpath( $file_path );
						break;
					}
				}
			}

			return array(
				str_replace( DIRECTORY_SEPARATOR, '/', $file_path ),
				$remote_file,
			);
		}

		/**
		 * Gets the filesize of a path or URL.
		 *
		 * @access public
		 *
		 * @param  string  $file_path
		 *
		 * @return string size on success, -1 on failure
		 */
		public function get_file_size( $file_path ) {
			// Check if file exists
			if ( $file_path ) {
				list( $file_path, $remote_file )
					= $this->parse_file_path( $file_path );
				// Check if file from the new path exists
				if ( ! empty( $file_path ) ) {
					if ( $remote_file ) {
						$file = wp_remote_head( $file_path );

						if ( ! is_wp_error( $file )
						     && ! empty( $file['headers']['content-length'] )
						) {
							return $file['headers']['content-length'];
						}
					} else {
						if ( file_exists( $file_path )
						     && ( $filesize
								= filesize( $file_path ) )
						) {
							return $filesize;
						}
					}
				}
			}

			return - 1;
		}

		/**
		 * Encode files for storage
		 *
		 * @param  array  $files
		 *
		 * @return string
		 */
		public function json_encode_files( $files ) {
			if ( version_compare( phpversion(), "5.4.0", ">=" ) ) {
				$files = json_encode( $files, JSON_UNESCAPED_UNICODE );
			} else {
				$files = json_encode( $files );
				if ( function_exists( 'mb_convert_encoding' ) ) {
					$files = preg_replace_callback( '/\\\\u([0-9a-f]{4})/i',
						array(
							$this,
							'json_unscaped_unicode_fallback',
						),
						$files );
				}
			}

			return $files;
		}

		/**
		 * Fallback for PHP < 5.4 where JSON_UNESCAPED_UNICODE does not exist.
		 *
		 * @param  array  $matches
		 *
		 * @return string
		 */
		public function json_unscaped_unicode_fallback( $matches ) {
			$sym = mb_convert_encoding(
				pack( 'H*', $matches[1] ),
				'UTF-8',
				'UTF-16'
			);

			return $sym;
		}

		/**
		 * Multi-byte-safe pathinfo replacement.
		 *
		 * @param $filepath
		 *
		 * @return mixed
		 */
		public function mb_pathinfo( $filepath ) {
			$ret = array();
			preg_match( '%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im',
				$filepath,
				$m );
			if ( isset( $m[1] ) ) {
				$ret['dirname'] = $m[1];
			}
			if ( isset( $m[2] ) ) {
				$ret['basename'] = $m[2];
			}
			if ( isset( $m[5] ) ) {
				$ret['extension'] = $m[5];
			}
			if ( isset( $m[3] ) ) {
				$ret['filename'] = $m[3];
			}

			return $ret;
		}

		/**
		 * Get file name for given path
		 *
		 * @param  string  $file_path
		 *
		 * @return string
		 */
		public function get_file_name( $file_path ) {
			return apply_filters( 'dlm_filemanager_get_file_name',
				current( explode( '?', DLM_Utils::basename( $file_path ) ) ) );
		}

		/**
		 * Get file type of give file name
		 *
		 * @param  string  $file_name
		 *
		 * @return string
		 */
		public function get_file_type( $file_name ) {
			return strtolower( substr( strrchr( $file_name, "." ), 1 ) );
		}

		/**
		 * Gets md5, sha1 and crc32 hashes for a file and store it.
		 *
		 * @param  string  $file_path
		 *
		 * @return array of sizes
		 * @deprecated use hasher service get_file_hashes() instead
		 *
		 */
		public function get_file_hashes( $file_path ) {
			return download_monitor()->service( 'hasher' )
			                         ->get_file_hashes( $file_path );
		}

		/**
		 * Return the secured file path or url of the downloadable file. Should not let restricted files or out of root files to be downloaded.
		 *
		 * @param  string  $file  The file path/url
		 * @param  bool  $relative  Wheter or not to return a relative path. Default is false
		 *
		 * @return array The secured file path/url and restriction status
		 * @since 4.5.9
		 */
		public function get_secure_path( $file, $relative = false ) {
			// ABSPATH needs to be defined
			if ( ! defined( 'ABSPATH' ) ) {
				die;
			}
			// Get file path and remote file status
			list( $file_path, $remote_file ) = $this->parse_file_path( $file );

			// Let's see if the file path is dirty
			$file_scheme = parse_url( $file_path, PHP_URL_SCHEME );
			// Default restricted URL schemes
			$restricted_schemes = array( 'php' );
			$restricted_schemes = array_merge(
				$restricted_schemes,
				apply_filters(
					'dlm_restricted_schemes',
					array()
				)
			);
			// Check restricted schemes
			if ( in_array( $file_scheme, $restricted_schemes ) ) {
				$restriction = true;

				return array( $file_path, $remote_file, $restriction );
			}

			// If the file is remote, return the file path. If the file is not located on local server, return the file path.
			// This is available even if the file is one of the restricted files below. The plugin will let the user download the file,
			// but the file will be empty, with a 404 error or an error message.
			if ( $remote_file ) {
				$restriction = false;

				return array( $file_path, $remote_file, $restriction );
			}

			// The list of predefined restricted files.
			$restricted_files = array(
				'wp-config.php',
				'.htaccess',
				'php.ini',
			);

			// Specify the files that should be restricted from the download process.
			$restricted_files = array_merge(
				$restricted_files,
				apply_filters(
					'dlm_file_urls_security_files',
					array()
				)
			);

			// Loop through the restricted files and return empty string if found.
			foreach ( $restricted_files as $restricted_file ) {
				if ( basename( $file_path ) === $restricted_file ) {
					// If the file is restricted.
					$restriction = true;

					return array( $file_path, $remote_file, $restriction );
				}
			}
			// Get allowed paths
			$allowed_paths = $this->get_allowed_paths();
			// Create the correct path using the file path and the allowed paths
			$correct_path  = $this->get_correct_path( $file_path,
				$allowed_paths );

			// If the file is not in one of the allowed paths, return restriction
			if ( ! $correct_path || empty( $correct_path ) ) {
				$restriction = true;

				return array( $file_path, $remote_file, $restriction );
			}
			// Check if the file has a relative path
			if ( $relative ) {
				// Now we should get longest commont path from the allowed paths.
				$common_path = DLM_Utils::longest_common_path( $allowed_paths );
				// If there is no common path, or is emtpy or is just a slash, return the file path, else do the replacement.
				if ( strlen( $common_path ) > 1 ) {
					$file_path = str_replace( $common_path, '', $file_path );
				}
			}

			$restriction = false;

			return array( $file_path, $remote_file, $restriction );
		}

		/**
		 * Get file allowed paths
		 *
		 * @return array
		 * @since 4.5.92
		 */
		public function get_allowed_paths() {
			// Get ABSPATH
			$abspath_sub       = str_replace( DIRECTORY_SEPARATOR,
				'/',
				untrailingslashit( ABSPATH ) );
			// Get user defined path
			$user_defined_path = str_replace( DIRECTORY_SEPARATOR,
				'/',
				get_option( 'dlm_downloads_path' ) );
			// Create the allowed paths array
			$allowed_paths     = array();
			// Check if the ABSPATH is in the WP_CONTENT_DIR
			if ( false === strpos( WP_CONTENT_DIR, ABSPATH ) ) {
				$content_dir   = str_replace( DIRECTORY_SEPARATOR,
					'/',
					str_replace( 'wp-content',
						'',
						untrailingslashit( WP_CONTENT_DIR ) ) );
				$allowed_paths = array( $abspath_sub, $content_dir );
			} else {
				$allowed_paths = array( $abspath_sub );
			}
			// Add the user defined path to the allowed paths array
			if ( $user_defined_path ) {
				$allowed_paths[] = $user_defined_path;
			}

			return $allowed_paths;
		}

		/**
		 * Return the correct path for the file by comparing the file path string with the allowed paths.
		 *
		 * @param  string  $file_path  The current path of the file
		 * @param  array  $allowed_paths  The allowed paths of the files
		 *
		 * @return string The correct path of the file
		 * @since 4.5.92
		 */
		public function get_correct_path( $file_path, $allowed_paths ) {
			/* We assume first assume that the path is false, as the ABSPATH is always allowed asnd should always be in the
			* allowed paths.
			*/
			$correct_path = false;

			// Cycle through the allowed paths and check if one of the allowed paths are in the file path.
			if ( ! empty( $allowed_paths ) ) {
				foreach ( $allowed_paths as $allowed_path ) {
					// If we encounter a scenario where the file is in the allowed path, we can trust it is in the correct path, so we should break the loop.
					if ( false !== strpos( $file_path, $allowed_path ) ) {
						$correct_path = $allowed_path;
						break;
					}
				}
			}

			return $correct_path;
		}

		/**
		 * Check for symbolik links in the file path.
		 *
		 * @param  string  $file_path  The file's path
		 * @param  bool  $redirect  Whether to redirect the user to the correct path. Default is false.
		 *
		 * @return array|mixed|string|string[]
		 */
		public function check_symbolic_links( $file_path, $redirect = false ) {
			// On Pantheon hosted sites the upload dir is a symbolic link to another location.
			// Make a filter of all shortcuts/symbolik links so that users can attach to them because we do not know what/how the server
			// is configured.
			$shortcuts     = apply_filters( 'dlm_upload_shortcuts',
				array( wp_get_upload_dir()['basedir'] ) );
			$scheme        = wp_parse_url( get_option( 'home' ),
				PHP_URL_SCHEME );
			// Get allowed paths
			$allowed_paths = download_monitor()->service( 'file_manager' )
			                                   ->get_allowed_paths();
			// Get the correct path
			$correct_path  = download_monitor()->service( 'file_manager' )
			                                   ->get_correct_path( $file_path,
				                                   $allowed_paths );

			if ( ! empty( $shortcuts ) ) {
				foreach ( $shortcuts as $shortcut ) {
					if ( is_link( $shortcut )
					     && readlink( $shortcut ) === $correct_path
					) {
						$file_path = str_replace( $correct_path,
							$shortcut,
							$file_path );
						if ( $redirect ) {
							$file_path = str_replace( ABSPATH,
								site_url( '/', $scheme ),
								$file_path );
						}
					}
				}
			}

			return $file_path;
		}

		/**
		 * Function to move files from Media Library to the DLM protected folder dlm_uploads.
		 *
		 * @param $post_id
		 *
		 * @return WP_Error
		 * @since 4.7.2
		 */
		public function move_file_to_dlm_uploads( $post_id ) {
			//Move file to dlm_uploads
			$file = get_post_meta( $post_id, '_wp_attached_file', true );

			if ( 0 === stripos( $file, $this->dlm_upload_dir( '/' ) ) ) {
				return new WP_Error( 'protected_file_existed', sprintf(
					__( 'This file is already protected. Please reload your page.',
						'download-monitor' ),
					$file
				), array( 'status' => 500 ) );
			}

			$reldir = dirname( $file );

			if ( in_array( $reldir, array( '\\', '/', '.' ), true ) ) {
				$reldir = '';
			}

			$protected_dir = path_join( $this->dlm_upload_dir(), $reldir );

			return $this->move_attachment_to_protected( $post_id,
				$protected_dir );
		}

		/**
		 * Function to move files back to the Media Library.
		 *
		 * @param $post_id
		 *
		 * @return array|bool|int|WP_Error
		 * @since 4.7.2
		 */
		public function move_file_back( $post_id ) {
			$file = get_post_meta( $post_id, '_wp_attached_file', true );

			// check if files are already not in Download Monitor's protected folder
			if ( 0 !== stripos( $file, $this->dlm_upload_dir( '/' ) ) ) {
				return true;
			}

			$protected_dir = ltrim( dirname( $file ),
				$this->dlm_upload_dir( '/' ) );

			return $this->move_attachment_to_protected( $post_id,
				$protected_dir );
		}

		/**
		 * Download Monitor's upload directory ( dlm_uploads ).
		 *
		 * @param $path
		 * @param $in_url
		 *
		 * @return string
		 * @since 4.7.2
		 */
		public function dlm_upload_dir( $path = '', $in_url = false ) {
			$dirpath = $in_url ? '/' : '';
			$dirpath .= 'dlm_uploads';
			$dirpath .= $path;

			return $dirpath;
		}

		/**
		 *  Move attachment to protected folder.
		 *
		 * @param $attachment_id
		 * @param $protected_dir
		 * @param $meta_input
		 *
		 * @return array|bool|WP_Error
		 * @since 4.7.2
		 */
		public function move_attachment_to_protected( $attachment_id, $protected_dir, $meta_input = [] ) {
			// Only attachments can be moved
			if ( 'attachment' !== get_post_type( $attachment_id ) ) {
				return new WP_Error( 'not_attachment', sprintf(
					__( 'The post with ID: %d is not an attachment post type.',
						'download-monitor' ),
					$attachment_id
				), array( 'status' => 404 ) );
			}
			// Check if the path is relative to the WP uploads directory
			if ( path_is_absolute( $protected_dir ) ) {
				return new WP_Error( 'protected_dir_not_relative', sprintf(
					__( 'The new path provided: %s is absolute. The new path must be a path relative to the WP uploads directory.',
						'download-monitor' ),
					$protected_dir
				), array( 'status' => 404 ) );
			}

			$meta = empty( $meta_input )
				? wp_get_attachment_metadata( $attachment_id ) : $meta_input;
			$meta = is_array( $meta ) ? $meta : array();

			$file       = get_post_meta( $attachment_id,
				'_wp_attached_file',
				true );
			$backups    = get_post_meta( $attachment_id,
				'_wp_attachment_backup_sizes',
				true );
			$upload_dir = wp_upload_dir();
			$old_dir    = dirname( $file );

			if ( in_array( $old_dir, array( '\\', '/', '.' ), true ) ) {
				$old_dir = '';
			}

			if ( $protected_dir === $old_dir ) {
				return true;
			}

			$old_full_path       = path_join( $upload_dir['basedir'],
				$old_dir );
			$protected_full_path = path_join( $upload_dir['basedir'],
				$protected_dir );
			// Try to make the directory if it doesn't exist
			if ( ! wp_mkdir_p( $protected_full_path ) ) {
				return new WP_Error( 'wp_mkdir_p_error', sprintf(
					__( 'There was an error making or verifying the directory at: %s',
						'download-monitor' ),
					$protected_full_path
				), array( 'status' => 500 ) );
			}

			//Get all files
			$sizes = array();

			if ( array_key_exists( 'sizes', $meta ) ) {
				$sizes = $this->get_files_from_meta( $meta['sizes'] );
			}

			$backup_sizes  = $this->get_files_from_meta( $backups );
			$old_basenames = $new_basenames = array_merge(
				array( wp_basename( $file ) ),
				$sizes,
				$backup_sizes
			);
			$orig_basename = wp_basename( $file );

			if ( is_array( $backups ) && isset( $backups['full-orig'] ) ) {
				$orig_basename = $backups['full-orig']['file'];
			}

			$orig_filename = pathinfo( $orig_basename );
			$orig_filename = $orig_filename['filename'];

			$result        = $this->resolve_name_conflict( $new_basenames,
				$protected_full_path,
				$orig_filename );
			$new_basenames = $result['new_basenames'];

			$this->rename_files( $old_basenames,
				$new_basenames,
				$old_full_path,
				$protected_full_path );

			$base_file_name = 0;

			$new_attached_file = path_join( $protected_dir, $new_basenames[0] );
			if ( array_key_exists( 'file', $meta ) ) {
				$meta['file'] = $new_attached_file;
			}
			// Update attached file
			update_post_meta( $attachment_id,
				'_wp_attached_file',
				$new_attached_file );

			if ( $new_basenames[ $base_file_name ]
			     != $old_basenames[ $base_file_name ]
			) {
				$pattern       = $result['pattern'];
				$replace       = $result['replace'];
				$separator     = "#";
				$orig_basename = ltrim(
					str_replace( $pattern,
						$replace,
						$separator . $orig_basename ),
					$separator
				);
				$meta          = $this->update_meta_sizes_file( $meta,
					$new_basenames );
				$this->update_backup_files( $attachment_id,
					$backups,
					$new_basenames );
			}
			// Update meta
			update_post_meta( $attachment_id,
				'_wp_attachment_metadata',
				$meta );
			$guid = path_join( $protected_full_path, $orig_basename );
			// Set new guid
			wp_update_post( array( 'ID' => $attachment_id, 'guid' => $guid ) );

			return empty( $meta_input ) ? true : $meta;
		}

		/**
		 * Get files from meta.
		 *
		 * @param $input
		 *
		 * @return array
		 * @since 4.7.2
		 */
		public function get_files_from_meta( $input ) {
			$files = array();
			if ( is_array( $input ) ) {
				foreach ( $input as $size ) {
					$files[] = $size['file'];
				}
			}

			return $files;
		}

		/**
		 * Resolve name conflict.
		 *
		 * @param $new_basenames
		 * @param $protected_full_path
		 * @param $orig_file_name
		 *
		 * @return array
		 * @since 4.7.2
		 */
		public function resolve_name_conflict(
			$new_basenames,
			$protected_full_path,
			$orig_file_name
		) {
			$conflict     = true;
			$number       = 1;
			$separator    = "#";
			$med_filename = $orig_file_name;
			$pattern      = "";
			$replace      = "";

			while ( $conflict ) {
				$conflict = false;
				foreach ( $new_basenames as $basename ) {
					if ( is_file( path_join( $protected_full_path,
						$basename ) )
					) {
						$conflict = true;
						break;
					}
				}

				if ( $conflict ) {
					$new_filename = "$orig_file_name-$number";
					$number ++;
					$pattern       = "$separator$med_filename";
					$replace       = "$separator$new_filename";
					$new_basenames = explode(
						$separator,
						ltrim(
							str_replace( $pattern,
								$replace,
								$separator . implode( $separator,
									$new_basenames ) ),
							$separator
						)
					);
				}
			}

			return array(
				'new_basenames' => $new_basenames,
				'pattern'       => $pattern,
				'replace'       => $replace,
			);
		}

		/**
		 * Rename files.
		 *
		 * @param $old_basenames
		 * @param $new_basenames
		 * @param $old_dir
		 * @param $protected_dir
		 *
		 * @return void|WP_Error
		 * @since 4.7.2
		 */
		public function rename_files(
			$old_basenames,
			$new_basenames,
			$old_dir,
			$protected_dir
		) {
			$unique_old_basenames
				= array_values( array_unique( $old_basenames ) );
			$unique_new_basenames
				= array_values( array_unique( $new_basenames ) );
			$i  = count( $unique_old_basenames );

			while ( $i -- ) {
				$old_fullpath = path_join( $old_dir,
					$unique_old_basenames[ $i ] );
				$new_fullpath = path_join( $protected_dir,
					$unique_new_basenames[ $i ] );
				if ( is_file( $old_fullpath ) ) {
					rename( $old_fullpath, $new_fullpath );

					if ( ! is_file( $new_fullpath ) ) {
						return new WP_Error(
							'rename_failed',
							sprintf(
								__( 'Rename failed when trying to move file from: %s, to: %s',
									'download-monitor' ),
								$old_fullpath,
								$new_fullpath
							)
						);
					}
				}
			}
		}

		/**
		 * Update meta sizes file.
		 *
		 * @param $meta
		 * @param $new_basenames
		 *
		 * @return array
		 * @since 4.7.2
		 */
		public function update_meta_sizes_file( $meta, $new_basenames ) {
			if ( is_array( $meta['sizes'] ) ) {
				$i = 0;

				foreach ( $meta['sizes'] as $size => $data ) {
					$meta['sizes'][ $size ]['file'] = $new_basenames[ ++ $i ];
				}
			}

			return $meta;
		}

		/**
		 * Update backup files.
		 *
		 * @param $attachment_id
		 * @param $backups
		 * @param $new_basenames
		 *
		 * @return void
		 * @since 4.7.2
		 */
		public function update_backup_files(
			$attachment_id,
			$backups,
			$new_basenames
		) {
			if ( is_array( $backups ) ) {
				$i                = 0;
				$l                = count( $backups );
				$new_backup_sizes = array_slice( $new_basenames, - $l, $l );

				foreach ( $backups as $size => $data ) {
					$backups[ $size ]['file'] = $new_backup_sizes[ $i ++ ];
				}
				update_post_meta( $attachment_id,
					'_wp_attachment_backup_sizes',
					$backups );
			}
		}
	}
}
Site is undergoing maintenance

PACJA Events

Maintenance mode is on

Site will be available soon. Thank you for your patience!