Skip to content

Commit

Permalink
Merge pull request #190 from GravityKit/feature/189-add-a-unique-key-…
Browse files Browse the repository at this point in the history
…when-embedding-shortcode

Add a unique key when embedding shortcode
  • Loading branch information
mrcasual committed Mar 8, 2024
2 parents 1569e4f + 961fa07 commit bbc16f3
Show file tree
Hide file tree
Showing 11 changed files with 499 additions and 169 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ phpunit.xml.dist export-ignore
README.md export-ignore
strauss.phar export-ignore
build export-ignore
tests

/.circleci export-ignore
/.github export-ignore
Expand Down
15 changes: 15 additions & 0 deletions public/css/gravityexport-lite.css
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,18 @@ fieldset.gk-gravityexport-download-file .gform-settings-panel__content {
border-bottom: 1px solid #ebebf2;
padding-bottom: 10px;
}

.gform-settings-panel .copy-short-code {
display: flex;
justify-content: space-between;
align-items: center;
}

.gform-settings-panel .copy-short-code .input {
flex: 1;
margin-right: 1rem;
}

.gform-settings-panel .copy-short-code .success {
margin-right: 1rem;
}
169 changes: 101 additions & 68 deletions public/js/gravityexport-lite.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,103 @@
var gfexcel_sortable;

(function ($) {
var updateLists = function ($elements) {
$elements.each(function (i, el) {
var $input = $(el).prevAll('input[type=hidden]');
$input.val($(el).sortable('toArray', {attribute: 'data-value'}).join(','));
})
};

gfexcel_sortable = function (elements, connector_class) {
var $elements = $(elements);
var labels_i10n = typeof gravityexport_lite_strings !== 'undefined'
? gravityexport_lite_strings
: {'enable': 'Enable all', 'disable': 'Disable all'}; // Fallback to English

$elements.each(function () {
var $list = $(this);
var send_to = '#' + $list.data('send-to');
var label = send_to.indexOf('enabled') > 0 ? labels_i10n.enable : labels_i10n.disable;
var $move_all_button = $('<button type="button">' + label + '</button>');

$move_all_button
// Add css via JS to hit add-ons.
.css({
background: 'none',
border: 0,
float: 'right',
marginTop: '-30px',
color: '#3e7da6',
cursor: 'pointer'
})
// Move all items to the `send-to` list when clicked.
.on('click', function () {
$list.find('li').appendTo($(send_to));
$elements.sortable('refresh');
updateLists($elements);
});

// Add the button before the list.
$(this).before($move_all_button);
});

$elements.sortable({
connectWith: '.' + connector_class,
update: function () {
updateLists($elements);
}
}).disableSelection();

$elements
.on('click', '.move', function () {
var element = $(this).closest('li');
var send_to = '#' + element.closest('ul').data('send-to');
element.appendTo($(send_to));
setTimeout(function () {
element.addClass('light-up');
setTimeout(function () {
element.removeClass('light-up');
}, 200);
}, 10);
$elements.sortable('refresh');
updateLists($elements);
});
};

$(document).ready(function () {
$("#start_date, #end_date").datepicker({dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true});
});
})(jQuery);
( function ( $ ) {
var updateLists = function ( $elements ) {
$elements.each( function ( i, el ) {
var $input = $( el ).prevAll( 'input[type=hidden]' );
$input.val( $( el ).sortable( 'toArray', { attribute: 'data-value' } ).join( ',' ) );
} )
};

gfexcel_sortable = function ( elements, connector_class ) {
var $elements = $( elements );
var labels_i10n = typeof gravityexport_lite_strings !== 'undefined'
? gravityexport_lite_strings
: { 'enable': 'Enable all', 'disable': 'Disable all' }; // Fallback to English

$elements.each( function () {
var $list = $( this );
var send_to = '#' + $list.data( 'send-to' );
var label = send_to.indexOf( 'enabled' ) > 0 ? labels_i10n.enable : labels_i10n.disable;
var $move_all_button = $( '<button type="button">' + label + '</button>' );

$move_all_button
// Add css via JS to hit add-ons.
.css( {
background: 'none',
border: 0,
float: 'right',
marginTop: '-30px',
color: '#3e7da6',
cursor: 'pointer'
} )
// Move all items to the `send-to` list when clicked.
.on( 'click', function () {
$list.find( 'li' ).appendTo( $( send_to ) );
$elements.sortable( 'refresh' );
updateLists( $elements );
} );

// Add the button before the list.
$( this ).before( $move_all_button );
} );

$elements.sortable( {
connectWith: '.' + connector_class,
update: function () {
updateLists( $elements );
}
} ).disableSelection();

$elements
.on( 'click', '.move', function () {
var element = $( this ).closest( 'li' );
var send_to = '#' + element.closest( 'ul' ).data( 'send-to' );
element.appendTo( $( send_to ) );
setTimeout( function () {
element.addClass( 'light-up' );
setTimeout( function () {
element.removeClass( 'light-up' );
}, 200 );
}, 10 );
$elements.sortable( 'refresh' );
updateLists( $elements );
} );
};

$( document ).ready( function () {
const $embedShortcodeEl = $( '#embed_code' );
const secret = $embedShortcodeEl.data( 'secret' );

$( '#start_date, #end_date' ).datepicker( { dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true } );

$( '#file_extension' ).on( 'change', function () {
const shortcode = $embedShortcodeEl.val();
const has_type = shortcode.match( / type=/ );
const regex = has_type ? / type="[^"]*"/ : /]$/;

let type = ` type="${ $( this ).val() }"`;

if ( !has_type ) {
type += ']';
}

$embedShortcodeEl.val( shortcode.replace( regex, type ) );
} );

$( '#has_embed_secret' ).on( 'change', function () {
let embedShortcode = $embedShortcodeEl.val();

if ( !embedShortcode ) {
return;
}

if ( $( this ).is( ':checked' ) ) {
embedShortcode = embedShortcode.replace( /]$/, ` secret="${ secret }"]` );
} else {
embedShortcode = embedShortcode.replace( / secret="[^"]+"/, '' );
}

$embedShortcodeEl.val( embedShortcode );
} );
} );
} )( jQuery );
5 changes: 5 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ You can hide a row by adding a hook. Checkout this example:

== Changelog ==

= develop =

* Enhancement: Added security by requiring a secret for embedding the download link shortcode
* Enhancement: Added embed shortcode copy section

= 2.1.0 on September 25, 2023 =

* Bugfix: Data from the old nested form could be exported if the nested form was changed.
Expand Down
5 changes: 4 additions & 1 deletion src/Action/DownloadUrlEnableAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@ public function fire( \GFAddOn $addon, array $form ): void {
return;
}

[ , , $settings ] = $form;
$settings = $form[2] ?? [];

if ( ! empty( $settings['hash'] ?? null ) ) {
// Feed is already enabled.
return;
}

// Enable embed secret by default.
$form[2]['has_embed_secret'] = 1;

parent::fire( $addon, $form );
}
}
39 changes: 39 additions & 0 deletions src/Addon/GravityExportAddon.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use GFExcel\Field\SeparableField;
use GFExcel\GFExcel;
use GFExcel\GFExcelOutput;
use GFExcel\GravityForms\Field\CopyShortcode;
use GFExcel\GravityForms\Field\DownloadFile;
use GFExcel\GravityForms\Field\DownloadUrl;
use GFExcel\GravityForms\Field\SortFields;
Expand Down Expand Up @@ -167,6 +168,7 @@ public function feed_settings_fields(): array {
Fields::register( 'download_file', DownloadFile::class );
Fields::register( 'download_url', DownloadUrl::class );
Fields::register( 'sort_fields', SortFields::class );
Fields::register( 'copy_shortcode', CopyShortcode::class );

$form = $this->get_current_form();

Expand Down Expand Up @@ -212,6 +214,12 @@ public function feed_settings_fields(): array {
'type' => 'download_url',
'assets_dir' => $this->assets_dir,
],
[
'label' => esc_html__( 'Embed shortcode', 'gk-gravityexport-lite' ),
'name' => 'copy_shortcode',
'type' => 'copy_shortcode',
'embed_type' => $this->get_setting( 'file_extension' ),
],
[
'label' => esc_html__( 'Custom Filename', 'gk-gravityexport-lite' ),
'type' => 'text',
Expand Down Expand Up @@ -273,6 +281,19 @@ public function feed_settings_fields(): array {
'collapsible' => true,
'title' => __( 'Security Settings', 'gk-gravityexport-lite' ),
'fields' => [
[
'name' => 'has_embed_secret',
'label' => esc_html__( 'Secure Shortcodes', 'gk-gravityexport-lite' ),
'type' => 'checkbox',
'description' => __( 'A secure shortcode contains a unique <code>secret</code>-attribute which prevents generating the URL for a form without permission.', 'gk-gravityexport-lite' ),
'choices' => [
[
'name' => 'has_embed_secret',
'label' => esc_html__( 'Enable secure embed shortcode', 'gk-gravityexport-lite' ),
'value' => '1',
],
],
],
[
'name' => 'is_secured',
'label' => esc_html__( 'Download Permissions', 'gk-gravityexport-lite' ),
Expand Down Expand Up @@ -1103,4 +1124,22 @@ public function useAdminLabels(): bool {
(bool) $this->get_plugin_setting( 'use_admin_label' )
);
}

/**
* @inheritDoc
* @since $ver$
*/
public function get_current_settings(): array {
$settings = parent::get_current_settings();

$feed = $this->get_feed( $this->get_default_feed_id( rgget( 'id' ) ) );
if ( ! $feed ) {
return $settings;
}

// Prevent hash from being overwritten with an input value.
$settings['hash'] = rgars( $feed, 'meta/hash', $settings['hash'] ?? '' );

return $settings;
}
}
76 changes: 76 additions & 0 deletions src/GravityForms/Field/CopyShortCode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace GFExcel\GravityForms\Field;

use Gravity_Forms\Gravity_Forms\Settings\Fields\HTML;
use GFExcel\Shortcode\DownloadUrl;

/**
* A field that contains the embed shortcode for this feed, with a copy to clipboard button.
* @since $ver$
*/
final class CopyShortcode extends HTML {
/**
* @inheritdoc
* @since $ver$
*/
public $type = 'copy_shortcode';

/**
* @since $ver$
* @var null|string
*/
protected $embed_type;

/**
* @inheritdoc
* @since $ver$
*/
public function scripts(): array {
$script = <<<JS
(function($) {
$( document ).ready(function() {
addClipboard('%s','%s');
});
})(jQuery);
JS;

return [
[
'handle' => 'gk-gravityexport-clipboard-js',
'callback' => function () use ( $script ) {
wp_add_inline_script(
'gk-gravityexport-clipboard-js',
sprintf(
$script,
esc_attr( '#copy-embed-code' ),
esc_attr__( 'The shortcode has been copied to your clipboard.', 'gk-gravityexport-lite' )
)
);
},
'deps' => [ 'jquery', 'wp-a11y', 'wp-i18n', 'clipboard' ],
],
];
}

/**
* @inheritDoc
* @since $ver$
*/
public function markup(): string {
$form_id = (int) rgget( 'id' );
$shortcode = esc_attr( DownloadUrl::generate_embed_short_code( $form_id, $this->embed_type ) );
$secret = DownloadUrl::get_secret( $form_id );
$copy_shortcode = esc_html__( 'Copy Shortcode', 'gk-gravityexport-lite' );

return <<<HTML
<div class="copy-short-code copy-to-clipboard-container">
<div class="input"><input type="text" readonly value="{$shortcode}" id="embed_code" data-secret="{$secret}"></div>
<div class="success hidden" aria-hidden="true">Copied!</div>
<button id="copy-embed-code" type="button" class="button" data-clipboard-target="[id=embed_code]">
<span class="dashicons dashicons-clipboard"></span> {$copy_shortcode}
</button>
</div>
HTML;
}
}
4 changes: 3 additions & 1 deletion src/GravityForms/Field/DownloadUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ public function scripts(): array {
return confirm("%s");
});
addClipboard('%s','%s');
if ( 'function' === typeof addClipboard ) {
addClipboard('%s','%s');
}
});
})(jQuery);
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceProvider/AddOnProvider.php