diff --git a/.eslintrc.json b/.eslintrc.json index ffdf0cfc..d1bbe284 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "extends": "plugin:@wordpress/eslint-plugin/recommended", - "env":{ + "env": { "browser": true }, "rules": { @@ -14,12 +14,8 @@ "react/jsx-boolean-value": "error", "unicorn/no-abusive-eslint-disable": "error" }, - "ignorePatterns": [ - "src/lib" - ], - "plugins":[ - "unicorn" - ], + "ignorePatterns": [ "src/lib" ], + "plugins": [ "unicorn" ], "overrides": [ { "files": [ "**/test/**/*.js" ], diff --git a/admin/class-create-theme.php b/admin/class-create-theme.php deleted file mode 100644 index 4834ea47..00000000 --- a/admin/class-create-theme.php +++ /dev/null @@ -1,500 +0,0 @@ -theme = wp_get_theme(); - } - - function create_block_theme_enqueue() { - global $pagenow; - - if ( 'site-editor.php' !== $pagenow ) { - return; - } - - $asset_file = include plugin_dir_path( dirname( __FILE__ ) ) . 'build/plugin-sidebar.asset.php'; - - wp_register_script( - 'create-block-theme-slot-fill', - plugins_url( 'build/plugin-sidebar.js', dirname( __FILE__ ) ), - $asset_file['dependencies'], - $asset_file['version'] - ); - wp_enqueue_script( - 'create-block-theme-slot-fill', - ); - - // Enable localization in the plugin sidebar. - wp_set_script_translations( 'create-block-theme-slot-fill', 'create-block-theme' ); - } - - function create_admin_menu() { - if ( ! wp_is_block_theme() ) { - return; - } - $page_title = _x( 'Create Block Theme', 'UI String', 'create-block-theme' ); - $menu_title = _x( 'Create Block Theme', 'UI String', 'create-block-theme' ); - add_theme_page( $page_title, $menu_title, 'edit_theme_options', 'create-block-theme', array( 'CBT_Theme_Form', 'create_admin_form_page' ) ); - - add_action( 'admin_enqueue_scripts', array( 'CBT_Theme_Form', 'form_script' ) ); - } - - function save_theme_locally( $export_type ) { - CBT_Theme_Templates::add_templates_to_local( $export_type ); - CBT_Theme_JSON::add_theme_json_to_local( $export_type ); - } - - function save_variation( $export_type, $theme ) { - CBT_Theme_JSON::add_theme_json_variation_to_local( 'variation', $theme ); - } - - public function download_file( $file, $filename ) { - // Set headers. - header( 'Content-Type: application/zip' ); - header( 'Content-Disposition: attachment; filename=' . $filename ); - header( 'Content-Length: ' . filesize( $file ) ); - - // Send file. - readfile( $file ); - - // Delete file. - unlink( $file ); - } - - /** - * Export activated child theme - */ - function export_child_theme( $theme ) { - if ( $theme['name'] ) { - // Used when CREATING a child theme - $theme['slug'] = CBT_Theme_Utils::get_theme_slug( $theme['name'] ); - } else { - // Used with EXPORTING a child theme - $theme['slug'] = wp_get_theme()->get( 'TextDomain' ); - } - - // Create ZIP file in the temporary directory. - $filename = tempnam( get_temp_dir(), $theme['slug'] ); - $zip = CBT_Theme_Zip::create_zip( $filename ); - - $zip = CBT_Theme_Zip::copy_theme_to_zip( $zip, null, null ); - $zip = CBT_Theme_Zip::add_templates_to_zip( $zip, 'current', $theme['slug'] ); - $zip = CBT_Theme_Zip::add_theme_json_to_zip( $zip, CBT_Theme_JSON_Resolver::export_theme_data( 'current' ) ); - - $zip->close(); - - // Download the ZIP file. - $this->download_file( $filename, $theme['slug'] . '.zip' ); - - return $filename; - } - - /** - * Create a sibling theme of the activated theme - */ - function create_sibling_theme( $theme, $screenshot ) { - $theme_slug = CBT_Theme_Utils::get_theme_slug( $theme['name'] ); - - // Sanitize inputs. - $theme['name'] = sanitize_text_field( $theme['name'] ); - $theme['description'] = sanitize_text_field( $theme['description'] ); - $theme['uri'] = sanitize_text_field( $theme['uri'] ); - $theme['author'] = sanitize_text_field( $theme['author'] ); - $theme['author_uri'] = sanitize_text_field( $theme['author_uri'] ); - $theme['tags_custom'] = sanitize_text_field( $theme['tags_custom'] ); - $theme['image_credits'] = sanitize_textarea_field( $theme['image_credits'] ); - $theme['recommended_plugins'] = sanitize_textarea_field( $theme['recommended_plugins'] ); - $theme['font_credits'] = sanitize_textarea_field( $theme['font_credits'] ); - $theme['slug'] = $theme_slug; - $theme['template'] = wp_get_theme()->get( 'Template' ); - $theme['text_domain'] = $theme_slug; - - // Create ZIP file in the temporary directory. - $filename = tempnam( get_temp_dir(), $theme['slug'] ); - $zip = CBT_Theme_Zip::create_zip( $filename ); - - $zip = CBT_Theme_Zip::copy_theme_to_zip( $zip, $theme['slug'], $theme['name'] ); - $zip = CBT_Theme_Zip::add_templates_to_zip( $zip, 'current', $theme['slug'] ); - $zip = CBT_Theme_Zip::add_theme_json_to_zip( $zip, CBT_Theme_JSON_Resolver::export_theme_data( 'current' ) ); - - // Add readme.txt. - $zip->addFromStringToTheme( - 'readme.txt', - CBT_Theme_Readme::create( $theme ) - ); - - // Augment style.css - $css_contents = file_get_contents( get_stylesheet_directory() . '/style.css' ); - // Remove metadata from style.css file - $css_contents = trim( substr( $css_contents, strpos( $css_contents, '*/' ) + 2 ) ); - // Add new metadata - $css_contents = CBT_Theme_Styles::build_style_css( $theme ) . $css_contents; - $zip->addFromStringToTheme( - 'style.css', - $css_contents - ); - - // Add / replace screenshot. - if ( CBT_Theme_Utils::is_valid_screenshot( $screenshot ) ) { - $zip->addFileToTheme( - $screenshot['tmp_name'], - 'screenshot.png' - ); - } - - $zip->close(); - - header( 'Content-Type: application/zip' ); - header( 'Content-Disposition: attachment; filename=' . $theme['slug'] . '.zip' ); - header( 'Content-Length: ' . filesize( $filename ) ); - flush(); - echo readfile( $filename ); - die(); - } - - /** - * Clone the activated theme to create a new theme - */ - function clone_theme( $theme, $screenshot ) { - $theme_slug = CBT_Theme_Utils::get_theme_slug( $theme['name'] ); - - // Sanitize inputs. - $theme['name'] = sanitize_text_field( $theme['name'] ); - $theme['description'] = sanitize_text_field( $theme['description'] ); - $theme['uri'] = sanitize_text_field( $theme['uri'] ); - $theme['author'] = sanitize_text_field( $theme['author'] ); - $theme['author_uri'] = sanitize_text_field( $theme['author_uri'] ); - $theme['tags_custom'] = sanitize_text_field( $theme['tags_custom'] ); - $theme['image_credits'] = sanitize_textarea_field( $theme['image_credits'] ); - $theme['recommended_plugins'] = sanitize_textarea_field( $theme['recommended_plugins'] ); - $theme['font_credits'] = sanitize_textarea_field( $theme['font_credits'] ); - $theme['slug'] = $theme_slug; - $theme['template'] = ''; - $theme['text_domain'] = $theme_slug; - - // Use previous theme's tags if custom tags are empty. - if ( empty( $theme['tags_custom'] ) ) { - $theme['tags_custom'] = implode( ', ', $this->theme->get( 'Tags' ) ); - } - - // Create ZIP file in the temporary directory. - $filename = tempnam( get_temp_dir(), $theme['slug'] ); - $zip = CBT_Theme_Zip::create_zip( $filename ); - - $zip = CBT_Theme_Zip::copy_theme_to_zip( $zip, $theme['slug'], $theme['name'] ); - - $zip = CBT_Theme_Zip::add_templates_to_zip( $zip, 'all', $theme['slug'] ); - $zip = CBT_Theme_Zip::add_theme_json_to_zip( $zip, CBT_Theme_JSON_Resolver::export_theme_data( 'all' ) ); - - // Add readme.txt. - $zip->addFromStringToTheme( - 'readme.txt', - CBT_Theme_Readme::create( $theme ) - ); - - // Augment style.css - $css_contents = file_get_contents( get_stylesheet_directory() . '/style.css' ); - // Remove metadata from style.css file - $css_contents = trim( substr( $css_contents, strpos( $css_contents, '*/' ) + 2 ) ); - // Add new metadata - $css_contents = CBT_Theme_Styles::build_style_css( $theme ) . $css_contents; - $zip->addFromStringToTheme( - 'style.css', - $css_contents - ); - - // Add / replace screenshot. - if ( CBT_Theme_Utils::is_valid_screenshot( $screenshot ) ) { - $zip->addFileToTheme( - $screenshot['tmp_name'], - 'screenshot.png' - ); - } - - $zip->close(); - - header( 'Content-Type: application/zip' ); - header( 'Content-Disposition: attachment; filename=' . $theme['slug'] . '.zip' ); - header( 'Content-Length: ' . filesize( $filename ) ); - flush(); - readfile( $filename ); - unlink( $filename ); - exit; - } - - /** - * Create a child theme of the activated theme - */ - function create_child_theme( $theme, $screenshot ) { - $parent_theme_slug = CBT_Theme_Utils::get_theme_slug( $this->theme->get( 'Name' ) ); - $child_theme_slug = CBT_Theme_Utils::get_theme_slug( $theme['name'] ); - - // Sanitize inputs. - $theme['name'] = sanitize_text_field( $theme['name'] ); - $theme['description'] = sanitize_text_field( $theme['description'] ); - $theme['uri'] = sanitize_text_field( $theme['uri'] ); - $theme['author'] = sanitize_text_field( $theme['author'] ); - $theme['author_uri'] = sanitize_text_field( $theme['author_uri'] ); - $theme['tags_custom'] = sanitize_text_field( $theme['tags_custom'] ); - $theme['image_credits'] = sanitize_textarea_field( $theme['image_credits'] ); - $theme['recommended_plugins'] = sanitize_textarea_field( $theme['recommended_plugins'] ); - $theme['font_credits'] = sanitize_textarea_field( $theme['font_credits'] ); - $theme['is_child_theme'] = true; - $theme['text_domain'] = $child_theme_slug; - $theme['template'] = $parent_theme_slug; - $theme['slug'] = $child_theme_slug; - - // Create ZIP file in the temporary directory. - $filename = tempnam( get_temp_dir(), $theme['slug'] ); - $zip = CBT_Theme_Zip::create_zip( $filename ); - - $zip = CBT_Theme_Zip::add_templates_to_zip( $zip, 'user', $theme['slug'] ); - $zip = CBT_Theme_Zip::add_theme_json_to_zip( $zip, CBT_Theme_JSON_Resolver::export_theme_data( 'user' ) ); - - // Add readme.txt. - $zip->addFromStringToTheme( - 'readme.txt', - CBT_Theme_Readme::create( $theme ) - ); - - // Add style.css. - $zip->addFromStringToTheme( - 'style.css', - CBT_Theme_Styles::build_style_css( $theme ) - ); - - // Add / replace screenshot. - if ( CBT_Theme_Utils::is_valid_screenshot( $screenshot ) ) { - $zip->addFileToTheme( - $screenshot['tmp_name'], - 'screenshot.png' - ); - } - - $zip->close(); - - header( 'Content-Type: application/zip' ); - header( 'Content-Disposition: attachment; filename=' . $theme['slug'] . '.zip' ); - header( 'Content-Length: ' . filesize( $filename ) ); - flush(); - echo readfile( $filename ); - die(); - } - - /** - * Export activated parent theme - */ - function export_theme( $theme ) { - $theme['slug'] = $this->theme->get( 'TextDomain' ); - - // Create ZIP file in the temporary directory. - $filename = tempnam( get_temp_dir(), $theme['slug'] ); - $zip = CBT_Theme_Zip::create_zip( $filename ); - - $zip = CBT_Theme_Zip::copy_theme_to_zip( $zip, null, null ); - $zip = CBT_Theme_Zip::add_templates_to_zip( $zip, 'all', null ); - $zip = CBT_Theme_Zip::add_theme_json_to_zip( $zip, CBT_Theme_JSON_Resolver::export_theme_data( 'all' ) ); - - $zip->close(); - - header( 'Content-Type: application/zip' ); - header( 'Content-Disposition: attachment; filename=' . $theme['slug'] . '.zip' ); - header( 'Content-Length: ' . filesize( $filename ) ); - flush(); - echo readfile( $filename ); - die(); - } - - function create_blank_theme( $theme, $screenshot ) { - $theme_slug = CBT_Theme_Utils::get_theme_slug( $theme['name'] ); - - // Sanitize inputs. - $theme['name'] = sanitize_text_field( $theme['name'] ); - $theme['description'] = sanitize_text_field( $theme['description'] ); - $theme['uri'] = sanitize_text_field( $theme['uri'] ); - $theme['author'] = sanitize_text_field( $theme['author'] ); - $theme['author_uri'] = sanitize_text_field( $theme['author_uri'] ); - $theme['tags_custom'] = sanitize_text_field( $theme['tags_custom'] ); - $theme['image_credits'] = sanitize_textarea_field( $theme['image_credits'] ); - $theme['recommended_plugins'] = sanitize_textarea_field( $theme['recommended_plugins'] ); - $theme['font_credits'] = sanitize_textarea_field( $theme['font_credits'] ); - $theme['template'] = ''; - $theme['slug'] = $theme_slug; - $theme['text_domain'] = $theme_slug; - - // Create theme directory. - $source = plugin_dir_path( __DIR__ ) . 'assets/boilerplate'; - $blank_theme_path = get_theme_root() . DIRECTORY_SEPARATOR . $theme['slug']; - if ( ! file_exists( $blank_theme_path ) ) { - wp_mkdir_p( $blank_theme_path ); - // Add readme.txt. - file_put_contents( - $blank_theme_path . DIRECTORY_SEPARATOR . 'readme.txt', - CBT_Theme_Readme::create( $theme ) - ); - - // Add new metadata. - $css_contents = CBT_Theme_Styles::build_style_css( $theme ); - - // Add style.css. - file_put_contents( - $blank_theme_path . DIRECTORY_SEPARATOR . 'style.css', - $css_contents - ); - - $iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator( $source, \RecursiveDirectoryIterator::SKIP_DOTS ), - \RecursiveIteratorIterator::SELF_FIRST - ); - - foreach ( - $iterator as $item - ) { - if ( $item->isDir() ) { - wp_mkdir_p( $blank_theme_path . DIRECTORY_SEPARATOR . $iterator->getSubPathname() ); - } else { - copy( $item, $blank_theme_path . DIRECTORY_SEPARATOR . $iterator->getSubPathname() ); - } - } - - // Overwrite default screenshot if one is provided. - if ( CBT_Theme_Utils::is_valid_screenshot( $screenshot ) ) { - file_put_contents( - $blank_theme_path . DIRECTORY_SEPARATOR . 'screenshot.png', - file_get_contents( $screenshot['tmp_name'] ) - ); - } - - if ( ! defined( 'IS_GUTENBERG_PLUGIN' ) ) { - global $wp_version; - $theme_json_version = 'wp/' . substr( $wp_version, 0, 3 ); - $schema = '"$schema": "https://schemas.wp.org/' . $theme_json_version . '/theme.json"'; - $theme_json_path = $blank_theme_path . DIRECTORY_SEPARATOR . 'theme.json'; - $theme_json_string = file_get_contents( $theme_json_path ); - $theme_json_string = str_replace( '"$schema": "https://schemas.wp.org/trunk/theme.json"', $schema, $theme_json_string ); - file_put_contents( $theme_json_path, $theme_json_string ); - } - } - } - - function blockbase_save_theme() { - if ( ! empty( $_GET['page'] ) && 'create-block-theme' === $_GET['page'] && ! empty( $_POST['theme'] ) ) { - - // Check user capabilities. - if ( ! current_user_can( 'edit_theme_options' ) ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - - // Check nonce - if ( ! wp_verify_nonce( $_POST['nonce'], 'create_block_theme' ) ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - - if ( 'save' === $_POST['theme']['type'] ) { - // Avoid running if WordPress dosn't have permission to overwrite the theme folder - if ( ! wp_is_writable( get_stylesheet_directory() ) ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_file_permissions' ) ); - } - - if ( is_child_theme() ) { - $this->save_theme_locally( 'current' ); - } else { - $this->save_theme_locally( 'all' ); - } - CBT_Theme_Styles::clear_user_styles_customizations(); - CBT_Theme_Templates::clear_user_templates_customizations(); - - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_save_success' ) ); - } elseif ( 'variation' === $_POST['theme']['type'] ) { - if ( '' === $_POST['theme']['variation'] ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_variation_name' ) ); - } - - // Avoid running if WordPress dosn't have permission to write the theme folder - if ( ! wp_is_writable( get_stylesheet_directory() ) ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_file_permissions' ) ); - } - - if ( is_child_theme() ) { - $this->save_variation( 'current', $_POST['theme'] ); - } else { - $this->save_variation( 'all', $_POST['theme'] ); - } - CBT_Theme_Styles::clear_user_styles_customizations(); - - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_variation_success' ) ); - } elseif ( 'blank' === $_POST['theme']['type'] ) { - // Avoid running if WordPress dosn't have permission to write the themes folder - if ( ! wp_is_writable( get_theme_root() ) ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_themes_file_permissions' ) ); - } - - if ( '' === $_POST['theme']['name'] ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - $this->create_blank_theme( $_POST['theme'], $_FILES['screenshot'] ); - - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_blank_success' ) ); - } elseif ( ! class_exists( 'ZipArchive' ) ) { - // Avoid running if ZipArchive is not enabled. - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_unsupported_zip_archive' ) ); - } elseif ( is_child_theme() ) { - if ( 'sibling' === $_POST['theme']['type'] ) { - if ( '' === $_POST['theme']['name'] ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - $this->create_sibling_theme( $_POST['theme'], $_FILES['screenshot'] ); - } else { - $this->export_child_theme( $_POST['theme'] ); - } - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_export_success' ) ); - } else { - if ( 'child' === $_POST['theme']['type'] ) { - if ( '' === $_POST['theme']['name'] ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - $this->create_child_theme( $_POST['theme'], $_FILES['screenshot'] ); - } elseif ( 'clone' === $_POST['theme']['type'] ) { - if ( '' === $_POST['theme']['name'] ) { - return add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_error_theme_name' ) ); - } - $this->clone_theme( $_POST['theme'], $_FILES['screenshot'] ); - } else { - $this->export_theme( $_POST['theme'] ); - } - add_action( 'admin_notices', array( 'CBT_Form_Messages', 'admin_notice_export_success' ) ); - } - } - } -} diff --git a/admin/css/form.css b/admin/css/form.css deleted file mode 100644 index e4904377..00000000 --- a/admin/css/form.css +++ /dev/null @@ -1,93 +0,0 @@ -.appearance_page_create-block-theme h2 { - margin-bottom: 0; -} - -.appearance_page_create-block-theme p.description { - margin-bottom: 1rem; -} - -.appearance_page_create-block-theme .submit { - clear: both; -} - -#col-left label, -.theme-form label, -.theme-form legend { - font-weight: 600; -} - -.theme-tag-form-control label { - font-weight: 400; -} - -.theme-form label { - display: block; - margin-bottom: 0.25rem; -} - -/* Theme Tag Checkboxes */ -.theme-tags { - display: grid; - margin-top: 0.5rem; -} - -.theme-tags fieldset { - margin-bottom: 1rem; -} - -.theme-tags legend { - margin-bottom: 1rem; -} - -.theme-tags label { - display: inline-block; - margin-left: 0.25rem; - margin-bottom: 0.25rem; -} - -#features-tags { - display: grid; -} - -.theme-tag-form-control { - margin-bottom: 0.5rem; -} - -@media screen and (min-width: 600px) { - .theme-tags { - grid-template-columns: 1fr 1fr; - } - - /* Feature tags have items than other categores, so display the list in 2 columns on wider screens. */ - #features-tags { - grid-template-columns: 1fr 1fr; - grid-column: 1 / 3; - margin-top: 1rem; - } -} - -@media screen and (min-width: 783px) { - .theme-tags fieldset { - margin-bottom: 0.5rem; - } - - .theme-tags legend { - margin-bottom: 0.5rem; - } - - /* Checkboxes shrink to standard size. */ - .theme-tag-form-control { - margin-bottom: 0; - } -} - -@media screen and (min-width: 1440px) { - .theme-tags { - grid-template-columns: 1fr 1fr 1fr 1fr; - } - - #features-tags { - grid-column: 3 / 5; - margin-top: 0; - } -} diff --git a/admin/index.php b/admin/index.php deleted file mode 100644 index 8142269b..00000000 --- a/admin/index.php +++ /dev/null @@ -1 +0,0 @@ - { - form.toggleAttribute( 'hidden', true ); - } ); -} - -// Handle theme tag validation -function validateThemeTags( tagCategory ) { - if ( ! tagCategory ) return; - let checkboxes; - - if ( 'subject' === tagCategory ) { - checkboxes = 'input[name="theme[tags-subject][]"]'; - } - - // Maximum number of checkboxes that can be selected - const max = 3; - - // Run validation on form load - limitCheckboxSelection( checkboxes, max ); - - const allCheckboxes = document.querySelectorAll( checkboxes ); - - // Run validation on each checkbox change - if ( allCheckboxes.length > max ) { - for ( let i = 0; i < allCheckboxes.length; i++ ) { - allCheckboxes[ i ].addEventListener( 'change', function () { - limitCheckboxSelection( checkboxes, max ); - } ); - } - } -} - -// Takes a checkbox selector and limits the number of checkboxes that can be selected -function limitCheckboxSelection( checkboxesSelector, max = 0 ) { - if ( ! checkboxesSelector ) return; - - const checked = document.querySelectorAll( - `${ checkboxesSelector }:checked` - ); - const unchecked = document.querySelectorAll( - `${ checkboxesSelector }:not(:checked)` - ); - - if ( checked.length >= max ) { - for ( let i = 0; i < unchecked.length; i++ ) { - unchecked[ i ].setAttribute( 'disabled', true ); - } - } else { - for ( let i = 0; i < unchecked.length; i++ ) { - unchecked[ i ].removeAttribute( 'disabled' ); - } - } -} - -// Store active theme tags when page is loaded -let activeThemeTags = []; -function onWindowLoad() { - activeThemeTags = document.querySelectorAll( - '.theme-tags input[type="checkbox"]:checked' - ); -} - -window.addEventListener( 'load', onWindowLoad ); -window.addEventListener( 'load', prepareThemeNameValidation ); - -function prepareThemeNameValidation() { - const themeNameInput = document.getElementById( 'theme-name' ); - if ( themeNameInput ) { - themeNameInput.addEventListener( 'input', validateThemeNameInput ); - } -} - -function slugify( text ) { - // Removes spaces - return text.toLowerCase().replace( / /g, '' ); -} - -function slugifyUnderscores( text ) { - // Replaces spaces with underscores - return text.toLowerCase().replace( / /g, '_' ); -} - -function slugifyDashes( text ) { - // Replaces spaces with dashes - return text.toLowerCase().replace( / /g, '-' ); -} - -function slugifyNoDashes( text ) { - // Removes spaces, dashes, and underscores - return text.toLowerCase().replace( / /g, '' ).replace( /[-_]/g, '' ); -} - -const ERROR_NAME_NOT_AVAILABLE = __( - 'Theme name is not available in the WordPress.org theme directory', - 'create-block-theme' -); -const ERROR_NAME_CONTAINS_THEME = __( - 'Theme name cannot contain the word "theme"', - 'create-block-theme' -); -const ERROR_NAME_CONTAINS_WORDPRESS = __( - 'Theme name cannot contain the word "WordPress"', - 'create-block-theme' -); - -function isThemeNameValid( themeName ) { - // Check the validity of the theme name following the WordPress.org theme directory rules - // https://meta.svn.wordpress.org/sites/trunk/wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php - - /* eslint-disable @wordpress/no-unused-vars-before-return */ - const lowerCaseName = themeName.toLowerCase(); - const slug = slugify( themeName ); - const slugDashes = slugifyUnderscores( themeName ); - const slugUnderscores = slugifyDashes( themeName ); - const slugNoDashes = slugifyNoDashes( themeName ); - - const validityStatus = { - isValid: true, - errorMessage: '', - }; - - // Check if the theme contains the word theme - if ( lowerCaseName.includes( 'theme' ) ) { - validityStatus.isValid = false; - validityStatus.errorMessage = ERROR_NAME_CONTAINS_THEME; - return validityStatus; - } - - // Check if the theme name contains WordPress - if ( slugNoDashes.includes( 'wordpress' ) ) { - validityStatus.isValid = false; - validityStatus.errorMessage = ERROR_NAME_CONTAINS_WORDPRESS; - return validityStatus; - } - - // Check if the theme name is available - const isNameAvailable = () => { - // default to empty array if the unavailable theme names are not loaded yet from the API - const notAvailableSlugs = window.wpOrgThemeDirectory.themeSlugs || []; - - // Compare the theme name to the list of unavailable theme names using several different slug formats - return ! notAvailableSlugs.some( - ( s ) => - s === slug || - s === slugDashes || - s === slugUnderscores || - slugifyNoDashes( s ) === slugNoDashes - ); - }; - - if ( ! isNameAvailable() ) { - validityStatus.isValid = false; - validityStatus.errorMessage = ERROR_NAME_NOT_AVAILABLE; - return validityStatus; - } - - return validityStatus; -} - -function validateThemeNameInput() { - const themeName = this?.value; - if ( ! themeName ) return true; - - // Check if theme name is available - const validityStatus = isThemeNameValid( themeName ); - - if ( ! validityStatus.isValid ) { - this.setCustomValidity( validityStatus.errorMessage ); - this.reportValidity(); - } else { - this.setCustomValidity( '' ); - } -} - -// Resets all theme tag states (checked, disabled) to default values -function resetThemeTags( themeType ) { - // Clear all checkboxes - const allCheckboxes = document.querySelectorAll( - '.theme-tags input[type="checkbox"]' - ); - allCheckboxes.forEach( ( checkbox ) => { - checkbox.checked = false; - checkbox.removeAttribute( 'disabled' ); - } ); - - // Recheck default tags - const defaultTags = document.querySelectorAll( - '.theme-tags input[type="checkbox"].default-tag' - ); - defaultTags.forEach( ( checkbox ) => { - checkbox.checked = true; - } ); - - if ( 'blank' !== themeType ) { - // Recheck active theme tags - if ( ! activeThemeTags ) return; - - activeThemeTags.forEach( ( checkbox ) => { - checkbox.checked = true; - } ); - } -} - -function resetThemeName() { - const themeNameInput = document.getElementById( 'theme-name' ); - themeNameInput.value = ''; - themeNameInput.setCustomValidity( '' ); -} diff --git a/admin/wp-org-theme-directory.php b/admin/wp-org-theme-directory.php deleted file mode 100644 index bcb77f1a..00000000 --- a/admin/wp-org-theme-directory.php +++ /dev/null @@ -1,77 +0,0 @@ - 'GET', - 'callback' => array( 'CBT_WP_Theme_Directory', 'get_theme_names' ), - 'permission_callback' => function () { - return current_user_can( 'edit_theme_options' ); - }, - ) - ); - - } - - public static function get_theme_names() { - $html = wp_safe_remote_get( self::THEME_NAMES_ENDPOINT ); - - if ( is_wp_error( $html ) ) { - return $html; - } - - // parse the html response extracting all the a inside li elements - $pattern = '/
{ errorMessage }
++ { createInterpolateElement( + __( + 'You can do everything from within the Editor but here are a few things you can do to get started.', + 'create-block-theme' + ), + { + a: ( + // eslint-disable-next-line jsx-a11y/anchor-has-content + + ), + } + ) } +
+ ++ { __( + 'Export a zip file ready to be imported into another WordPress environment.', + 'create-block-theme' + ) } +
+ ++ { __( + 'Start from scratch! Create a blank theme to get started with your own design ideas.', + 'create-block-theme' + ) } +
+ ++ { __( + 'Use the currently activated theme as a starting point.', + 'create-block-theme' + ) } +
+ ++ { __( + 'Make a theme that uses the currently activated theme as a parent.', + 'create-block-theme' + ) } +
++ { __( + "Create Block Theme is a tool to help you make Block Themes using the WordPress Editor. It does this by adding tools to the Editor to help you create and manage your theme. Themes created with Create Block Theme don't require Create Block Theme to be installed on the site where the theme is used.", + 'create-block-theme' + ) } +
+
+ { createInterpolateElement(
+ __(
+ 'Have a question? Ask for some help in the
+ { createInterpolateElement(
+ __(
+ 'Found a bug? Report it on
+ { createInterpolateElement(
+ __(
+ 'Want to contribute? Check out the
+ { __( + 'There is a new panel accessible from the WordPress Editor which you can open by clicking on a new icon to the right of the “Save” button, at the top of the Editor.', + 'create-block-theme' + ) } +
+ ++ { __( + 'In the Create Block Theme Panel click "Save Changes to Theme". You will be presented with a number of options of which things you want to be saved to your theme. Make your choices and then click "Save Changes".', + 'create-block-theme' + ) } +
+ ++ { __( + 'First Install and activate a font from any source using the WordPress Font Library. Then, using the Create Block Theme Panel select “Save Changes To Theme” and select “Save Fonts” before saving the theme. All of the active fonts will be activated in the theme and deactivated in the system (and may be safely deleted from the system). Any fonts that are installed in the theme that have been deactivated with the WordPress Font Library will be removed from the theme.', + 'create-block-theme' + ) } +
+ +