Commit 71558db9 authored by Michael Iseard's avatar Michael Iseard
Browse files

More changes and improvements

parent aa6b46ec
......@@ -30,6 +30,39 @@
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/woocommerce/action-scheduler" />
<path value="/tmp/wordpress-tests-lib" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/wp-coding-standards/wpcs" />
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/squizlabs/php_codesniffer" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/graham-campbell/result-type" />
</include_path>
</component>
<component name="PhpInterpreters">
......
......@@ -3,6 +3,7 @@
namespace Kudos\Admin\Table;
use Kudos\Entity\TransactionEntity;
use Kudos\Helpers\Campaigns;
use Kudos\Helpers\Settings;
use Kudos\Helpers\Utils;
use Kudos\Service\MapperService;
......@@ -34,7 +35,6 @@ class CampaignsTable extends WP_List_Table {
];
$this->export_columns = [
'date' => __( 'Name', 'kudos-donations' ),
'label' => __( 'Email', 'kudos-donations' ),
'transactions' => __( 'Street', 'kudos-donations' ),
'total' => __( 'Total', 'kudos-donations' ),
......@@ -42,7 +42,7 @@ class CampaignsTable extends WP_List_Table {
parent::__construct(
[
'orderBy' => 'date',
'orderBy' => 'slug',
'singular' => __( 'Campaign', 'kudos-donations' ),
'plural' => __( 'Campaigns', 'kudos-donations' ),
'ajax' => false,
......@@ -75,7 +75,7 @@ class CampaignsTable extends WP_List_Table {
$mapper = $this->mapper;
$search = $this->get_search_data();
$campaigns = Settings::get_setting( 'campaign_labels' );
$campaigns = Settings::get_setting( 'campaigns' );
if ( ! $campaigns ) {
return [];
}
......@@ -91,10 +91,11 @@ class CampaignsTable extends WP_List_Table {
}
foreach ( $campaigns as $key => $campaign ) {
$label = $campaign['label'];
$id = $campaign['id'];
$transactions = $mapper->get_all_by( [ 'campaign_label' => $label ] );
$transactions = $mapper->get_all_by( [ 'campaign_label' => $id ] );
// $campaigns[ $key ]['date'] = date("r",hexdec(substr($id,3,8)));
$campaigns[ $key ]['transactions'] = 0;
$campaigns[ $key ]['total'] = 0;
if ( $transactions ) {
......@@ -128,7 +129,6 @@ class CampaignsTable extends WP_List_Table {
*/
public function column_names(): array {
return [
'date' => __( 'Date', 'kudos-donations' ),
'label' => __( 'Label', 'kudos-donations' ),
'transactions' => __( 'Transactions', 'kudos-donations' ),
'total' => __( 'Total', 'kudos-donations' ),
......@@ -245,7 +245,7 @@ class CampaignsTable extends WP_List_Table {
protected function column_cb( $item ): string {
return sprintf(
'<input type="checkbox" name="bulk-action[]" value="%s" />',
$item['label']
$item['name']
);
}
......@@ -259,23 +259,9 @@ class CampaignsTable extends WP_List_Table {
*/
protected function column_date( array $item ): string {
$delete_nonce = wp_create_nonce( 'bulk-' . $this->_args['singular'] );
$actions = [
'delete' => sprintf(
'<a href="?page=%s&action=%s&label=%s&_wpnonce=%s">%s</a>',
esc_attr( $_REQUEST['page'] ),
'delete',
sanitize_text_field( $item['label'] ),
$delete_nonce,
__( 'Delete', 'kudos-donations' )
),
];
return __( 'Added', 'kudos-donations' ) . '<br/>' .
wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
strtotime( $item['date'] ) ) . '<br/>' .
$this->row_actions( $actions );
strtotime( $item['date'] ) );
}
/**
......@@ -288,7 +274,7 @@ class CampaignsTable extends WP_List_Table {
*/
protected function column_label( array $item ): string {
return strtoupper( $item['label'] );
return $item['name'];
}
......@@ -304,7 +290,7 @@ class CampaignsTable extends WP_List_Table {
return sprintf(
'<a href=%1$s>%2$s</a>',
sprintf( admin_url( 'admin.php?page=kudos-transactions&search-field=campaign_label&s=%s' ), rawurlencode( $item['label'] ) ),
sprintf( admin_url( 'admin.php?page=kudos-transactions&search-field=campaign_label&s=%s' ), rawurlencode( $item['slug'] ) ),
strtoupper( $item['transactions'] )
);
......
......@@ -4,6 +4,7 @@ namespace Kudos\Admin\Table;
use Kudos\Entity\DonorEntity;
use Kudos\Entity\TransactionEntity;
use Kudos\Helpers\Campaigns;
use Kudos\Helpers\Utils;
use Kudos\Service\MapperService;
use WP_List_Table;
......@@ -446,7 +447,7 @@ class TransactionsTable extends WP_List_Table {
'<a href=%1$s>%2$s</a>',
sprintf( admin_url( 'admin.php?page=kudos-campaigns&search-field=label&s=%s' ),
rawurlencode( $item['campaign_label'] ) ),
strtoupper( $item['campaign_label'] )
Campaigns::get_campaign( $item['campaign_label'], 'id' )['name'] ?? $item['campaign_label']
);
}
......
......@@ -2,7 +2,7 @@
namespace Kudos\Front;
use Kudos\Helpers\Settings;
use Kudos\Helpers\Campaigns;
use Kudos\Service\TwigService;
class KudosButton {
......@@ -62,7 +62,7 @@ class KudosButton {
*/
private $campaign_label;
/**
* @var mixed
* @var string
*/
private $donation_type;
......@@ -85,21 +85,21 @@ class KudosButton {
$this->label = $atts['button_label'];
$this->alignment = $atts['alignment'];
if(isset($atts['campaign_id'])) {
$campaign = Settings::get_campaign($atts['campaign_id']);
}
// Set campaign according to atts and if none found or empty then set as default
if(!empty($atts['campaign_id'])) $campaign = Campaigns::get_campaign($atts['campaign_id']);
if(empty($campaign)) $campaign = Campaigns::get_campaign('default');
$this->address = [
'enabled' => !empty($campaign['address_enabled']) ?? false,
'required' => !empty($campaign['address_required']) ?? false
];
$this->donation_type = isset($campaign['donation_type']) ? $campaign['donation_type'] : 'both';
$this->title = isset($campaign['modal_title']) ? $campaign['modal_title'] : '' ;
$this->text = isset($campaign['welcome_text']) ? $campaign['welcome_text'] : '' ;
$this->amount_type = isset($campaign['amount_type']) ? $campaign['amount_type'] : '' ;
$this->fixed_amounts = isset($campaign['fixed_amounts']) ? $campaign['fixed_amounts'] : '' ;
$this->campaign_label = !empty($campaign['id']) ? $campaign['id'] : 'default';
$this->donation_type = !empty($campaign['donation_type']) ? $campaign['donation_type'] : 'both';
$this->title = !empty($campaign['modal_title']) ? $campaign['modal_title'] : '' ;
$this->text = !empty($campaign['welcome_text']) ? $campaign['welcome_text'] : '' ;
$this->amount_type = !empty($campaign['amount_type']) ? $campaign['amount_type'] : '' ;
$this->fixed_amounts = !empty($campaign['fixed_amounts']) ? $campaign['fixed_amounts'] : '' ;
}
......
<?php
namespace Kudos\Helpers;
class Campaigns {
/**
* Adds default campaign
*
* @since 2.3.0
*/
public static function add_default() {
$default_campaign[0] = [
'id' => 'default',
'slug' => 'default',
'name' => 'Default',
'modal_title' => 'Hello',
'welcome_text' => 'Welcome text',
'address_required' => true,
'amount_type' => 'both',
'fixed_amounts' => '1,5,20,50',
'donation_type' => 'both',
'protected' => true
];
if(empty(Settings::get_setting('campaigns'))) update_option(Settings::PREFIX . 'campaigns', $default_campaign);
}
/**
* Gets the campaign by specified column (e.g slug)
*
* @param string $value
* @param string $column
*
* @return array|null
* @since 2.3.0
*/
public static function get_campaign( string $value, $column = 'slug' ): ?array {
$forms = Settings::get_setting('campaigns');
$key = array_search($value, array_column($forms, $column));
// Check if key is an index and if so return index from forms
if(is_int($key)) {
return $forms[$key];
}
return null;
}
}
......@@ -164,6 +164,9 @@ class Settings {
'items' => [
'type' => 'object',
'properties' => [
'id' => [
'type' => 'int'
],
'slug' => [
'type' => 'string'
],
......@@ -219,6 +222,9 @@ class Settings {
// Loop through each of the options sanitizing the data
foreach ($forms as $key=>$form) {
if(!array_search('id', $form)) $output[$key]['id'] = uniqid('kc_');
foreach ($form as $option=>$value) {
switch ($option) {
......@@ -256,27 +262,6 @@ class Settings {
}
/**
* Gets the campaign by slug name
*
* @param string $slug
*
* @return array|null
*/
public static function get_campaign( string $slug ): ?array {
$forms = self::get_setting('campaigns');
$key = array_search($slug, array_column($forms, 'slug'));
// Check if key is an index and if so return index from forms
if(is_int($key)) {
return $forms[$key];
}
return null;
}
/**
* Update specified setting
*
......@@ -322,20 +307,6 @@ class Settings {
}
}
$default_campaign[0] = [
'slug' => 'kudos_default_campaign',
'name' => 'Default',
'modal_title' => 'Hello',
'welcome_text' => 'Welcome text',
'address_required' => true,
'amount_type' => 'both',
'fixed_amounts' => '1,5,20,50,100',
'donation_type' => 'both',
'protected' => true
];
add_option(self::PREFIX . 'campaigns', $default_campaign);
}
/**
......
......@@ -6,6 +6,7 @@ use Kudos\Entity\CampaignEntity;
use Kudos\Entity\DonorEntity;
use Kudos\Entity\SubscriptionEntity;
use Kudos\Entity\TransactionEntity;
use Kudos\Helpers\Campaigns;
use Kudos\Helpers\Settings;
/**
......@@ -218,6 +219,7 @@ class ActivatorService {
$settings = new Settings();
$settings->add_defaults();
Campaigns::add_default();
}
}
import { CampaignPanel } from "./CampaignPanel"
const { __, sprintf } = wp.i18n;
const { PanelBody, BaseControl, TextControl, Button } = wp.components;
const { PanelBody, TextControl, Button } = wp.components;
const { useState } = wp.element;
const AddCampaignPanel = ( props ) => {
const [ addFormValue, setAddFormValue ] = useState('');
const [ buttonDisabled, setButtonDisabled ] = useState(true);
let current = props.settings._kudos_campaigns;
const addCampaign = ( name ) => {
let current = props.settings._kudos_campaigns;
const isValid = ( value ) => {
// Bail if name is empty
if( '' === name.trim() ) {
props.showNotice(__('Campaign name empty.', 'kudos-donations'))
return;
if( '' === value.trim() || current.find( x => x.name.toLowerCase() === value.toLowerCase().trim() ) ) {
setButtonDisabled(true)
return false;
}
// Bail if duplicate found
if(current.find( x => x.name.toLowerCase() === name.toLowerCase().trim() )) {
props.showNotice(__('Duplicate campaign name', 'kudos-donations'))
return;
}
return true
}
const updateValue = ( value ) => {
setAddFormValue( value );
setButtonDisabled(!isValid(value));
}
const addCampaign = ( name ) => {
// Add new campaign with defaults to top of array using unshift
current.unshift({
current.push({
slug: name,
name: name,
modal_title: __( 'Support us!', 'kudos-donations' ),
......@@ -43,35 +49,35 @@ const AddCampaignPanel = ( props ) => {
return (
<div>
<PanelBody
title={ __( 'Campaigns', 'kudos-donations' ) }
initialOpen={ true }
title={ __( 'Add a campaign', 'kudos-donations' ) }
opened={ true }
>
<BaseControl
<TextControl
label={ __(
'Campaign name',
'kudos-donations'
) }
help={__("Give your campaign a unique name to identify it.", 'kudos-donations')}
id={'kudos_new_campaign'}
className={'kd-inline'}
type={ 'text' }
value={ addFormValue }
onChange={ (newValue) => updateValue( newValue ) }
/>
<br/>
<Button
isPrimary
isSmall
disabled={ buttonDisabled }
onClick={
() => addCampaign(document.getElementById('kudos_new_campaign').value)
}
>
<TextControl
label={ __(
'Add campaign',
'kudos-donations'
) }
id={'kudos_new_campaign'}
className={'kd-inline'}
type={ 'text' }
value={ addFormValue }
onChange={ (newValue) => setAddFormValue( newValue ) }
/>
<Button
isPrimary
isSmall
onClick={
() => addCampaign(document.getElementById('kudos_new_campaign').value)
}
>
{__('Add campaign', 'kudos-donations')}
</Button>
</BaseControl>
{__('Add campaign', 'kudos-donations')}
</Button>
</PanelBody>
......@@ -79,7 +85,7 @@ const AddCampaignPanel = ( props ) => {
return(
<CampaignPanel
key={ form.name }
key={ form.slug }
allowDelete={ !form.protected }
settings={ props.settings }
campaign={ props.settings._kudos_campaigns[i] }
......
const { __ } = wp.i18n;
const { PanelBody, ToggleControl, CheckboxControl, PanelRow } = wp.components;
const AddressFieldPanel = (props ) => {
return (
<PanelBody
title={ __( 'Address field', 'kudos-donations' ) }
initialOpen={ false }
>
<PanelRow>
<ToggleControl
label={__("Enable", 'kudos-donations')}
checked={ props.settings._kudos_address_enabled || '' }
onChange={ ( value ) => props.handleInputChange( '_kudos_address_enabled', value ) }
/>
</PanelRow>
{ props.settings._kudos_address_enabled ?
<PanelRow>
<CheckboxControl
label={__("Required", "kudos-donations")}
checked={ props.settings._kudos_address_required || '' }
onChange={ ( value ) => props.handleInputChange( '_kudos_address_required', value ) }
/>
</PanelRow>
: '' }
</PanelBody>
);
};
export { AddressFieldPanel };
const { __ } = wp.i18n;
const { CheckboxControl, PanelBody, BaseControl, RadioControl, ToggleControl, TextControl, Button } = wp.components;
const { useState } = wp.element;
const {
BaseControl,
Button,
CheckboxControl,
ClipboardButton,
Flex,
PanelBody,
RadioControl,
TextControl,
ToggleControl
} = wp.components;
const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleInputChange, allowDelete = false } ) => {
const saveCampaigns = () => {
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
}
const [ hasCopied, setHasCopied ] = useState( false )
const removeCampaign = ( slug ) => {
let current = settings._kudos_campaigns
......@@ -35,7 +44,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
value={ campaign.modal_title || '' }
onChange={ (value) => {
campaign.modal_title = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
} }
/>
......@@ -47,7 +56,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
value={ campaign.welcome_text || '' }
onChange={ (value) => {
campaign.welcome_text = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
} }
/>
......@@ -64,7 +73,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
checked={ campaign.address_enabled || '' }
onChange={ (value) => {
campaign.address_enabled = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
} }
/>
......@@ -75,7 +84,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
checked={ campaign.address_required || '' }
onChange={ (value) => {
campaign.address_required = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
}}
/>
......@@ -98,7 +107,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
] }
onChange={ (value) => {
campaign.donation_type = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
}}
/>
......@@ -114,7 +123,7 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
] }
onChange={ (value) => {
campaign.amount_type = value
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
}}
/>
......@@ -130,25 +139,41 @@ const CampaignPanel = ( { settings, campaign, showNotice, updateSetting, handleI
if(valuesArray.length <= 4) {
campaign.fixed_amounts = value.replace(/[^,0-9]/g, '')
}
saveCampaigns()
handleInputChange('_kudos_campaigns', settings._kudos_campaigns)
}}
/>
: '' }
{ allowDelete ?
<Flex>
<ClipboardButton
isPrimary
isSmall