diff --git a/config/services/wp-console/generate.yml b/config/services/wp-console/generate.yml
index 25217be..5722a1c 100644
--- a/config/services/wp-console/generate.yml
+++ b/config/services/wp-console/generate.yml
@@ -82,5 +82,10 @@ services:
console.generate_cron_single:
class: WP\Console\Command\Generate\CronSingleCommand
arguments: ['@console.cron_base_generator', '@console.extension_manager', '@console.validator', '@console.string_converter']
+ tags:
+ - { name: wordpress.command }
+ console.generate_settings_page:
+ class: WP\Console\Command\Generate\SettingsPageCommand
+ arguments: ['@console.settings_page_generator', '@console.extension_manager', '@console.validator', '@console.string_converter', '@console.wordpress_api']
tags:
- { name: wordpress.command }
\ No newline at end of file
diff --git a/config/services/wp-console/generator.yml b/config/services/wp-console/generator.yml
index e54486f..186e69b 100644
--- a/config/services/wp-console/generator.yml
+++ b/config/services/wp-console/generator.yml
@@ -70,5 +70,10 @@ services:
console.cron_base_generator:
class: WP\Console\Generator\CronBaseGenerator
arguments: ['@console.extension_manager']
+ tags:
+ - { name: wordpress.generator }
+ console.settings_page_generator:
+ class: WP\Console\Generator\SettingsPageGenerator
+ arguments: ['@console.extension_manager']
tags:
- { name: wordpress.generator }
\ No newline at end of file
diff --git a/config/translations/en/generate.settings.page.yml b/config/translations/en/generate.settings.page.yml
new file mode 100644
index 0000000..ae0d46d
--- /dev/null
+++ b/config/translations/en/generate.settings.page.yml
@@ -0,0 +1,49 @@
+description: 'Generate a new custom settings page.'
+help: 'The generate:settings:page command helps you generates a new Settings page.'
+welcome: 'Welcome to the Wordpress Settings page generator'
+options:
+ plugin: 'The Plugin name.'
+ class-name: 'The settings page function name'
+ setting-group: 'Name of the settings group used in register_setting'
+ setting-name: 'Name of the options saved in the database.'
+ page-title: 'Setting Page title'
+ menu-title: 'Admin sidebar menu title.'
+ capability: 'Access permission.'
+ slug: 'Unique slug for the admin page'
+ callback-function: 'The name of the layout function.'
+ section-field: 'Section to add fields.'
+ fields: 'Setting Page fields.'
+ text-domain: 'Translations file.'
+questions:
+ plugin: 'The plugin name'
+ class-name: 'Enter settings page class name'
+ setting-group: 'Enter the name of the settings group used in register_setting'
+ setting-name: 'Enter the name of the options saved in the database'
+ page-title: 'Enter the setting Page title'
+ menu-title: 'Enter the admin sidebar menu title'
+ capability: 'Choice the capability to give access permission'
+ slug: 'Enter the slug for the admin page'
+ callback-function: 'Enter the name of the layout function'
+ section-add: 'Do you want add section to fields'
+ section-name: 'Enter the name to the new section'
+ section-add-another: 'Do you want to add another section'
+ fields:
+ fields-add: 'Do you want to generate the fields'
+ type: 'Enter field type'
+ id: 'Enter field id'
+ label: 'Enter field label'
+ description: 'Enter field description'
+ placeholder: 'Enter field placeholder'
+ default-value: 'Enter field default value'
+ src_image: 'Enter the image path'
+ section-id: 'Choice the section to add the field'
+ fields-add-another: 'Do you want to add another field'
+ multiple-label: 'Enter the label for option for '
+ multiple-value: 'Enter the value for option for '
+ multiple-options-add: 'Do you want to add another option for '
+ text-domain: 'Enter the text-domain to translation file'
+warnings:
+ plugin-unavailable: 'Warning The following plugin are not already available in your local environment "%s"'
+errors:
+ directory-exists: 'The target directory "%s" is not empty.'
+ interval-invalid: 'The interval must be a number'
\ No newline at end of file
diff --git a/src/Command/Generate/SettingsPageCommand.php b/src/Command/Generate/SettingsPageCommand.php
new file mode 100644
index 0000000..86c365e
--- /dev/null
+++ b/src/Command/Generate/SettingsPageCommand.php
@@ -0,0 +1,380 @@
+generator = $generator;
+ $this->extensionManager = $extensionManager;
+ $this->validator = $validator;
+ $this->stringConverter = $stringConverter;
+ $this->wordpressApi = $wordpressApi;
+ parent::__construct();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('generate:settings:page')
+ ->setDescription($this->trans('commands.generate.settings.page.description'))
+ ->setHelp($this->trans('commands.generate.settings.page.help'))
+ ->addOption(
+ 'plugin',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.common.options.plugin')
+ )
+ ->addOption(
+ 'class-name',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.class-name')
+ )
+ ->addOption(
+ 'setting-group',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.setting-group')
+ )
+ ->addOption(
+ 'setting-name',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.setting-name')
+ )
+ ->addOption(
+ 'menu-title',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.menu-title')
+ )
+ ->addOption(
+ 'capability',
+ '',
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.user-capability')
+ )
+ ->addOption(
+ 'slug',
+ null,
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.slug')
+ )
+ ->addOption(
+ 'callback-function',
+ null,
+ InputOption::VALUE_REQUIRED,
+ $this->trans('commands.generate.settings.page.options.callback-function')
+ )
+ ->addOption(
+ 'page-title',
+ '',
+ InputOption::VALUE_OPTIONAL,
+ $this->trans('commands.generate.settings.page.options.page-title')
+ )
+ ->addOption(
+ 'sections',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ $this->trans('commands.generate.settings.page.options.section')
+ )
+ ->addOption(
+ 'fields',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ $this->trans('commands.generate.settings.page.options.fields')
+ )
+ ->addOption(
+ 'text-domain',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ $this->trans('commands.generate.settings.page.options.text-domain')
+ )
+ ->setAliases(['gsp']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new WPStyle($input, $output);
+
+ // @see use WP\Console\Command\Shared\ConfirmationTrait::confirmGeneration
+ if (!$this->confirmGeneration($io)) {
+ return;
+ }
+
+ $plugin = $plugin = $this->validator->validatePluginName($input->getOption('plugin'));
+ $class_name = $this->validator->validateClassName($input->getOption('class-name'));
+ $setting_group = $input->getOption('setting-group');
+ $setting_name = $input->getOption('setting-name');
+ $page_title = $input->getOption('page-title');
+ $menu_title = $input->getOption('menu-title');
+ $capability = $input->getOption('capability');
+ $slug = $input->getOption('slug');
+ $callback_function = $this->validator->validateFunctionName($input->getOption('callback-function'));
+ $sections= $input->getOption('sections');
+ $fields = $input->getOption('fields');
+ $text_domain = $input->getOption('text-domain');
+
+ $this->generator->generate(
+ $plugin,
+ $class_name,
+ $setting_group,
+ $setting_name,
+ $page_title,
+ $menu_title,
+ $capability,
+ $slug,
+ $callback_function,
+ $sections,
+ $fields,
+ $text_domain
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $io = new WPStyle($input, $output);
+
+ // --plugin
+ $plugin = $input->getOption('plugin');
+ if (!$plugin) {
+ $plugin = $this->pluginQuestion($io);
+ $input->setOption('plugin', $plugin);
+ }
+
+ // --class name
+ $class_name = $input->getOption('class-name');
+ if (!$class_name) {
+ $class_name = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.class-name'),
+ 'CustomSettingsPage',
+ function ($value) {
+ if (!strlen(trim($value))) {
+ throw new \Exception('The Class name can not be empty');
+ }
+ return $this->stringConverter->humanToCamelCase($value);
+ }
+ );
+ $input->setOption('class-name', $class_name);
+ }
+
+ // --setting group
+ $setting_group = $input->getOption('setting-group');
+ if (!$setting_group) {
+ $setting_group = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.setting-group'),
+ strtolower($class_name).'_group'
+ );
+ }
+ $input->setOption('setting-group', $setting_group);
+
+ // --setting name
+ $setting_name = $input->getOption('setting-name');
+ if (!$setting_name) {
+ $setting_name = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.setting-name'),
+ strtolower($class_name).'_name'
+ );
+ }
+ $input->setOption('setting-name', $setting_name);
+
+ // --capability
+ $capability = $input->getOption('capability');
+ if (!$capability) {
+ $capability = $io->choiceNoList(
+ $this->trans('commands.generate.settings.page.questions.capability'),
+ $this->wordpressApi->getCapabilities(),
+ "manage_options"
+ );
+ }
+ $input->setOption('capability', $capability);
+
+ // --slug
+ $slug = $input->getOption('slug');
+ if (!$slug) {
+ $slug = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.slug'),
+ $this->stringConverter->createMachineName($menu_title),
+ function ($value) {
+ return $this->stringConverter->createMachineName($value);
+ }
+ );
+ }
+ $input->setOption('slug', $slug);
+
+
+ // --callback function
+ $callback_function = $input->getOption('callback-function');
+ if (!$callback_function) {
+ $callback_function = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.callback-function'),
+ null,
+ function ($function) {
+ return $this->validator->validateFunctionName($function);
+ }
+ );
+ }
+ $input->setOption('callback-function', $callback_function);
+
+ // --menu title
+ $menu_title = $input->getOption('menu-title');
+ if (!$menu_title) {
+ $menu_title = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.menu-title'),
+ 'Custom Setting Page'
+ );
+ }
+ $input->setOption('menu-title', $menu_title);
+
+ // --page title
+ $page_title = $input->getOption('page-title');
+ if (!$page_title) {
+ $page_title = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.page-title'),
+ $menu_title
+ );
+ }
+ $input->setOption('page-title', $page_title);
+
+ // --sections
+ $sections = $input->getOption('sections');
+ if (!$sections) {
+ $sections = [];
+ if ($io->confirm(
+ $this->trans('commands.generate.settings.page.questions.section-add'),
+ true
+ )
+ ) {
+ $validate_menu = '';
+ while (true) {
+ $name = $io->ask(
+ $this->trans('commands.generate.settings.page.questions.section-name'),
+ 'My custom section settings',
+ function ($value) use ($validate_menu) {
+ if ($value == $validate_menu) {
+ throw new \Exception('The name already exist');
+ }
+ return $value;
+ }
+ );
+
+ if (empty($name)) {
+ break;
+ }
+
+ $validate_menu = $name;
+
+ $sections[$this->stringConverter->createMachineName($name)] = $name;
+
+ if (!$io->confirm(
+ $this->trans('commands.generate.settings.page.questions.section-add-another'),
+ false
+ )
+ ) {
+ break;
+ }
+ }
+ }
+ }
+ $input->setOption('sections', $sections);
+
+ // --fields
+ $fields = $input->getOption('fields');
+ if (!empty($sections)) {
+ if (!$fields) {
+ if ($io->confirm(
+ $this->trans('commands.generate.settings.page.questions.fields.fields-add'),
+ true
+ )
+ ) {
+ // @see \WP\Console\Command\Shared\FieldsTypeTrait::fieldsQuestion
+ $fields = $this->fieldsQuestion($io, 'settings.page', 'fields', $sections);
+ $input->setOption('fields', $fields);
+ }
+ }
+ }
+
+ // --text domain
+ $text_domain = $input->getOption('text-domain');
+ if (!$text_domain) {
+ $text_domain = $io->askEmpty(
+ $this->trans('commands.generate.settings.page.questions.text-domain')
+ );
+ }
+ $input->setOption('text-domain', $text_domain);
+ }
+}
diff --git a/src/Command/Shared/FieldsTypeTrait.php b/src/Command/Shared/FieldsTypeTrait.php
index 972d37f..83b7685 100644
--- a/src/Command/Shared/FieldsTypeTrait.php
+++ b/src/Command/Shared/FieldsTypeTrait.php
@@ -17,7 +17,7 @@
trait FieldsTypeTrait
{
- public function fieldsQuestion(WPStyle $io, $command)
+ public function fieldsQuestion(WPStyle $io, $command, $optionName, $sections = null)
{
$stringConverter = $this->stringConverter;
@@ -27,7 +27,7 @@ public function fieldsQuestion(WPStyle $io, $command)
$count = 0;
while (true) {
$type = $io->choiceNoList(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.type'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.type'),
$fields_options,
NULL,
TRUE
@@ -38,12 +38,12 @@ public function fieldsQuestion(WPStyle $io, $command)
}
$label = $io->ask(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.label'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.label'),
null
);
$id = $io->ask(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.id'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.id'),
$this->stringConverter->createMachineName($label),
function ($id) use ($stringConverter) {
return $stringConverter->createMachineName($id);
@@ -51,7 +51,7 @@ function ($id) use ($stringConverter) {
);
$description = $io->askEmpty(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.description')
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.description')
);
array_push(
@@ -66,36 +66,38 @@ function ($id) use ($stringConverter) {
if ($type != 'select' && $type != 'radio' && $type != 'checkbox') {
$placeholder = $io->askEmpty(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.placeholder')
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.placeholder')
);
$default_value = $io->askEmpty(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.default-value')
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.default-value')
);
$fields[$count]['placeholder'] = $placeholder;
$fields[$count]['default_value'] = $default_value;
}
- if ($type == 'select' || $type == 'radio' || $type == 'checkbox') {
- if ($io->confirm(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.multiple-options', $type),
- false
- )
- ) {
- $fields[$count]['multi_selection'] = $this->multiSelection($io, $type, $command);
- }
+ if ($type == 'select' || $type == 'radio') {
+ $fields[$count]['multi_selection'] = $this->multiSelection($io, $type, $command, $optionName);
}
if ($type == 'image') {
$src = $io->ask(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.src')
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.src')
);
$fields[$count]['src_image'] = $src;
}
+ if ($command == 'settings.page') {
+ $section_id = $io->choice(
+ $this->trans('commands.generate.settings.page.questions.fields.section-id'),
+ array_values($sections)
+ );
+ $fields[$count]['section_id'] = array_search($section_id, $sections);
+ }
+
if (!$io->confirm(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.'.$command.'-add-another'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.'.$optionName.'-add-another'),
false
)
) {
@@ -107,18 +109,18 @@ function ($id) use ($stringConverter) {
return $fields;
}
- private function multiSelection(WPStyle $io, $type, $command)
+ private function multiSelection(WPStyle $io, $type, $command, $optionName)
{
$multiple_options = [];
while (true) {
$multiple_options_label = $io->ask(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.multiple-label'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.multiple-label').$type,
''
);
$multiple_options_value = $io->ask(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.multiple-value'),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.multiple-value').$type,
''
);
@@ -130,7 +132,7 @@ private function multiSelection(WPStyle $io, $type, $command)
]
);
if (!$io->confirm(
- $this->trans('commands.generate.'.$command.'.questions.'.$command.'-items.multiple-options-add', $type),
+ $this->trans('commands.generate.'.$command.'.questions.'.$optionName.'.multiple-options-add').$type,
false
)
) {
diff --git a/src/Generator/SettingsPageGenerator.php b/src/Generator/SettingsPageGenerator.php
new file mode 100644
index 0000000..ce4d509
--- /dev/null
+++ b/src/Generator/SettingsPageGenerator.php
@@ -0,0 +1,128 @@
+extensionManager = $extensionManager;
+ }
+
+
+ /**
+ * Generator SettingsPage
+ *
+ * @param string $plugin,
+ * @param string $class_name
+ * @param string $setting_group
+ * @param string $setting_name
+ * @param string $page_title
+ * @param string $menu_title
+ * @param string $capability
+ * @param string $slug
+ * @param string $callback_function
+ * @param array $sections
+ * @param array $fields
+ * @param string $text_domain
+ */
+ public function generate(
+ $plugin,
+ $class_name,
+ $setting_group,
+ $setting_name,
+ $page_title,
+ $menu_title,
+ $capability,
+ $slug,
+ $callback_function,
+ $sections,
+ $fields,
+ $text_domain
+ ) {
+ $pluginFile = $this->extensionManager->getPlugin($plugin)->getPathname();
+ $dir = $this->extensionManager->getPlugin($plugin)->getPath();
+
+ $parameters = [
+ "plugin" => $plugin,
+ "class_name" => $class_name,
+ "setting_group" => $setting_group,
+ "setting_name" => $setting_name,
+ "page_title" => $page_title,
+ "menu_title" => $menu_title,
+ "capability" => $capability,
+ "slug" => $slug,
+ "callback_function" => $callback_function,
+ "sections" => $sections,
+ "fields" => $fields,
+ "text_domain" => $text_domain,
+ "class_name_path" => 'SettingsPage/' . lcfirst($class_name) . '.php',
+ "admin_settings_page_path" => 'admin/partials/settings-page-admin.php',
+ "file_exists" => file_exists($pluginFile),
+ "command_name" => 'settingspage'
+ ];
+
+ $file_path = $dir.'/admin/partials/'.$parameters['class_name_path'];
+ $file_path_admin = $dir.'/'.$parameters['admin_settings_page_path'];
+
+ if (file_exists($file_path)) {
+ if (!is_dir($file_path)) {
+ throw new \RuntimeException(
+ sprintf(
+ 'Unable to generate the settings page , it already exist at "%s"',
+ realpath($file_path)
+ )
+ );
+ }
+ }
+
+ if (!file_exists($file_path_admin)) {
+ $this->renderFile(
+ 'plugin/plugin.php.twig',
+ $pluginFile,
+ $parameters,
+ FILE_APPEND
+ );
+ }
+
+ $this->renderFile(
+ 'plugin/src/SettingsPage/class-settings-page.php.twig',
+ $file_path,
+ $parameters
+ );
+
+ $parameters['admin_file_exists'] = file_exists($file_path_admin);
+
+ $this->renderFile(
+ 'plugin/src/class-admin.php.twig',
+ $file_path_admin,
+ $parameters,
+ FILE_APPEND
+ );
+ }
+}
diff --git a/templates/plugin/plugin.php.twig b/templates/plugin/plugin.php.twig
index bac32d0..4043564 100644
--- a/templates/plugin/plugin.php.twig
+++ b/templates/plugin/plugin.php.twig
@@ -170,4 +170,16 @@ function {{ plugin }}_add_cron_{{ type }}()
}
{{ plugin }}_add_cron_{{ type }}();
{%- endif -%}
+{%- if admin_settings_page_path is defined -%}
+
+/**
+ * This function add custom settings page that are in admin/partials/settings-page-admin.php
+ */
+function {{ plugin }}_add_settings_page()
+{
+ // Include the files for rendering the display.
+ include_once plugin_dir_path( __FILE__ ) .'{{ admin_settings_page_path }}';
+}
+{{ plugin }}_add_settings_page();
+{%- endif -%}
{%- endblock -%}
\ No newline at end of file
diff --git a/templates/plugin/src/SettingsPage/class-settings-page.php.twig b/templates/plugin/src/SettingsPage/class-settings-page.php.twig
new file mode 100644
index 0000000..4831cf3
--- /dev/null
+++ b/templates/plugin/src/SettingsPage/class-settings-page.php.twig
@@ -0,0 +1,166 @@
+{% extends "base/class.php.twig" %}
+{%- block class_declaration -%}
+/**
+ * Create a custom settings page
+ */
+class {{ class_name }} {% endblock -%}
+{% block class_construct %}
+ /**
+ * Holds the values to be used in the fields callbacks
+ */
+ private $options;
+
+ /**
+ * Start up
+ */
+ public function __construct()
+ {
+ add_action( 'admin_menu', array( $this, 'add_{{ class_name|lower }}_plugin_page' ) );
+ add_action( 'admin_init', array( $this, '{{ class_name|lower}}_page_init' ) );
+ }
+{% endblock %}
+
+{% block class_methods %}
+
+ /**
+ * Add options page
+ */
+ public function add_{{ class_name|lower }}_plugin_page()
+ {
+ // This page will be under "Settings"
+ add_options_page(
+ 'Settings Submenu',
+ __( '{{ menu_title }}', '{{ text_domain }}' ),
+ '{{ capability }}',
+ '{{ slug }}',
+ array( $this, '{{ callback_function }}' )
+ );
+ }
+
+ /**
+ * Options page callback
+ */
+ public function {{ callback_function }}()
+ {
+ // Set class property
+ $this->options = get_option( '{{ setting_name }}' );
+ ?>
+
+{% if page_title is not null or page_title is defined %}
+
{{ page_title }}
+{% endif %}
+
+
+
+{% for options in field.multi_selection %}
+
+{% endfor %}
+ ';
+{% elseif field.type == 'radio' %}
+{% for options in field.multi_selection %}
+ echo 'options['{{ field.id }}'], false ).'/> {{ options.label }}
';
+{% endfor %}
+{% elseif field.type == 'image' %}
+ echo '
+{% elseif field.type == 'checkbox' %}
+ echo 'options['{{ field.id }}'], false ).'/> {{ options.label }}
';
+{% else %}
+ printf(
+ '',
+ isset( $this->options['{{ field.id }}'] ) ? esc_attr( $this->options['{{ field.id }}']) : ''
+ );
+{% endif %}
+ }
+
+{% endfor %}
+{% endif %}
+{% endblock %}
\ No newline at end of file