class-acf-admin-tool-export.php
1 year ago
class-acf-admin-tool-import.php
7 months ago
class-acf-admin-tool.php
1 year ago
index.php
1 year ago
class-acf-admin-tool-import.php
299 lines
| 1 | <?php |
| 2 | |
| 3 | if ( ! defined( 'ABSPATH' ) ) { |
| 4 | exit; // Exit if accessed directly |
| 5 | } |
| 6 | |
| 7 | if ( ! class_exists( 'ACF_Admin_Tool_Import' ) ) : |
| 8 | |
| 9 | class ACF_Admin_Tool_Import extends ACF_Admin_Tool { |
| 10 | |
| 11 | |
| 12 | /** |
| 13 | * initialize |
| 14 | * |
| 15 | * This function will initialize the admin tool |
| 16 | * |
| 17 | * @date 10/10/17 |
| 18 | * @since ACF 5.6.3 |
| 19 | * |
| 20 | * @param n/a |
| 21 | * @return n/a |
| 22 | */ |
| 23 | function initialize() { |
| 24 | |
| 25 | // vars |
| 26 | $this->name = 'import'; |
| 27 | $this->title = __( 'Import Field Groups', 'secure-custom-fields' ); |
| 28 | $this->icon = 'dashicons-upload'; |
| 29 | } |
| 30 | |
| 31 | |
| 32 | /** |
| 33 | * html |
| 34 | * |
| 35 | * This function will output the metabox HTML |
| 36 | * |
| 37 | * @date 10/10/17 |
| 38 | * @since ACF 5.6.3 |
| 39 | * |
| 40 | * @param n/a |
| 41 | * @return n/a |
| 42 | */ |
| 43 | function html() { |
| 44 | |
| 45 | ?> |
| 46 | <div class="acf-postbox-header"> |
| 47 | <h2 class="acf-postbox-title"><?php esc_html_e( 'Import', 'secure-custom-fields' ); ?></h2> |
| 48 | <div class="acf-tip"><i tabindex="0" class="acf-icon acf-icon-help acf-js-tooltip" title="<?php esc_attr_e( 'Choose an SCF JSON file to import. Use only files from trusted sources, then click Import.', 'secure-custom-fields' ); ?>">?</i></div> |
| 49 | </div> |
| 50 | <div class="acf-postbox-inner"> |
| 51 | <div class="acf-fields"> |
| 52 | <?php |
| 53 | |
| 54 | acf_render_field_wrap( |
| 55 | array( |
| 56 | 'label' => __( 'Select JSON File', 'secure-custom-fields' ), |
| 57 | 'type' => 'file', |
| 58 | 'name' => 'acf_import_file', |
| 59 | 'value' => false, |
| 60 | 'uploader' => 'basic', |
| 61 | 'mime_types' => 'application/json,application/x-json,application/x-javascript,text/javascript,text/x-javascript,text/json', |
| 62 | 'instructions' => __( 'Import JSON containing field groups, post types, or taxonomies (trusted sources only)', 'secure-custom-fields' ), |
| 63 | ) |
| 64 | ); |
| 65 | |
| 66 | ?> |
| 67 | </div> |
| 68 | <p class="acf-submit"> |
| 69 | <button type="submit" class="acf-btn" name="import_type" value="json"> |
| 70 | <?php esc_html_e( 'Import JSON', 'secure-custom-fields' ); ?> |
| 71 | </button> |
| 72 | </p> |
| 73 | |
| 74 | <?php |
| 75 | if ( is_plugin_active( 'custom-post-type-ui/custom-post-type-ui.php' ) && acf_get_setting( 'enable_post_types' ) ) { |
| 76 | $cptui_post_types = get_option( 'cptui_post_types' ); |
| 77 | $cptui_taxonomies = get_option( 'cptui_taxonomies' ); |
| 78 | $choices = array(); |
| 79 | $overwrite_warning = false; |
| 80 | |
| 81 | if ( $cptui_post_types ) { |
| 82 | $choices['post_types'] = __( 'Post Types', 'secure-custom-fields' ); |
| 83 | $existing_post_types = acf_get_acf_post_types(); |
| 84 | |
| 85 | foreach ( $existing_post_types as $existing_post_type ) { |
| 86 | if ( isset( $cptui_post_types[ $existing_post_type['post_type'] ] ) ) { |
| 87 | $overwrite_warning = true; |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | if ( $cptui_taxonomies ) { |
| 93 | $choices['taxonomies'] = __( 'Taxonomies', 'secure-custom-fields' ); |
| 94 | |
| 95 | if ( ! $overwrite_warning ) { |
| 96 | $existing_taxonomies = acf_get_acf_taxonomies(); |
| 97 | foreach ( $existing_taxonomies as $existing_taxonomy ) { |
| 98 | if ( isset( $cptui_taxonomies[ $existing_taxonomy['taxonomy'] ] ) ) { |
| 99 | $overwrite_warning = true; |
| 100 | } |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | if ( ! empty( $choices ) ) : |
| 106 | ?> |
| 107 | <div class="acf-fields import-cptui"> |
| 108 | <?php |
| 109 | acf_render_field_wrap( |
| 110 | array( |
| 111 | 'label' => __( 'Import from Custom Post Type UI', 'secure-custom-fields' ), |
| 112 | 'type' => 'checkbox', |
| 113 | 'name' => 'acf_import_cptui', |
| 114 | 'choices' => $choices, |
| 115 | 'toggle' => true, |
| 116 | ) |
| 117 | ); |
| 118 | ?> |
| 119 | </div> |
| 120 | <?php |
| 121 | if ( $overwrite_warning ) { |
| 122 | echo '<p class="acf-inline-notice notice notice-info">' . esc_html__( 'Importing a Post Type or Taxonomy with the same key as one that already exists will overwrite the settings for the existing Post Type or Taxonomy with those of the import.', 'secure-custom-fields' ) . '</p>'; |
| 123 | } |
| 124 | ?> |
| 125 | <p class="acf-submit"> |
| 126 | <button type="submit" class="acf-btn" name="import_type" value="cptui"> |
| 127 | <?php esc_html_e( 'Import from Custom Post Type UI', 'secure-custom-fields' ); ?> |
| 128 | </button> |
| 129 | </p> |
| 130 | <?php |
| 131 | endif; |
| 132 | } |
| 133 | ?> |
| 134 | </div> |
| 135 | <?php |
| 136 | } |
| 137 | |
| 138 | /** |
| 139 | * Imports the selected ACF posts and returns an admin notice on completion. |
| 140 | * |
| 141 | * @since ACF 5.6.3 |
| 142 | * |
| 143 | * @return ACF_Admin_Notice |
| 144 | */ |
| 145 | public function submit() { |
| 146 | //phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce verified before this function is called. |
| 147 | if ( 'cptui' === acf_request_arg( 'import_type', '' ) && ! empty( $_POST['acf_import_cptui'] ) ) { |
| 148 | $import = acf_sanitize_request_args( $_POST['acf_import_cptui'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- unslash not needed. |
| 149 | return $this->import_cpt_ui( $import ); |
| 150 | } |
| 151 | |
| 152 | // Check file size. |
| 153 | if ( empty( $_FILES['acf_import_file']['size'] ) ) { |
| 154 | return acf_add_admin_notice( __( 'No file selected', 'secure-custom-fields' ), 'warning' ); |
| 155 | } |
| 156 | |
| 157 | $file = acf_sanitize_files_array( $_FILES['acf_import_file'] ); |
| 158 | |
| 159 | // Check errors. |
| 160 | if ( $file['error'] ) { |
| 161 | return acf_add_admin_notice( __( 'Error uploading file. Please try again', 'secure-custom-fields' ), 'warning' ); |
| 162 | } |
| 163 | |
| 164 | // Check file type. |
| 165 | if ( pathinfo( $file['name'], PATHINFO_EXTENSION ) !== 'json' ) { |
| 166 | return acf_add_admin_notice( __( 'Incorrect file type', 'secure-custom-fields' ), 'warning' ); |
| 167 | } |
| 168 | |
| 169 | // Read JSON. |
| 170 | $json = file_get_contents( $file['tmp_name'] ); |
| 171 | $json = json_decode( $json, true ); |
| 172 | |
| 173 | // Check if empty. |
| 174 | if ( ! $json || ! is_array( $json ) ) { |
| 175 | return acf_add_admin_notice( __( 'Import file empty', 'secure-custom-fields' ), 'warning' ); |
| 176 | } |
| 177 | |
| 178 | // Ensure $json is an array of posts. |
| 179 | if ( isset( $json['key'] ) ) { |
| 180 | $json = array( $json ); |
| 181 | } |
| 182 | |
| 183 | // Remember imported post ids. |
| 184 | $ids = array(); |
| 185 | |
| 186 | // Loop over json. |
| 187 | foreach ( $json as $to_import ) { |
| 188 | // Search database for existing post. |
| 189 | $post_type = acf_determine_internal_post_type( $to_import['key'] ); |
| 190 | $post = acf_get_internal_post_type_post( $to_import['key'], $post_type ); |
| 191 | |
| 192 | if ( $post ) { |
| 193 | $to_import['ID'] = $post->ID; |
| 194 | } |
| 195 | |
| 196 | // Import the post. |
| 197 | $to_import = acf_import_internal_post_type( $to_import, $post_type ); |
| 198 | |
| 199 | // Append message. |
| 200 | $ids[] = $to_import['ID']; |
| 201 | } |
| 202 | |
| 203 | // Count number of imported posts. |
| 204 | $total = count( $ids ); |
| 205 | |
| 206 | // Generate text. |
| 207 | /* translators: %d - number of items imported */ |
| 208 | $text = sprintf( _n( 'Imported %s item', 'Imported %s items', $total, 'secure-custom-fields' ), $total ); |
| 209 | |
| 210 | // Add links to text. |
| 211 | $links = array(); |
| 212 | foreach ( $ids as $id ) { |
| 213 | $links[] = '<a href="' . esc_url( get_edit_post_link( $id ) ) . '">' . esc_html( get_the_title( $id ) ) . '</a>'; |
| 214 | } |
| 215 | $text .= ' ' . implode( ', ', $links ); |
| 216 | |
| 217 | // Add notice. |
| 218 | return acf_add_admin_notice( $text, 'success' ); |
| 219 | //phpcs:enable WordPress.Security.NonceVerification.Missing |
| 220 | } |
| 221 | |
| 222 | /** |
| 223 | * Handles the import of CPTUI post types and taxonomies. |
| 224 | * |
| 225 | * @since ACF 6.1 |
| 226 | * |
| 227 | * @param array $import_args What to import. |
| 228 | * @return ACF_Admin_Notice |
| 229 | */ |
| 230 | public function import_cpt_ui( $import_args ) { |
| 231 | if ( ! is_array( $import_args ) ) { |
| 232 | return acf_add_admin_notice( __( 'Nothing from Custom Post Type UI plugin selected for import.', 'secure-custom-fields' ), 'warning' ); |
| 233 | } |
| 234 | |
| 235 | $imported = array(); |
| 236 | |
| 237 | // Import any post types. |
| 238 | if ( in_array( 'post_types', $import_args, true ) ) { |
| 239 | $cptui_post_types = get_option( 'cptui_post_types' ); |
| 240 | $instance = acf_get_internal_post_type_instance( 'acf-post-type' ); |
| 241 | |
| 242 | if ( ! is_array( $cptui_post_types ) || ! $instance ) { |
| 243 | return acf_add_admin_notice( __( 'Failed to import post types.', 'secure-custom-fields' ), 'warning' ); |
| 244 | } |
| 245 | |
| 246 | foreach ( $cptui_post_types as $post_type ) { |
| 247 | $result = $instance->import_cptui_post_type( $post_type ); |
| 248 | |
| 249 | if ( is_array( $result ) && isset( $result['ID'] ) ) { |
| 250 | $imported[] = (int) $result['ID']; |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | // Import any taxonomies. |
| 256 | if ( in_array( 'taxonomies', $import_args, true ) ) { |
| 257 | $cptui_taxonomies = get_option( 'cptui_taxonomies' ); |
| 258 | $instance = acf_get_internal_post_type_instance( 'acf-taxonomy' ); |
| 259 | |
| 260 | if ( ! is_array( $cptui_taxonomies ) || ! $instance ) { |
| 261 | return acf_add_admin_notice( __( 'Failed to import taxonomies.', 'secure-custom-fields' ), 'warning' ); |
| 262 | } |
| 263 | |
| 264 | foreach ( $cptui_taxonomies as $taxonomy ) { |
| 265 | $result = $instance->import_cptui_taxonomy( $taxonomy ); |
| 266 | |
| 267 | if ( is_array( $result ) && isset( $result['ID'] ) ) { |
| 268 | $imported[] = (int) $result['ID']; |
| 269 | } |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | if ( ! empty( $imported ) ) { |
| 274 | // Generate text. |
| 275 | $total = count( $imported ); |
| 276 | /* translators: %d - number of items imported from CPTUI */ |
| 277 | $text = sprintf( _n( 'Imported %d item from Custom Post Type UI -', 'Imported %d items from Custom Post Type UI -', $total, 'secure-custom-fields' ), $total ); |
| 278 | |
| 279 | // Add links to text. |
| 280 | $links = array(); |
| 281 | foreach ( $imported as $id ) { |
| 282 | $links[] = '<a href="' . esc_url( get_edit_post_link( $id ) ) . '">' . esc_html( get_the_title( $id ) ) . '</a>'; |
| 283 | } |
| 284 | |
| 285 | $text .= ' ' . implode( ', ', $links ); |
| 286 | $text .= __( '. The Custom Post Type UI plugin can be deactivated.', 'secure-custom-fields' ); |
| 287 | |
| 288 | return acf_add_admin_notice( $text, 'success' ); |
| 289 | } |
| 290 | |
| 291 | return acf_add_admin_notice( __( 'Nothing to import', 'secure-custom-fields' ), 'warning' ); |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | // Initialize. |
| 296 | acf_register_admin_tool( 'ACF_Admin_Tool_Import' ); |
| 297 | endif; // class_exists check. |
| 298 | |
| 299 | ?> |