Skip to content

Commit

Permalink
Add "Recommended Plugins" input box (#402)
Browse files Browse the repository at this point in the history
Co-authored-by: Jason Crist <jcrist@pbking.com>
  • Loading branch information
mikachan and pbking authored Jun 23, 2023
1 parent 161363c commit b5c1f5b
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 121 deletions.
88 changes: 46 additions & 42 deletions admin/class-create-theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,17 @@ function create_sibling_theme( $theme, $screenshot ) {
$theme_slug = 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['slug'] = $theme_slug;
$theme['template'] = wp_get_theme()->get( 'Template' );
$theme['text_domain'] = $theme_slug;
$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['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'] );
Expand Down Expand Up @@ -164,17 +165,18 @@ function clone_theme( $theme, $screenshot ) {
$theme_slug = 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['slug'] = $theme_slug;
$theme['template'] = '';
$theme['original_theme'] = wp_get_theme()->get( 'Name' );
$theme['text_domain'] = $theme_slug;
$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['slug'] = $theme_slug;
$theme['template'] = '';
$theme['original_theme'] = wp_get_theme()->get( 'Name' );
$theme['text_domain'] = $theme_slug;

// Use previous theme's tags if custom tags are empty.
if ( empty( $theme['tags_custom'] ) ) {
Expand Down Expand Up @@ -235,17 +237,18 @@ function create_child_theme( $theme, $screenshot ) {
$child_theme_slug = 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['is_parent_theme'] = true;
$theme['text_domain'] = $child_theme_slug;
$theme['template'] = $parent_theme_slug;
$theme['slug'] = $child_theme_slug;
$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['is_parent_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'] );
Expand Down Expand Up @@ -312,16 +315,17 @@ function create_blank_theme( $theme, $screenshot ) {
$theme_slug = 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['template'] = '';
$theme['slug'] = $theme_slug;
$theme['text_domain'] = $theme_slug;
$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['template'] = '';
$theme['slug'] = $theme_slug;
$theme['text_domain'] = $theme_slug;

// Create theme directory.
$source = plugin_dir_path( __DIR__ ) . 'assets/boilerplate';
Expand Down
24 changes: 23 additions & 1 deletion admin/create-theme/theme-form.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public static function create_admin_form_page() {
<input type="file" accept=".png" name="screenshot" id="screenshot" class="upload"/>
</label>
<br /><br />
<label id="image_credits_input">
<label class="hide-on-blank-theme">
<?php _e( 'Image Credits:', 'create-block-theme' ); ?><br />
<small><?php _e( 'List the credits for each image you have included in the theme. Include the image name, license type, and source URL.', 'create-block-theme' ); ?></small><br />
<small>
Expand All @@ -186,6 +186,28 @@ public static function create_admin_form_page() {
<textarea placeholder="<?php echo $image_credits_placeholder; ?>" rows="4" cols="50" name="theme[image_credits]" class="large-text"></textarea>
<br /><br />
</label>
<label class="hide-on-blank-theme">
<?php _e( 'Recommended Plugins:', 'create-block-theme' ); ?><br />
<small>
<?php
printf(
/* Translators: Recommended plugins link. */
esc_html__( 'List the recommended plugins for this theme. e.g. contact forms, social media. Plugins must be from the WordPress.org plugin repository (%s).', 'create-block-theme' ),
'<a href="' . esc_url( __( 'https://make.wordpress.org/themes/handbook/review/required/#6-plugins', 'create-block-theme' ) ) . '" target="_blank">read more</a>'
);
?>
</small><br />
<?php
$recommended_plugins_placeholder = __(
'Plugin Name
https://wordpress.org/plugins/plugin-name/
Plugin Description',
'create-block-theme'
);
?>
<textarea placeholder="<?php echo $recommended_plugins_placeholder; ?>" rows="4" cols="50" name="theme[recommended_plugins]" class="large-text"></textarea>
<br /><br />
</label>
<div>
<?php Theme_Tags::theme_tags_section(); ?>
</div>
Expand Down
188 changes: 142 additions & 46 deletions admin/create-theme/theme-readme.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,28 @@ class Theme_Readme {
* Build a readme.txt file for CHILD/GRANDCHILD themes.
*/
public static function build_readme_txt( $theme ) {
$slug = $theme['slug'];
$name = $theme['name'];
$description = $theme['description'];
$uri = $theme['uri'];
$author = $theme['author'];
$author_uri = $theme['author_uri'];
$copy_year = gmdate( 'Y' );
$wp_version = get_bloginfo( 'version' );
$image_credits = $theme['image_credits'] ?? '';
$is_parent_theme = $theme['is_parent_theme'] ?? false;
$original_theme = $theme['original_theme'] ?? '';
$slug = $theme['slug'];
$name = $theme['name'];
$description = $theme['description'];
$uri = $theme['uri'];
$author = $theme['author'];
$author_uri = $theme['author_uri'];
$copy_year = gmdate( 'Y' );
$wp_version = get_bloginfo( 'version' );
$image_credits = $theme['image_credits'] ?? '';
$recommended_plugins = $theme['recommended_plugins'] ?? '';
$is_parent_theme = $theme['is_parent_theme'] ?? false;
$original_theme = $theme['original_theme'] ?? '';

// Handle copyright section.
$new_copyright_section = $is_parent_theme || $original_theme ? true : false;
$original_theme_credits = $new_copyright_section ? self::original_theme_credits( $name, $is_parent_theme ) : '';
$copyright_section = self::copyright_section( $new_copyright_section, $original_theme_credits, $name, $copy_year, $author, $image_credits );

$default_copyright_section = "== Copyright ==
{$name} WordPress Theme, (C) {$copy_year} {$author}
{$name} is distributed under the terms of the GNU GPL.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.";

$copyright_section = $new_copyright_section ? self::copyright_section( $original_theme_credits, $image_credits ) : $default_copyright_section;
// Handle recommended plugins section.
if ( $recommended_plugins ) {
$recommended_plugins_section = self::recommended_plugins_section( $recommended_plugins );
}

return "=== {$name} ===
Contributors: {$author}
Expand All @@ -52,7 +44,7 @@ public static function build_readme_txt( $theme ) {
= 0.0.1 =
* Initial release
{$recommended_plugins_section}
{$copyright_section}
";
}
Expand Down Expand Up @@ -132,34 +124,138 @@ static function original_theme_credits( $new_name, $is_parent_theme = false ) {
*
* @return string
*/
static function copyright_section( $original_theme_credits, $image_credits ) {
$copyright_section = '';
$copyright_section_intro = '== Copyright ==';
static function copyright_section( $new_copyright_section, $original_theme_credits, $name, $copy_year, $author, $image_credits ) {
// Default copyright section.
$copyright_section = "== Copyright ==
// Get current theme readme.txt
$current_readme = get_stylesheet_directory() . '/readme.txt' ?? '';
$current_readme_content = file_exists( $current_readme ) ? file_get_contents( $current_readme ) : '';
{$name} WordPress Theme, (C) {$copy_year} {$author}
{$name} is distributed under the terms of the GNU GPL.
if ( ! $current_readme_content ) {
return;
}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
// Copy copyright section from current theme readme.txt
if ( str_contains( $current_readme_content, $copyright_section_intro ) ) {
$copyright_section_start = strpos( $current_readme_content, $copyright_section_intro );
$copyright_section = substr( $current_readme_content, $copyright_section_start );
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.";

// If a new copyright section is required, then build ones based on the current theme.
if ( $new_copyright_section ) {
$copyright_section_intro = '== Copyright ==';

// Get current theme readme.txt
$current_readme = get_stylesheet_directory() . '/readme.txt' ?? '';
$current_readme_content = file_exists( $current_readme ) ? file_get_contents( $current_readme ) : '';

if ( $original_theme_credits ) {
$new_copyright_section = str_replace( $copyright_section_intro . "\n", '', $copyright_section );
$copyright_section = $copyright_section_intro . "\n\n" . $original_theme_credits . "\n" . $new_copyright_section;
if ( ! $current_readme_content ) {
return;
}

if ( $image_credits ) {
$copyright_section = $copyright_section . "\n" . $image_credits;
// Copy copyright section from current theme readme.txt
if ( str_contains( $current_readme_content, $copyright_section_intro ) ) {
$copyright_section_start = strpos( $current_readme_content, $copyright_section_intro );
$copyright_section = substr( $current_readme_content, $copyright_section_start );

if ( $original_theme_credits ) {
$new_copyright_section = str_replace( $copyright_section_intro . "\n", '', $copyright_section );
$copyright_section = $copyright_section_intro . "\n\n" . $original_theme_credits . "\n" . $new_copyright_section;
}
}
}

if ( $image_credits ) {
$copyright_section = $copyright_section . "\n" . $image_credits;
}

return $copyright_section;
}

/**
* Build Recommended Plugins section.
*
* @return string
*/
static function recommended_plugins_section( $recommended_plugins, $updated_readme = '' ) {
$recommended_plugins_section = '';

if ( ! $recommended_plugins ) {
return '';
}

$section_start = "\n== Recommended Plugins ==\n";

// Remove existing Recommended Plugins section.
if ( $updated_readme && str_contains( $updated_readme, $section_start ) ) {
$pattern = '/\s+== Recommended Plugins ==\s+(.*?)(?=(\n\=\=)|$)/s';
preg_match_all( $pattern, $updated_readme, $matches );
$current_section = $matches[0][0];
$updated_readme = str_replace( $current_section, '', $updated_readme );
}

$recommended_plugins_section = $section_start . "\n" . $recommended_plugins . "\n";

if ( $updated_readme ) {
return $updated_readme . $recommended_plugins_section;
}

return $recommended_plugins_section;
}

/**
* Update current readme.txt file, rather than building a new one.
*
* @return string
*/
public static function update_readme_txt( $theme ) {
$description = $theme['description'];
$author = $theme['author'];
$wp_version = get_bloginfo( 'version' );
$image_credits = $theme['image_credits'] ?? '';
$recommended_plugins = $theme['recommended_plugins'] ?? '';
$updated_readme = '';
$current_readme = get_stylesheet_directory() . '/readme.txt' ?? '';
$readme_content = file_exists( $current_readme ) ? file_get_contents( $current_readme ) : '';

if ( ! $readme_content ) {
return;
}

$updated_readme = $readme_content;

// Update description.
if ( $description ) {
$pattern = '/(== Description ==)(.*?)(\n\n=|$)/s';
preg_match_all( $pattern, $updated_readme, $matches );
$current_description = $matches[0][0];
$updated_readme = str_replace( $current_description, "== Description ==\n\n{$description}\n\n=", $updated_readme );
}

// Update Author/Contributors.
if ( $author ) {
$pattern = '/(Contributors:)(.*?)(\n|$)/s';
preg_match_all( $pattern, $updated_readme, $matches );
$current_uri = $matches[0][0];
$updated_readme = str_replace( $current_uri, "Contributors: {$author}\n", $updated_readme );
}

// Update "Tested up to" version.
if ( $wp_version ) {
$pattern = '/(Tested up to:)(.*?)(\n|$)/s';
preg_match_all( $pattern, $updated_readme, $matches );
$current_uri = $matches[0][0];
$updated_readme = str_replace( $current_uri, "Tested up to: {$wp_version}\n", $updated_readme );
}

if ( $recommended_plugins ) {
$updated_readme = self::recommended_plugins_section( $recommended_plugins, $updated_readme );
}

if ( $image_credits ) {
$updated_readme = $updated_readme . "\n\n" . $image_credits;
}

return $updated_readme;
}
}
2 changes: 1 addition & 1 deletion admin/create-theme/theme-tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class Theme_Tags {
/**
* Build theme tags list for readme.txt.
* Build theme tags list for style.css.
*
* @param array $theme Theme data.
* @return string
Expand Down
Loading

0 comments on commit b5c1f5b

Please sign in to comment.