Skip to content

Commit 406e06b

Browse files
committed
Merge dev to main
1 parent b0dcfca commit 406e06b

17 files changed

+765
-329
lines changed

LICENSE

+617-282
Large diffs are not rendered by default.

app/Features/Embeds.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use SSFV\Codex\Contracts\Hookable;
88
use SSFV\Codex\Facades\App;
9+
use SSFV\Codex\Facades\Config;
910
use SSFV\Codex\Foundation\Hooks\Hook;
1011
use WP_Scripts;
1112

@@ -23,11 +24,13 @@ public function hook(Hook $hook): void
2324

2425
public function disables(Hook $hook): void
2526
{
27+
// phpcs:disable
2628
/** @var WP $wp */
2729
$wp = $GLOBALS['wp'];
28-
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
2930
$wp->public_query_vars = array_diff($wp->public_query_vars, ['embed']);
31+
// phpcs:enable
3032

33+
$hook->addAction('update_option_' . Config::get('app.option_prefix') . 'cron', [$this, 'flushPermalinks']);
3134
$hook->addAction('enqueue_block_editor_assets', [$this, 'disableOnBlockEditor']);
3235
$hook->addAction('wp_default_scripts', [$this, 'disableScriptDependencies']);
3336
$hook->addFilter('embed_oembed_discover', '__return_false');
@@ -42,6 +45,11 @@ public function disables(Hook $hook): void
4245
$hook->removeFilter('pre_oembed_result', 'wp_filter_pre_oembed_result', 10);
4346
}
4447

48+
public function flushPermalinks(): void
49+
{
50+
flush_rewrite_rules(false);
51+
}
52+
4553
/**
4654
* @param array<mixed> $data
4755
*

app/Plugin.php

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public function getInstances(ContainerInterface $container): iterable
2121
yield new Switches\Assets();
2222
yield new Switches\General();
2323
yield new Switches\Media();
24+
yield new Switches\Security();
25+
yield new Switches\Webpage();
2426

2527
// Mark as initilized.
2628
do_action('syntatis/feature-flipper/init', $container);

app/Switches/Admin.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public function hook(Hook $hook): void
2828
return;
2929
}
3030

31-
$hook->addAction('admin_init', static function (): void {
32-
remove_action('admin_notices', 'update_nag', 3);
33-
remove_action('network_admin_notices', 'update_nag', 3);
31+
$hook->addAction('admin_init', static function () use ($hook): void {
32+
$hook->removeAction('admin_notices', 'update_nag', 3);
33+
$hook->removeAction('network_admin_notices', 'update_nag', 3);
3434
}, 99);
3535
}
3636
}

app/Switches/Assets.php

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ public function hook(Hook $hook): void
2323
*
2424
* @see https://make.wordpress.org/core/2023/10/17/replacing-hard-coded-style-tags-with-wp_add_inline_style/
2525
*/
26-
remove_action('wp_print_styles', 'print_emoji_styles');
27-
remove_action('wp_head', 'print_emoji_detection_script', 7);
28-
remove_action('admin_print_scripts', 'print_emoji_detection_script');
29-
remove_action('admin_print_styles', 'print_emoji_styles');
30-
remove_filter('the_content_feed', 'wp_staticize_emoji');
31-
remove_filter('comment_text_rss', 'wp_staticize_emoji');
32-
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
26+
$hook->removeAction('wp_print_styles', 'print_emoji_styles');
27+
$hook->removeAction('wp_head', 'print_emoji_detection_script', 7);
28+
$hook->removeAction('admin_print_scripts', 'print_emoji_detection_script');
29+
$hook->removeAction('admin_print_styles', 'print_emoji_styles');
30+
$hook->removeFilter('the_content_feed', 'wp_staticize_emoji');
31+
$hook->removeFilter('comment_text_rss', 'wp_staticize_emoji');
32+
$hook->removeFilter('wp_mail', 'wp_staticize_emoji_for_email');
3333
}
3434

3535
// 2. Scripts Version.
@@ -41,11 +41,11 @@ public function hook(Hook $hook): void
4141
$hook->addFilter('style_loader_src', $callback);
4242
}
4343

44+
// 3. jQuery Migrate.
4445
if (Option::get('jquery_migrate')) {
4546
return;
4647
}
4748

48-
// 3. jQuery Migrate.
4949
$hook->addAction('wp_default_scripts', static function (WP_Scripts $scripts): void {
5050
if (empty($scripts->registered['jquery'])) {
5151
return;

app/Switches/Security.php

+42
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,52 @@
66

77
use SSFV\Codex\Contracts\Hookable;
88
use SSFV\Codex\Foundation\Hooks\Hook;
9+
use Syntatis\FeatureFlipper\Option;
10+
use WP_Error;
11+
12+
use function define;
13+
use function defined;
914

1015
class Security implements Hookable
1116
{
1217
public function hook(Hook $hook): void
1318
{
19+
// 1. Disable XML-RPC.
20+
if (! Option::get('xmlrpc')) {
21+
$hook->addFilter('pings_open', '__return_false');
22+
$hook->addFilter('xmlrpc_enabled', '__return_false');
23+
$hook->addFilter('xmlrpc_methods', '__return_empty_array');
24+
$hook->removeAction('wp_head', 'rsd_link');
25+
}
26+
27+
// 2. Disable file editor.
28+
if (! Option::get('file_edit') && ! defined('DISALLOW_FILE_EDIT')) {
29+
define('DISALLOW_FILE_EDIT', true);
30+
}
31+
32+
// 3. Disable public REST API.
33+
if (! Option::get('authenticated_rest_api')) {
34+
return;
35+
}
36+
37+
$hook->addFilter('rest_authentication_errors', [$this, 'apiForceAuthentication']);
38+
}
39+
40+
/**
41+
* @param WP_Error|true|null $access
42+
*
43+
* @return WP_Error|true|null
44+
*/
45+
public function apiForceAuthentication($access)
46+
{
47+
return is_user_logged_in()
48+
? $access
49+
: new WP_Error(
50+
'rest_login_required',
51+
__('You must be logged in to access this resource.', 'syntatis-feature-flipper'),
52+
[
53+
'status' => rest_authorization_required_code(),
54+
],
55+
);
1456
}
1557
}

app/Switches/Webpage.php

+18
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@
66

77
use SSFV\Codex\Contracts\Hookable;
88
use SSFV\Codex\Foundation\Hooks\Hook;
9+
use Syntatis\FeatureFlipper\Option;
910

1011
class Webpage implements Hookable
1112
{
1213
public function hook(Hook $hook): void
1314
{
15+
// 1. RSD Link.
16+
if (! Option::get('rsd_link')) {
17+
$hook->removeAction('wp_head', 'rsd_link');
18+
}
19+
20+
// 2. WordPress Generator meta tag.
21+
if (! Option::get('generator_tag')) {
22+
$hook->removeAction('wp_head', 'wp_generator');
23+
}
24+
25+
// 3. Shortlink.
26+
if (Option::get('shortlink')) {
27+
return;
28+
}
29+
30+
$hook->removeAction('wp_head', 'wp_shortlink_wp_head');
31+
$hook->removeAction('wp_head', 'wp_shortlink_header');
1432
}
1533
}

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"homepage": "https://github.com/tfirdaus"
1919
}
2020
],
21-
"license": "GPL-2.0-or-later",
21+
"license": "GPL-3.0",
2222
"autoload": {
2323
"psr-4": {
2424
"Syntatis\\FeatureFlipper\\": [

inc/settings/all.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@
5050
(new Setting('jquery_migrate', 'boolean'))
5151
->withDefault(true),
5252

53-
// Webpage
53+
// Webpage.
5454
(new Setting('rsd_link', 'boolean'))
5555
->withDefault(true),
56-
(new Setting('wordpress_generator', 'boolean'))
56+
(new Setting('generator_tag', 'boolean'))
5757
->withDefault(true),
5858
(new Setting('shortlink', 'boolean'))
5959
->withDefault(true),
60-
(new Setting('rest_api_link', 'boolean'))
61-
->withDefault(true),
6260

63-
// Security
61+
// Security.
6462
(new Setting('xmlrpc', 'boolean'))
6563
->withDefault(true),
66-
(new Setting('unauthenticated_rest_api', 'boolean'))
64+
(new Setting('file_edit', 'boolean'))
65+
->withDefault(true),
66+
(new Setting('authenticated_rest_api', 'boolean'))
6767
->withDefault(false),
6868
];

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"name": "@syntatis/wp-feature-flipper",
3-
"version": "0.1.0",
2+
"name": "syntatis-feature-flipper",
3+
"version": "1.0.0",
44
"description": "Easily switch some features in WordPress, on and off",
55
"author": {
66
"name": "Thoriq Firdaus",
77
"url": "https://github.com/tfirdaus"
88
},
99
"private": true,
10-
"license": "GPL-2.0-or-later",
10+
"license": "GPL-3.0",
1111
"keywords": [
1212
"wordpress",
1313
"plugin",
@@ -22,7 +22,7 @@
2222
"inc",
2323
"dist",
2424
"*.php",
25-
"!*.*.php"
25+
"!**/*.*.php"
2626
],
2727
"dependencies": {
2828
"@syntatis/kubrick": "^0.1.0-beta.3",

readme.txt

+30-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,42 @@
11
=== Feature Flipper ===
22

33
Contributors: tfirdaus
4-
Tags: wordpress, plugin, boilerplate
4+
Tags: disable, rss, emojis, xmlrpc, rest-api, security, gutenberg
55
Requires at least: 5.8
66
Tested up to: 6.6
7-
Stable tag: 0.1
7+
Stable tag: 1.0
88
Requires PHP: 7.4
99
License: GPLv2 or later
1010
License URI: https://www.gnu.org/licenses/gpl-2.0.html
1111

12-
Easily switch WordPress feature on and off.
12+
Easily switch some features in WordPress, on and off.
1313

1414
== Description ==
1515

16-
The plugin long description.
16+
WordPress comes with a lot of features. Some of them are useful and essential, while there are probably some that you do not need. This plugin allows you to switch some of these features, on and off, easily. Several features that this plugin supports are:
17+
18+
- **Gutenberg**: Gutenberg has become the default editor in WordPress on both Page and Post type. But if you are not using it, you can disable it to switch back to the Classic Editor.
19+
- **Emojis**: Emojis are fun. But WordPress loads some scripts to support rendering emojis. If you do not use Emojis in your content, you can disable them to remove the additional weight from the scripts.
20+
- **XML-RPC**: XML-RPC is a remote procedure call protocol that allows you to communicate with your WordPress site. If you do not use any services that require XML-RPC, you can disable it which helps reducing the attack surface of your site.
21+
- **jQuery Migrate**: jQuery Migrate is a JavaScript library that helps you to migrate your jQuery code to the latest version. If you are not using any old jQuery code, you can disable it to remove the additional weight of the library from your site.
22+
- **Post Embeds**: Post Embeds allow you to embed posts from your site into another site, or within your own site. If you do not use this feature, you can disable it to prevent others from embedding your posts.
23+
- **Attachment Slug**: WordPress, by default, will automaically create a slug for your attachment URLs from the media file name. This could cause issues when the slug is conflicting with your post or page slug. To avoid attchment reserving the slug, you can disable this default behaviour. This plugin will randomly generate a unique slug for your attachment URLs.
24+
- And more...
25+
26+
== Installation ==
27+
28+
1. Upload the plugin files to the `/wp-content/plugins/feature-flipper` directory, or install the plugin through the WordPress plugins screen directly.
29+
2. Activate the plugin through the 'Plugins' screen in WordPress.
30+
3. Use the Settings -> Flipper screen to configure the plugin.
31+
32+
[More info on installing plugins](https://wordpress.org/documentation/article/manage-plugins/#installing-plugins)
33+
34+
== Frequently Asked Questions ==
35+
36+
= How do I disable a feature? =
37+
38+
To disable a feature, you can go to the Settings -> Flipper screen in your WordPress admin dashboard. You will see a list of features that you can enable or disable. Simply click the toggle button to switch the feature on or off.
39+
40+
= How do I suggest a new feature? =
41+
42+
You can suggest a new feature by creating a new issue in the [plugin's GitHub repository](https://github.com/syntatis/wp-feature-flipper).

src/setting-page/components/form/Form.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, useEffect, useRef, useState } from 'react';
1+
import { createContext, useEffect, useRef, useState } from '@wordpress/element';
22
import { SubmitButton } from './SubmitButton';
33
import { useSettingsContext } from './useSettingsContext';
44
import { FormNotice } from './FormNotice';

src/setting-page/components/form/SettingsProvider.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const SettingsProvider = ( { children } ) => {
1515
submitValues,
1616
getOption,
1717
initialValues,
18+
updatedValues,
1819
} = useSettings();
1920

2021
return (
@@ -28,6 +29,7 @@ export const SettingsProvider = ( { children } ) => {
2829
setStatus,
2930
submitValues,
3031
initialValues,
32+
updatedValues,
3133
setValues: ( name, value ) => {
3234
setValues( {
3335
...values,

src/setting-page/components/form/useSettings.js

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function parseExceptionMessage( errorString ) {
2020
export const useSettings = () => {
2121
const [ values, setValues ] = useState( preloaded );
2222
const [ status, setStatus ] = useState();
23+
const [ updatedValues, setUpdatedValues ] = useState();
2324
const [ updating, setUpdating ] = useState( false );
2425
const [ errorMessages, setErrorMessages ] = useState( {} );
2526
const filterValues = ( v ) => {
@@ -70,6 +71,7 @@ export const useSettings = () => {
7071
setStatus( 'error' );
7172
} )
7273
.finally( () => {
74+
setUpdatedValues( data );
7375
setUpdating( false );
7476
} );
7577
};
@@ -84,5 +86,6 @@ export const useSettings = () => {
8486
setStatus,
8587
getOption,
8688
initialValues: preloaded,
89+
updatedValues,
8790
};
8891
};

src/setting-page/tabs/SecurityTab.jsx

+13-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ export const SecurityTab = () => {
66
return (
77
<Form>
88
<Fieldset>
9+
<SwitchInput
10+
name="file_edit"
11+
id="file-edit"
12+
label={ __( 'File Edit', 'syntatis-feature-flipper' ) }
13+
description={ __(
14+
'When set to "off", it will disable the file editor for themes and plugins.',
15+
'syntatis-feature-flipper'
16+
) }
17+
>
18+
{ __( 'Enable File Editor', 'syntatis-feature-flipper' ) }
19+
</SwitchInput>
920
<SwitchInput
1021
name="xmlrpc"
1122
id="xmlrpc"
@@ -18,8 +29,8 @@ export const SecurityTab = () => {
1829
{ __( 'Enable XML-RPC', 'syntatis-feature-flipper' ) }
1930
</SwitchInput>
2031
<SwitchInput
21-
name="unauthenticated_rest_api"
22-
id="xmlrpc"
32+
name="authenticated_rest_api"
33+
id="authenticated-rest-api"
2334
label={ __(
2435
'REST API Authentication',
2536
'syntatis-feature-flipper'

src/setting-page/tabs/WebpageTab.jsx

+2-13
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ export const WebpageTab = () => {
2424
{ __( 'Add RSD link', 'syntatis-feature-flipper' ) }
2525
</SwitchInput>
2626
<SwitchInput
27-
name="wordpress_generator"
28-
id="wordpress-generator"
27+
name="generator_tag"
28+
id="generator-tag"
2929
label={ __(
3030
'Generator Meta Tag',
3131
'syntatis-feature-flipper'
@@ -51,17 +51,6 @@ export const WebpageTab = () => {
5151
>
5252
{ __( 'Add Shortlink', 'syntatis-feature-flipper' ) }
5353
</SwitchInput>
54-
<SwitchInput
55-
name="rest_api_link"
56-
id="rest_api_link"
57-
label={ __( 'REST API Link', 'syntatis-feature-flipper' ) }
58-
description={ __(
59-
'When set to "off", it will remove the REST API link from the webpage head.',
60-
'syntatis-feature-flipper'
61-
) }
62-
>
63-
{ __( 'Add REST API link', 'syntatis-feature-flipper' ) }
64-
</SwitchInput>
6554
</Fieldset>
6655
</Form>
6756
);

0 commit comments

Comments
 (0)