├── .gitignore ├── tests ├── unit │ └── CommandTest.php └── TestCase.php ├── config └── template.php ├── composer.json ├── src ├── Plugin.php ├── Command.php └── Generator.php ├── genesis-config-exporter.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.lock 3 | vendor 4 | -------------------------------------------------------------------------------- /tests/unit/CommandTest.php: -------------------------------------------------------------------------------- 1 | assertTrue( true ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | [ 23 | 'plugins' => [ 24 | {{plugins}} 25 | ], 26 | ], 27 | 'content' => [ 28 | {{content}} 29 | ], 30 | 'navigation_menus' => [ 31 | {{navmenu}} 32 | ], 33 | 'widgets' => [ 34 | {{widgets}} 35 | ], 36 | ]; 37 | TEMPLATE; 38 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "seothemes/genesis-config-exporter", 3 | "type": "wordpress-plugin", 4 | "license": "GPL-2.0-or-later", 5 | "authors": [ 6 | { 7 | "name": "seothemes", 8 | "email": "seothemeswp@gmail.com" 9 | } 10 | ], 11 | "require": { 12 | "php": "^7.2" 13 | }, 14 | "require-dev": { 15 | "brain/monkey": "^2.3", 16 | "phpunit/phpunit": "^8.3", 17 | "squizlabs/php_codesniffer": "^3.4", 18 | "wp-cli/wp-cli-bundle": "^2.3", 19 | "wp-coding-standards/wpcs": "^2.1" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "SeoThemes\\GenesisConfigExporter\\": "src" 24 | } 25 | }, 26 | "autoload-dev": { 27 | "psr-4": { 28 | "SeoThemes\\GenesisConfigExporter\\Tests\\": "tests" 29 | } 30 | }, 31 | "scripts": { 32 | "test": "./vendor/bin/phpunit --bootstrap=vendor/autoload.php tests/ --colors=always" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Plugin.php: -------------------------------------------------------------------------------- 1 | file = $file; 49 | $this->dir = \trailingslashit( \dirname( $file ) ); 50 | $this->url = \trailingslashit( \plugin_dir_url( $file ) ); 51 | $this->base = \plugin_basename( $file ); 52 | $this->handle = \basename( $file, '.php' ); 53 | $this->name = \ucwords( \str_replace( '-', ' ', $this->handle ) ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Command.php: -------------------------------------------------------------------------------- 1 | generator = $generator; 24 | } 25 | 26 | /** 27 | * Description of expected behavior. 28 | * 29 | * @since 1.0.0 30 | * 31 | * @param $args 32 | * @param $assoc_args 33 | * 34 | * @return void 35 | * @throws \Exception 36 | */ 37 | public function export( $args, $assoc_args ) { 38 | if ( ! isset( $assoc_args['force'] ) ) { 39 | \WP_CLI::confirm( 'This will overwrite your current child theme\'s onboarding config file. Proceed?' ); 40 | } 41 | 42 | if ( ! isset( $assoc_args['dry'] ) ) { 43 | $this->generator->generate( $assoc_args ); 44 | } 45 | 46 | if ( isset( $assoc_args['dry'] ) ) { 47 | echo $this->generator->replace(); 48 | } 49 | 50 | \WP_CLI::success( 'Generated ' . $this->generator->file_path ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /genesis-config-exporter.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 39 | $this->template = require_once $this->plugin->dir . 'config/template.php'; 40 | $this->file_path = \get_stylesheet_directory() . '/config/onboarding.php'; 41 | $this->image_dir = '/config/images/'; 42 | } 43 | 44 | /** 45 | * Description of expected behavior. 46 | * 47 | * @since 1.0.0 48 | * 49 | * @param array $args Associative array of args from WP CLI. 50 | * 51 | * @return void 52 | * 53 | * @throws \Exception 54 | */ 55 | public function generate( $args ) { 56 | include_once ABSPATH . '/wp-admin/includes/file.php'; 57 | \WP_Filesystem(); 58 | 59 | /** 60 | * Set up file system. 61 | * 62 | * @var \WP_Filesystem_Base $wp_filesystem 63 | */ 64 | global $wp_filesystem; 65 | 66 | $wp_filesystem->put_contents( $this->file_path, $this->replace( $args ) ); 67 | } 68 | 69 | /** 70 | * Description of expected behavior. 71 | * 72 | * @since 1.0.0 73 | * 74 | * @param array $args Command args. 75 | * 76 | * @return mixed 77 | */ 78 | public function replace( $args ) { 79 | $template = $this->template; 80 | $theme = \wp_get_theme(); 81 | 82 | $replace = [ 83 | 'name' => $theme->get( 'Name' ), 84 | 'package' => $theme->get( 'Name' ), 85 | 'author' => $theme->get( 'Author' ), 86 | 'link' => $theme->get( 'ThemeURI' ), 87 | 'plugins' => $this->get_plugins( $args ), 88 | 'content' => $this->get_content( $args ), 89 | 'navmenu' => $this->get_navmenu( $args ), 90 | 'widgets' => $this->get_widgets( $args ), 91 | ]; 92 | 93 | foreach ( $replace as $from => $to ) { 94 | $template = str_replace( "{{{$from}}}", $to, $template ); 95 | } 96 | 97 | return $template; 98 | } 99 | 100 | /** 101 | * Description of expected behavior. 102 | * 103 | * @since 1.0.0 104 | * 105 | * @param array $args Command args. 106 | * 107 | * @return string 108 | */ 109 | private function get_plugins( $args ) { 110 | $plugins = ''; 111 | $active = \array_values( \get_option( 'active_plugins' ) ); 112 | $count = 0; 113 | 114 | if ( ( $key = array_search( $this->plugin->base, $active ) ) !== false ) { 115 | unset( $active[ $key ] ); 116 | } 117 | 118 | foreach ( $active as $slug ) { 119 | $base = explode( DIRECTORY_SEPARATOR, $slug )[0]; 120 | $name = ucwords( str_replace( '-', ' ', $base ) ); 121 | $url = "https://wordpress.org/plugins/$base/"; 122 | 123 | $plugins .= 0 === $count++ ? "[" : "\n\t\t\t["; 124 | $plugins .= " 125 | 'name' => '{$name}', 126 | 'slug' => '{$slug}', 127 | 'public_url' => '{$url}', 128 | ],"; 129 | } 130 | 131 | return $plugins; 132 | } 133 | 134 | /** 135 | * Description of expected behavior. 136 | * 137 | * @since 1.0.0 138 | * 139 | * @param array $args Command args. 140 | * 141 | * @return string 142 | */ 143 | private function get_content( $args ) { 144 | $content = ''; 145 | $posts = \get_posts( [ 146 | 'numberposts' => -1, 147 | 'post_type' => 'any', 148 | //'post_status' => [ 'publish', 'inherit' ], // Include attachments. 149 | ] ); 150 | 151 | foreach ( $posts as $post ) { 152 | 153 | // Generate meta. 154 | $meta_input = ''; 155 | $meta = \get_post_meta( $post->ID, false, true ); 156 | 157 | foreach ( $meta as $key => $value ) { 158 | if ( isset( $value[0] ) && ! empty( $value[0] ) ) { 159 | $original = $value[0]; 160 | $value = '_thumbnail_id' === $key ? \get_the_title( $original ) : $original; 161 | 162 | //if ( '_wp_attachment_metadata' === $key ) { 163 | // $value = $this->get_attachment_meta( $original ); 164 | //} 165 | 166 | $meta_input .= "\n\t\t\t\t'{$key}' => '{$value}',"; 167 | } 168 | } 169 | 170 | $meta_input = ! empty( $meta_input ) ? "\n\t\t\t'meta_input' => [ $meta_input \n\t\t\t]," : ''; 171 | 172 | // Generate images. 173 | $featured_image = ''; 174 | 175 | if ( isset( $meta['_thumbnail_id'][0] ) || 'attachment' === $post->post_type ) { 176 | $featured_image = $this->get_featured_image( $post, $meta, $args ); 177 | } 178 | 179 | // Generate content. 180 | $post_content = \str_replace( '\'', ''', $post->post_content ); 181 | $post_content = "\n\t\t\t'post_content' => '{$post_content}',"; 182 | 183 | $content .= "'{$post->post_name}' => [ 184 | 'post_title' => '{$post->post_title}', 185 | 'post_type' => '{$post->post_type}', 186 | 'post_status' => '{$post->post_status}', 187 | 'comment_status' => '{$post->comment_status}', 188 | 'ping_status' => '{$post->ping_status}',"; 189 | 190 | $content .= $featured_image . $meta_input . $post_content; 191 | $content .= "\n\t\t],\n\t\t"; 192 | } 193 | 194 | return $content; 195 | } 196 | 197 | /** 198 | * Description of expected behavior. 199 | * 200 | * @since 1.0.0 201 | * 202 | * @param $post 203 | * @param $meta 204 | * @param array $args Command args. 205 | * 206 | * @return string 207 | */ 208 | private function get_featured_image( $post, $meta, $args ) { 209 | $image = []; 210 | $image_dir = isset( $args['image_dir'] ) ? $args['image_dir'] : $this->image_dir; 211 | 212 | if ( 'attachment' === $post->post_type ) { 213 | $image['path'] = \wp_get_upload_dir()['basedir'] . DIRECTORY_SEPARATOR . $meta['_wp_attached_file'][0]; 214 | 215 | } else { 216 | $image['path'] = \get_attached_file( $meta['_thumbnail_id'][0] ); 217 | } 218 | 219 | $image['dir'] = \get_stylesheet_directory() . $image_dir; 220 | $image['name'] = \basename( $image['path'] ); 221 | $image['file'] = $image['dir'] . DIRECTORY_SEPARATOR . $image['name']; 222 | $image['url'] = "\\get_stylesheet_directory() . '{$image_dir}{$image['name']}'"; 223 | 224 | if ( ! is_dir( $image['dir'] ) ) { 225 | \wp_mkdir_p( $image['dir'] ); 226 | } 227 | 228 | if ( ! file_exists( $image['file'] ) ) { 229 | \copy( $image['path'], $image['file'] ); 230 | } 231 | 232 | return "\n\t\t\t'featured_image' => {$image['url']},"; 233 | } 234 | 235 | /** 236 | * Description of expected behavior. 237 | * 238 | * @since 1.0.0 239 | * 240 | * @param $meta_data 241 | * 242 | * @return string 243 | */ 244 | private function get_attachment_meta( $meta_data ) { 245 | $meta_data = \unserialize( $meta_data ); 246 | $attachment_meta = '['; 247 | $formatted_value = ''; 248 | 249 | foreach ( $meta_data as $meta_name => $meta_value ) { 250 | if ( is_string( $meta_value ) ) { 251 | $formatted_value = "'{$meta_value}'"; 252 | 253 | } elseif ( is_int( $meta_value ) ) { 254 | $formatted_value = "{$meta_value}"; 255 | 256 | } elseif ( 'image_meta' === $meta_name && is_array( $meta_value ) ) { 257 | $formatted_value = "["; 258 | 259 | foreach ( $meta_value as $image_meta_name => $image_meta_value ) { 260 | if ( ! is_array( $image_meta_value ) ) { 261 | $formatted_value .= "\n\t\t\t\t\t\t'{$image_meta_name}' => '{$image_meta_value}',"; 262 | } 263 | } 264 | 265 | $formatted_value .= "\n\t\t\t\t\t]"; 266 | 267 | } elseif ( 'sizes' === $meta_name ) { 268 | $formatted_value = "["; 269 | 270 | foreach ( $meta_value as $size_key => $size_value ) { 271 | if ( is_array( $size_value ) ) { 272 | $formatted_value .= "\n\t\t\t\t\t\t'$size_key' => ["; 273 | 274 | foreach ( $size_value as $size_name => $size ) { 275 | $formatted_value .= "\n\t\t\t\t\t\t\t'{$size_name}' => '{$size}',"; 276 | } 277 | 278 | $formatted_value .= "\n\t\t\t\t\t\t],"; 279 | } 280 | } 281 | 282 | $formatted_value .= "\n\t\t\t\t\t]"; 283 | } 284 | 285 | $attachment_meta .= "\n\t\t\t\t\t'{$meta_name}' => {$formatted_value},"; 286 | } 287 | 288 | $attachment_meta .= "\n\t\t\t\t]"; 289 | 290 | return $attachment_meta; 291 | } 292 | 293 | /** 294 | * Description of expected behavior. 295 | * 296 | * @since 1.0.0 297 | * 298 | * @param array $args Command args. 299 | * 300 | * @return string 301 | */ 302 | private function get_navmenu( $args ) { 303 | $menus = ''; 304 | $locations = \get_registered_nav_menus(); 305 | 306 | foreach ( $locations as $location => $title ) { 307 | $menu_items = \wp_get_nav_menu_items( $title ); 308 | 309 | if ( ! is_array( $menu_items ) ) { 310 | continue; 311 | } 312 | 313 | $menus .= "'$location' => [\n"; 314 | 315 | foreach ( $menu_items as $menu_item ) { 316 | $url = \basename( $menu_item->url ); 317 | 318 | $menu_item_slugs[ $menu_item->ID ] = $url; 319 | 320 | $menus .= "\t\t\t'{$url}' => [\n"; 321 | $menus .= "\t\t\t\t'title' => '{$menu_item->title}',\n"; 322 | $menus .= "\t\t\t\t'id' => '{$url}',\n"; 323 | 324 | // If has a parent. 325 | if ( $menu_item->menu_item_parent ) { 326 | $menus .= "\t\t\t\t'parent' => '{$menu_item_slugs[$menu_item->menu_item_parent]}',\n"; 327 | } 328 | 329 | $menus .= "\t\t\t],\n"; 330 | } 331 | 332 | $menus .= "\t\t],"; 333 | } 334 | 335 | return $menus; 336 | } 337 | 338 | /** 339 | * Description of expected behavior. 340 | * 341 | * @since 1.0.0 342 | * 343 | * @param array $args Command args. 344 | * 345 | * @return string 346 | */ 347 | private function get_widgets( $args ) { 348 | $widgets = ''; 349 | 350 | $sidebars_widgets = \wp_get_sidebars_widgets(); 351 | unset( $sidebars_widgets['wp_inactive_widgets'] ); 352 | 353 | foreach ( $sidebars_widgets as $widget_area => $widgets_array ) { 354 | 355 | if ( empty( $widgets_array ) ) { 356 | continue; 357 | } 358 | 359 | $widgets .= "\t\t'$widget_area' => [\n"; 360 | 361 | foreach ( $widgets_array as $widget ) { 362 | $type = substr( $widget, 0, strrpos( $widget, '-' ) ); 363 | $id = substr( $widget, strrpos( $widget, '-' ) + 1 ); 364 | $args = \get_option( "widget_$type" )[ $id ]; 365 | 366 | $widgets .= "\t\t\t[\n"; 367 | $widgets .= "\t\t\t\t'type' => '$type',\n"; 368 | 369 | if ( ! empty( $args ) ) { 370 | $widgets .= "\t\t\t\t'args' => [\n"; 371 | 372 | foreach ( $args as $key => $value ) { 373 | $escaped = \str_replace( '\'', ''', $value ); 374 | $widgets .= "\t\t\t\t\t'$key' => '$escaped',\n"; 375 | } 376 | 377 | $widgets .= "\t\t\t\t],"; 378 | } 379 | 380 | $widgets .= "\n\t\t\t],"; 381 | } 382 | 383 | $widgets .= "\n\t\t],\n"; 384 | } 385 | 386 | return $widgets; 387 | } 388 | } 389 | --------------------------------------------------------------------------------