diff --git a/actions/pass.php b/actions/pass.php index 3cc153cce..9938a8eac 100644 --- a/actions/pass.php +++ b/actions/pass.php @@ -9,7 +9,7 @@ class Pass_Action extends Url_Action { /** * Process an external passthrough - a URL that lives external to this server. * - * @param String $url Target URL. + * @param string $url Target URL. * @return void */ public function process_external( $url ) { @@ -21,7 +21,7 @@ public function process_external( $url ) { /** * Process an internal passthrough - a URL that lives on the same server. Here we change the request URI and continue without making a remote request. * - * @param String $target Target URL. + * @param string $target Target URL. * @return void */ public function process_internal( $target ) { @@ -42,7 +42,7 @@ public function process_internal( $target ) { /** * Is a URL external? * - * @param String $target URL to test. + * @param string $target URL to test. * @return boolean */ public function is_external( $target ) { diff --git a/api/api-404.php b/api/api-404.php index 8b6eb1e92..3a5e61310 100644 --- a/api/api-404.php +++ b/api/api-404.php @@ -85,7 +85,7 @@ class Redirection_Api_404 extends Redirection_Api_Filter_Route { /** * 404 API endpoint constructor * - * @param String $namespace Namespace. + * @param string $namespace Namespace. */ public function __construct( $namespace ) { $orders = [ 'url', 'ip', 'total', 'count', '' ]; diff --git a/api/api-group.php b/api/api-group.php index 1221ca836..73380193e 100644 --- a/api/api-group.php +++ b/api/api-group.php @@ -138,7 +138,7 @@ class Redirection_Api_Group extends Redirection_Api_Filter_Route { /** * 404 API endpoint constructor * - * @param String $namespace Namespace. + * @param string $namespace Namespace. */ public function __construct( $namespace ) { $orders = [ 'name', 'id', '' ]; diff --git a/api/api-log.php b/api/api-log.php index 4557890ef..4b478b58c 100644 --- a/api/api-log.php +++ b/api/api-log.php @@ -104,7 +104,7 @@ class Redirection_Api_Log extends Redirection_Api_Filter_Route { /** * Log API endpoint constructor * - * @param String $namespace Namespace. + * @param string $namespace Namespace. */ public function __construct( $namespace ) { $orders = [ 'url', 'ip', 'total', 'count', '' ]; diff --git a/api/api-redirect.php b/api/api-redirect.php index 3e5f1a3b1..84052a48c 100644 --- a/api/api-redirect.php +++ b/api/api-redirect.php @@ -174,7 +174,7 @@ class Redirection_Api_Redirect extends Redirection_Api_Filter_Route { /** * Redirect API endpoint constructor * - * @param String $namespace Namespace. + * @param string $namespace Namespace. */ public function __construct( $namespace ) { $orders = [ 'source', 'last_count', 'last_access', 'position', 'id', '' ]; diff --git a/api/api.php b/api/api.php index 7a37623c6..ddc149322 100644 --- a/api/api.php +++ b/api/api.php @@ -143,8 +143,8 @@ protected function get_filter_args( $order_fields, $filters = [] ) { /** * Register a bulk action route * - * @param String $namespace Namespace. - * @param String $route Route. + * @param string $namespace Namespace. + * @param string $route Route. * @param Array $orders * @param Array $filters * @param Object $callback diff --git a/client/component/form-table/style.scss b/client/component/form-table/style.scss index cc4602a71..14ca52f54 100644 --- a/client/component/form-table/style.scss +++ b/client/component/form-table/style.scss @@ -15,4 +15,14 @@ margin-bottom: 0; line-height: 1.6; } + + textarea { + width: 300px; + height: 100px; + } + + .inline-notice { + margin-top: 10px; + margin-bottom: 0; + } } diff --git a/client/page/options/donation.js b/client/page/options/donation.js deleted file mode 100644 index e035bc3fa..000000000 --- a/client/page/options/donation.js +++ /dev/null @@ -1,150 +0,0 @@ -/** - * External dependencies - */ - -import React from 'react'; -import { __ } from '@wordpress/i18n'; -import PropTypes from 'prop-types'; - -/** - * Internal dependencies - */ -import { FormTable, TableRow } from 'component/form-table'; -import { createInterpolateElement } from 'wp-plugin-components'; -import './donation.scss'; - -const MIN = 16; -const MAX = 100; - -class Donation extends React.Component { - static propTypes = { - support: PropTypes.bool.isRequired, - }; - - constructor( props ) { - super( props ); - - this.onDonate = this.handleDonation.bind( this ); - this.onChange = this.handleChange.bind( this ); - this.onBlur = this.handleBlur.bind( this ); - this.onInput = this.handleInput.bind( this ); - this.state = { - support: props.support, - amount: 20, - }; - } - - handleBlur() { - this.setState( { amount: Math.max( MIN, this.state.amount ) } ); - } - - handleDonation() { - this.setState( { support: false } ); - } - - getReturnUrl() { - return document.location.href + '#thanks'; - } - - handleChange( data ) { - if ( this.state.amount !== data.value ) { - this.setState( { amount: parseInt( data.value, 10 ) } ); - } - } - - handleInput( ev ) { - const value = ev.target.value ? parseInt( ev.target.value, 10 ) : MIN; - - this.setState( { amount: value } ); - } - - getAmountoji( amount ) { - const amounts = [ - [ 100, '😍' ], - [ 80, '😎' ], - [ 60, '😊' ], - [ 40, '😃' ], - [ 20, '😀' ], - [ 10, '🙂' ], - ]; - - for ( let pos = 0; pos < amounts.length; pos++ ) { - if ( amount >= amounts[ pos ][ 0 ] ) { - return amounts[ pos ][ 1 ]; - } - } - - return amounts[ amounts.length - 1 ][ 1 ]; - } - - renderSupported() { - return ( -
- { __( "You've supported this plugin - thank you!", 'redirection' ) }   - { __( "I'd like to support some more.", 'redirection' ) } -
- ); - } - - renderUnsupported() { - const marks = { [ MIN ]: '' }; - - for ( let x = 20; x <= MAX; x += 20 ) { - marks[ x ] = ''; - } - - return ( -
- - - - - - - - - - - - - - - - - -
- $ - - { this.getAmountoji( this.state.amount ) } - -
-
- ); - } - - render() { - const { support } = this.state; - - return ( -
- - - { support ? this.renderSupported() : this.renderUnsupported() } - - -
- ); - } -} - -export default Donation; diff --git a/client/page/options/donation.scss b/client/page/options/donation.scss deleted file mode 100644 index 2dd286def..000000000 --- a/client/page/options/donation.scss +++ /dev/null @@ -1,57 +0,0 @@ -/** - * The donation section of the options page - */ -.donation { - .donation-amount { - display: flex; - align-items: center; - margin-top: 10px; - - span { - font-size: 28px; - vertical-align: bottom; - margin-left: 4px; - } - - img { - width: 24px !important; - margin-bottom: -5px !important; - } - } - - .donation-amount::after { - content: ""; - display: block; - clear: both; - } - - input[type="number"] { - width: 60px; - margin-left: 10px; - } - - td, - th { - padding-bottom: 0; - margin-bottom: 0; - } - - input[type="submit"] { - margin-left: 10px; - } -} - -.newsletter h3 { - margin-top: 30px; -} - -.redirect-option__row { - td { - padding-left: 0; - padding-bottom: 0; - } - - h2 { - margin: 0; - } -} diff --git a/client/page/options/index.js b/client/page/options/index.js index c2265dea5..87820cc60 100644 --- a/client/page/options/index.js +++ b/client/page/options/index.js @@ -13,7 +13,6 @@ import { STATUS_IN_PROGRESS, STATUS_COMPLETE } from 'state/settings/type'; import OptionsForm from './options-form'; import DeletePlugin from 'page/options/delete-plugin'; import Placeholder from 'wp-plugin-components/placeholder'; -import Donation from './donation'; import Newsletter from './newsletter'; class Options extends React.Component { @@ -31,7 +30,6 @@ class Options extends React.Component { return (
- { loadStatus === STATUS_COMPLETE && } { loadStatus === STATUS_COMPLETE && } diff --git a/client/page/options/options-form/index.js b/client/page/options/options-form/index.js index bb887bbc2..34ab0e43f 100644 --- a/client/page/options/options-form/index.js +++ b/client/page/options/options-form/index.js @@ -2,7 +2,7 @@ * External dependencies */ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { __ } from '@wordpress/i18n'; import { connect } from 'react-redux'; @@ -11,11 +11,12 @@ import { connect } from 'react-redux'; */ import { saveSettings } from 'state/settings/action'; import { STATUS_IN_PROGRESS } from 'state/settings/type'; -import { FormTable, TableRow } from 'component/form-table'; +import { FormTable } from 'component/form-table'; import { Button } from 'wp-plugin-components'; import LogOptions from './log-options'; import OtherOptions from './other-options'; import UrlOptions from './url-options'; +import './style.scss'; function supportLink( rel, anchor ) { return 'https://redirection.me/support/' + rel + ( anchor ? '/#' + anchor : '' ); @@ -43,22 +44,13 @@ function OptionsForm( props ) { } // Update local settings if values change - useEffect(() => { + useEffect( () => { setSettings( values ); - }, [ values ]); + }, [ values ] ); return (
- - - - diff --git a/client/page/options/options-form/log-options.js b/client/page/options/options-form/log-options.js index ca9ccdb63..b9f3c4950 100644 --- a/client/page/options/options-form/log-options.js +++ b/client/page/options/options-form/log-options.js @@ -3,12 +3,13 @@ */ import { __ } from '@wordpress/i18n'; +import TextareaAutosize from 'react-textarea-autosize'; /** * Internal dependencies */ import { TableRow } from 'component/form-table'; -import { ExternalLink, Select, createInterpolateElement } from 'wp-plugin-components'; +import { ExternalLink, MultiOptionDropdown, Notice, Select, createInterpolateElement } from 'wp-plugin-components'; const timeToKeep = () => [ { value: -1, label: __( 'No logs', 'redirection' ) }, @@ -23,10 +24,20 @@ const ipLogging = () => [ { value: 1, label: __( 'Full IP logging', 'redirection' ) }, { value: 2, label: __( 'Anonymize IP (mask last part)', 'redirection' ) }, ]; +const ipAddress = () => [ + { value: 'HTTP_CF_CONNECTING_IP', label: 'HTTP_CF_CONNECTING_IP' }, + { value: 'HTTP_CLIENT_IP', label: 'HTTP_CLIENT_IP' }, + { value: 'HTTP_X_FORWARDED_FOR', label: 'HTTP_X_FORWARDED_FOR' }, + { value: 'HTTP_X_FORWARDED', label: 'HTTP_X_FORWARDED' }, + { value: 'HTTP_X_CLUSTER_CLIENT_IP', label: 'HTTP_X_CLUSTER_CLIENT_IP' }, + { value: 'HTTP_FORWARDED_FOR', label: 'HTTP_FORWARDED_FOR' }, + { value: 'HTTP_FORWARDED', label: 'HTTP_FORWARDED' }, + { value: 'HTTP_VIA', label: 'HTTP_VIA' }, +]; function LogOptions( props ) { const { settings, onChange, getLink } = props; - const { expire_redirect, expire_404, ip_logging, log_external, track_hits, log_header, support } = settings; + const { expire_redirect, expire_404, ip_logging, log_external, track_hits, log_header, ip_proxy, ip_headers } = settings; return ( <> @@ -62,6 +73,27 @@ function LogOptions( props ) { />{ ' ' } { __( '(IP logging level)', 'redirection' ) } + + 0 } + hideTitle={ ip_headers.length > 0 } + onApply={ ( options ) => onChange( { ip_headers: options } ) } + title={ ip_headers.length === 0 ? __( 'REMOTE_ADDR', 'redirection' ) : '' } + /> + +

{ createInterpolateElement( __( 'Only set custom IP headers if your server does not use REMOTE_ADDR to store the client IP address.', 'redirection' ), { code: } ) }

+ { ip_headers.length > 0 &&

{ createInterpolateElement( __( 'Please ensure you trust the data in these headers. If using a proxy then set its address below.', 'redirection' ), { code: } ) }

} +
+ { + ip_headers.length > 0 && + + onChange( { ip_proxy: ev.target.value.split( '\n' ) } ) } rows={ 5 } /> +

{ __( 'If using a proxy then add any IP addresses here to only trust IP headers from those addresses.', 'redirection' ) }

+
+ }