#StackBounty: #php #plugin-development #functions #headers #nonce Reliable way to add nonce to HTTP Header in WordPress?

Bounty: 50

I am trying to implement CSP on my wordpress site.

Inspired by this question, https://stackoverflow.com/questions/50002041/adding-nonce-to-script-tag I tried to build a way to add nonces to my wordpress site.

add_action( 'run_custom_nonce_value', 'custom_nonce_value' );
function custom_nonce_value () {
    $created_nonce = wp_create_nonce();
    define( 'NONCE_RANDVALUE', $created_nonce ); 
}

This function was directly taken from the Stackoverflow link mentioned above.

It created Nonce Values using wp_create_nonce()

The major problem is that it creates a nonce but doesn’t update it. Refreshing my wordpress site still shows the same nonce.

could global $variable be better option instead of define?

Anyways, after that the below code is slightly modified and adds the nonce to headers using WP actions and adds nonce to all scripts that are registered.

add_filter( 'script_loader_tag', 'add_nonce_to_script', 10, 3 );
function add_nonce_to_script( $tag, $handle, $source ) {
    custom_nonce_value();
    $val_nonce = NONCE_RANDVALUE;
    $search = "type='text/javascript'";
    $replace = "type='text/javascript' nonce='".$val_nonce."' ";
    $subject = $tag;

    $output = str_replace($search, $replace, $subject);
    return $output;
}

function pagely_security_headers($headers) {
    custom_nonce_value();
    $val_nonce = NONCE_RANDVALUE;
    $headers['X-Content-Security-Policy'] = "default-src 'self'; script-src unsafe-hashes 'self' https://milyin.com 'nonce-" . $val_nonce . "' https:; object-src 'none';base-uri 'none';img-src https: data:;style-src 'self' 'unsafe-inline' https:;report-uri https://milyin.com/?csp=true";
    return $headers;

}
add_filter( 'wp_headers', 'pagely_security_headers' );


So, we need to solve 2 things.

1.) It does not update the value of nonce, refreshing page and opening new tab still use the same value of nonce, diluting the entire purpose of nonces.

2.) A better way to echo the nonce elsewhere as I want inline scripts not registered in WordPress to also have the nonce.

Also, I read CSP requires base64 nonces, are these nonces base64?


Get this bounty!!!

#StackBounty: #plugin-development #shortcode Using a custom shortcode from within the template of a shortcode plugin

Bounty: 100

I’ve written a custom plugin, ta-intentclicks which is used as a shortcode:

[ta-intentclicks count="3" category="SEC-EDR"...]

Within this shortcode I’d like to use another shortcode that I can use as a helper. For example; in one of the PHP templates within my plugin.

[ta-intentclicks-link url="$list_item['link']"]Visit website[/ta-intentclicks-link]
[ta-intentclicks-link url="$list_item['link']"]<img src="foo" />[/ta-intentclicks-link]

Which would output this:

<a href="<the URL>" rel="sponsored" target="_blank" class="icp-list-link">Visit website</a>
<a href="<the URL>" rel="sponsored" target="_blank" class="icp-list-link"><img src="foo" /></a>

Here’s a quick directory snapshot to help illustrate my question.
enter image description here

The plugin entry point is includes/class-ta-intentclicks.php which defines the shortcode and runs it, calling the Layout class along the way.

class TaIntentClicks {

    function __construct() {
        add_shortcode('ta-intentclicks', array($this, 'run'));
    }

    function run($attributes = []) {
        ... do some stuff
        return $this->layout->render($response, $layoutAttributes, $dataAttributes);
    }

}

class TAIntentClicksLayout {
    function parse($stuff, $template) {

        ob_start();
        $output = '';
        include $template;
        $output = ob_get_contents();
        ob_end_clean();
        return $output;
    }

    function render($response, $layoutAttributes, $dataAttributes) {

        return $this->parse(
            $response,
            $layoutAttributes,
            $this->getTemplate($layoutAttributes),
            $dataAttributes
        );
    }
}

I’ve seen examples of people calling "do_shortcode" to execute a shortcode, but I’m unclear where the shortcode function goes in my case, OR where to place the "do_shortcode" call.

Can anyone offer guidance here? This is my first plugin and I’m a bit lost as to how and implement this functionality. Thanks in advance.


Get this bounty!!!

#StackBounty: #plugin-development #woocommerce Can woocommerse be used dynamically for billing from another plugin for payment processi…

Bounty: 50

I’m working on a plugin and rather than write my own payment processing code I was wondering if I could leverage woocommerce to do this. My plugin handles what amounts to rental spaces and all the custom management stuff is done with my plugin. It would be nice if there is a way for woocommerce to just to collect and log payments for my plugin. Is this possible? Most of the examples I’ve found about the API seem to apply to remote API use for woocommerce.

Thanks


Get this bounty!!!

#StackBounty: #plugins #plugin-development #customization #javascript #jquery Override a function on editor.js file on Elementor

Bounty: 50

I’m working on a Elementor Project, I need urgent help to add few devices here. Since, ‘editor.min.js’ is on Elementor core file, but I need to add/Override few lines on this file.

What I’ve doing –

    $wpse_devices = array(
       'new_device'  =>'.addDevice('WPSE', i.650)'
    );
    wp_localize_script( 'elementor-editor', 'wpse_editor', $wpse_devices );

Current Version is /*! elementor - v2.9.14 - 21-07-2020 */

On line#9738

  initStylesheet: function initStylesheet() {
    var breakpoints = elementorFrontend.config.breakpoints;
    this.stylesheet = new Stylesheet();
    this.stylesheet.addDevice('mobile', 0).addDevice('tablet', breakpoints.md).addDevice('desktop', breakpoints.lg);
  }

I need it to Override this method on my project. It should be like –

  initStylesheet: function initStylesheet() {
    var breakpoints = elementorFrontend.config.breakpoints;
    this.stylesheet = new Stylesheet();
    this.stylesheet
       .addDevice('mobile', 0)
       .addDevice('tablet', breakpoints.md)
       .addDevice('desktop', breakpoints.lg)
       + wpse_editor.new_device;
  }

I’ve tried to find out many ways, but no luck. This file built with Webpack and Reactjs.
Any help will save me.


Get this bounty!!!

#StackBounty: #plugin-development #javascript #block-editor How to control an elements classes from multiple Gutenberg sidebar controls?

Bounty: 50

I am trying to extend the core/table block and copy-pasted, trail and errored me into something that is close to what I am trying to do. But I it’s not quite working as I like.

I like to extend the Block to have toggle elements that control the classes on the <table> the block already does this for two base classes but I want it to work with Bootstrap CSS tables.

The original Block code can be found here.

What I like to do is something Gutenberg also does great and for the table block is does so for the style. When you set it to ‘Striped’ it will add a is-style-striped to the block. It will live update the field and as soon as you manually remove the class it will automatically switch the style to ‘Default’. I like to link a few class toggles to a text field like that. I searched a little in GB code but could not find where or how it’s done. The buildTableClasses function that uses classnames/dedupe could be a way but there are a few issues here.

                        <ToggleControl
                            label={ __( 'Hover' ) }
                            checked={ !! tableHover }
                            onChange={ () => props.setAttributes( {
                                tableHover: ! tableHover,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
  1. I do not really understand the negation and double negation used here. This code is based off some tutorial I found. Currently, is behaves weird. Like inverted, classes get added when the toggles are off, but also when toggling another toggle that last class sticks, some weird. I experimented with it but it broke completely, so I posted it this way.
  2. The background class for the table that the block already has originally does not end up in the ‘table classes’ text control field.
  3. When I remove a class manually from the field the changes are not bound to the toggles. So I like to find a way to make this work. I could write a function for it but I like to know if there is maybe a better way to do all this. Probably better to reuse some GB core code or model the code after it. If you can point be into the right direction that would be great.
  4. I like to know how I can extend an already existing section, like adding new controls to it. Or removing a section like the style section that makes. Because Bootstrap has so many classes that control style that can be combined the combination of styles would be huge so class toggles is probably a better way to do it.
  5. During playing around with this I noticed that it sometimes broke the block and GB seems to do some checks of the output and was actually unable to restore the block. So I wonder if I should rather fork the block but it would be annoying to maintain. But if an extended block breaks users blocks when the filters come in or get removed later breaks this solution it not great.

The complete code I have currently. Ready to try plugin on Github. The save function is copy-pasted from GB and modified for the table classes.

import classnames from 'classnames/dedupe';

const wp = window.wp;
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;
const { assign } = window.lodash;
const {
    createHigherOrderComponent,
} = wp.compose;

const {
    Fragment,
} = wp.element;

const {
    RichText,
    InspectorControls,
    getColorClassName,
} = wp.editor;

const {
    PanelBody,
    TextControl,
    ToggleControl,
} = wp.components;

const filterBlocks = ( settings ) => {
    console.log( settings );

    if ( settings.name !== 'core/table' ) {
        return settings;
    }

    const newSettings = {
        ...settings,
        attributes: {
            ...settings.attributes, // spread in old attributes so we don't lose them!
            tableClass: { // here is our new attribute
                type: 'string',
                default: 'table ',
            },
            tableBordered: { // here is our new attribute
                type: 'boolean',
                default: false,
            },
            tableStriped: { // here is our new attribute
                type: 'boolean',
                default: false,
            },
            tableHover: { // here is our new attribute
                type: 'boolean',
                default: true,
            },
        },
        save( { attributes } ) {
            const {
                hasFixedLayout,
                head,
                body,
                foot,
                backgroundColor,
                caption,
                tableBordered,
                tableStriped,
                tableHover,
                tableClass,
            } = attributes;
            const isEmpty = ! head.length && ! body.length && ! foot.length;

            if ( isEmpty ) {
                return null;
            }

            const classes = buildTableClasses( attributes );

            const hasCaption = ! RichText.isEmpty( caption );

            const Section = ( { type, rows } ) => {
                if ( ! rows.length ) {
                    return null;
                }

                const Tag = `t${ type }`;

                return (
                    <Tag>
                        { rows.map( ( { cells }, rowIndex ) => (
                            <tr key={ rowIndex }>
                                { cells.map(
                                    ( { content, tag, scope, align }, cellIndex ) => {
                                        const cellClasses = classnames( {
                                            [ `has-text-align-${ align }` ]: align,
                                        } );

                                        return (
                                            <RichText.Content
                                                className={
                                                    cellClasses ?
                                                        cellClasses :
                                                        undefined
                                                }
                                                data-align={ align }
                                                tagName={ tag }
                                                value={ content }
                                                key={ cellIndex }
                                                scope={
                                                    tag === 'th' ? scope : undefined
                                                }
                                            />
                                        );
                                    }
                                ) }
                            </tr>
                        ) ) }
                    </Tag>
                );
            };

            return (
                <figure>
                    <table className={ classes === '' ? undefined : classes }>
                        <Section type="head" rows={ head } />
                        <Section type="body" rows={ body } />
                        <Section type="foot" rows={ foot } />
                    </table>
                    { hasCaption && (
                        <RichText.Content tagName="figcaption" value={ caption } />
                    ) }
                </figure>
            );
        },
    };

    return newSettings;
};

addFilter(
    'blocks.registerBlockType',
    'example/filter-blocks',
    filterBlocks
);

function buildTableClasses( attributes ) {
    const {
        hasFixedLayout,
        backgroundClass,
        tableStriped,
        tableBordered,
        tableHover,
        tableClass,
    } = attributes;

    const classes = classnames(
        tableClass.split( ' ' ),
        backgroundClass,
        {
            table: true,
            'has-fixed-layout': hasFixedLayout,
            'has-background': !! backgroundClass,
            'table-bordered': tableBordered,
            'table-striped': tableStriped,
            'table-hover': tableHover,
        }
    );

    return classes;
}

const tableClassControl = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        if ( 'core/table' !== props.name ) {
            return (
                <BlockEdit { ...props } />
            );
        }

        const {
            tableStriped,
            tableBordered,
            tableHover,
            tableClass,
        } = props.attributes;

        return (
            <Fragment>
                <BlockEdit { ...props } />
                <InspectorControls>
                    <PanelBody
                        title={ __( 'Table classes' ) }
                        initialOpen={ true }
                    >
                        <ToggleControl
                            label={ __( 'Striped' ) }
                            checked={ !! tableStriped }
                            onChange={ () => props.setAttributes( {
                                tableStriped: ! tableStriped,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <ToggleControl
                            label={ __( 'Bordered' ) }
                            checked={ !! tableBordered }
                            onChange={ () => props.setAttributes( {
                                tableBordered: ! tableBordered,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <ToggleControl
                            label={ __( 'Hover' ) }
                            checked={ !! tableHover }
                            onChange={ () => props.setAttributes( {
                                tableHover: ! tableHover,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <TextControl
                            label={ __( '<table> classes' ) }
                            type="text"
                            value={ tableClass }
                            onChange={ ( value ) =>
                                props.setAttributes( { tableClass: value } )
                            }
                        />
                    </PanelBody>
                </InspectorControls>
            </Fragment>
        );
    };
}, 'tableClassControl' );

addFilter( 'editor.BlockEdit', 'extend-block-example/with-spacing-control', tableClassControl );


Get this bounty!!!

#StackBounty: #plugin-development #javascript #block-editor How to contol an elments classes from multiple Gutenberg sidebar controls?

Bounty: 50

I am trying to extend the core/table block and copy-pasted, trail and errored me into something that is close to what I am trying to do. But I it’s not quite working as I like.

I like to extend the Block to have toggle elements that control the classes on the <table> the block already does this for two base classes but I want it to work with Bootstrap CSS tables.

The original Block code can be found here.

What I like to do is something Gutenberg also does great and for the table block is does so for the style. When you set it to ‘Striped’ it will add a is-style-striped to the block. It will live update the field and as soon as you manually remove the class it will automatically switch the style to ‘Default’. I like to link a few class toggles to a text field like that. I searched a little in GB code but could not find where or how it’s done. The buildTableClasses function that uses classnames/dedupe could be a way but there are a few issues here.

                        <ToggleControl
                            label={ __( 'Hover' ) }
                            checked={ !! tableHover }
                            onChange={ () => props.setAttributes( {
                                tableHover: ! tableHover,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
  1. I do not really understand the negation and double negation used here. This code is based off some tutorial I found. Currently, is behaves weird. Like inverted, classes get added when the toggles are off, but also when toggling another toggle that last class sticks, some weird. I experimented with it but it broke completely, so I posted it this way.
  2. The background class for the table that the block already has originally does not end up in the ‘table classes’ text control field.
  3. When I remove a class manually from the field the changes are not bound to the toggles. So I like to find a way to make this work. I could write a function for it but I like to know if there is maybe a better way to do all this. Probably better to reuse some GB core code or model the code after it. If you can point be into the right direction that would be great.
  4. I like to know how I can extend an already existing section, like adding new controls to it. Or removing a section like the style section that makes. Because Bootstrap has so many classes that control style that can be combined the combination of styles would be huge so class toggles is probably a better way to do it.
  5. During playing around with this I noticed that it sometimes broke the block and GB seems to do some checks of the output and was actually unable to restore the block. So I wonder if I should rather fork the block but it would be annoying to maintain. But if an extended block breaks users blocks when the filters come in or get removed later breaks this solution it not great.

The complete code I have currently. Ready to try plugin on Github. The save function is copy-pasted from GB and modified for the table classes.

import classnames from 'classnames/dedupe';

const wp = window.wp;
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;
const { assign } = window.lodash;
const {
    createHigherOrderComponent,
} = wp.compose;

const {
    Fragment,
} = wp.element;

const {
    RichText,
    InspectorControls,
    getColorClassName,
} = wp.editor;

const {
    PanelBody,
    TextControl,
    ToggleControl,
} = wp.components;

const filterBlocks = ( settings ) => {
    console.log( settings );

    if ( settings.name !== 'core/table' ) {
        return settings;
    }

    const newSettings = {
        ...settings,
        attributes: {
            ...settings.attributes, // spread in old attributes so we don't lose them!
            tableClass: { // here is our new attribute
                type: 'string',
                default: 'table ',
            },
            tableBordered: { // here is our new attribute
                type: 'boolean',
                default: false,
            },
            tableStriped: { // here is our new attribute
                type: 'boolean',
                default: false,
            },
            tableHover: { // here is our new attribute
                type: 'boolean',
                default: true,
            },
        },
        save( { attributes } ) {
            const {
                hasFixedLayout,
                head,
                body,
                foot,
                backgroundColor,
                caption,
                tableBordered,
                tableStriped,
                tableHover,
                tableClass,
            } = attributes;
            const isEmpty = ! head.length && ! body.length && ! foot.length;

            if ( isEmpty ) {
                return null;
            }

            const classes = buildTableClasses( attributes );

            const hasCaption = ! RichText.isEmpty( caption );

            const Section = ( { type, rows } ) => {
                if ( ! rows.length ) {
                    return null;
                }

                const Tag = `t${ type }`;

                return (
                    <Tag>
                        { rows.map( ( { cells }, rowIndex ) => (
                            <tr key={ rowIndex }>
                                { cells.map(
                                    ( { content, tag, scope, align }, cellIndex ) => {
                                        const cellClasses = classnames( {
                                            [ `has-text-align-${ align }` ]: align,
                                        } );

                                        return (
                                            <RichText.Content
                                                className={
                                                    cellClasses ?
                                                        cellClasses :
                                                        undefined
                                                }
                                                data-align={ align }
                                                tagName={ tag }
                                                value={ content }
                                                key={ cellIndex }
                                                scope={
                                                    tag === 'th' ? scope : undefined
                                                }
                                            />
                                        );
                                    }
                                ) }
                            </tr>
                        ) ) }
                    </Tag>
                );
            };

            return (
                <figure>
                    <table className={ classes === '' ? undefined : classes }>
                        <Section type="head" rows={ head } />
                        <Section type="body" rows={ body } />
                        <Section type="foot" rows={ foot } />
                    </table>
                    { hasCaption && (
                        <RichText.Content tagName="figcaption" value={ caption } />
                    ) }
                </figure>
            );
        },
    };

    return newSettings;
};

addFilter(
    'blocks.registerBlockType',
    'example/filter-blocks',
    filterBlocks
);

function buildTableClasses( attributes ) {
    const {
        hasFixedLayout,
        backgroundClass,
        tableStriped,
        tableBordered,
        tableHover,
        tableClass,
    } = attributes;

    const classes = classnames(
        tableClass.split( ' ' ),
        backgroundClass,
        {
            table: true,
            'has-fixed-layout': hasFixedLayout,
            'has-background': !! backgroundClass,
            'table-bordered': tableBordered,
            'table-striped': tableStriped,
            'table-hover': tableHover,
        }
    );

    return classes;
}

const tableClassControl = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        if ( 'core/table' !== props.name ) {
            return (
                <BlockEdit { ...props } />
            );
        }

        const {
            tableStriped,
            tableBordered,
            tableHover,
            tableClass,
        } = props.attributes;

        return (
            <Fragment>
                <BlockEdit { ...props } />
                <InspectorControls>
                    <PanelBody
                        title={ __( 'Table classes' ) }
                        initialOpen={ true }
                    >
                        <ToggleControl
                            label={ __( 'Striped' ) }
                            checked={ !! tableStriped }
                            onChange={ () => props.setAttributes( {
                                tableStriped: ! tableStriped,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <ToggleControl
                            label={ __( 'Bordered' ) }
                            checked={ !! tableBordered }
                            onChange={ () => props.setAttributes( {
                                tableBordered: ! tableBordered,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <ToggleControl
                            label={ __( 'Hover' ) }
                            checked={ !! tableHover }
                            onChange={ () => props.setAttributes( {
                                tableHover: ! tableHover,
                                tableClass: buildTableClasses( props.attributes ),
                            } ) }
                        />
                        <TextControl
                            label={ __( '<table> classes' ) }
                            type="text"
                            value={ tableClass }
                            onChange={ ( value ) =>
                                props.setAttributes( { tableClass: value } )
                            }
                        />
                    </PanelBody>
                </InspectorControls>
            </Fragment>
        );
    };
}, 'tableClassControl' );

addFilter( 'editor.BlockEdit', 'extend-block-example/with-spacing-control', tableClassControl );


Get this bounty!!!

#StackBounty: #plugin-development #theme-development #custom-field #metabox #options Best choice of options/settings framework for plug…

Bounty: 50

My question is what is the best options/settings framework out there now to safely build custom plugin/theme upon? I found the similar question here, but it was asked 7 years ago and definitely, things changed from that time.

I used ACF a lot to manage custom meta fields and creating theme options page. The plugin is great, but the main drawbacks for me are: difficult to translate (clone/repeater field bugs with WPML, manual field translation settings for EVERY field), hard to figure out compatibility issues if included with plugin (what if ACF is already used in theme, what if it’s free version or older PRO version then included etc.)

I also used GenerateWP and https://www.wp-hasty.com/ for settings page options that leverage native WP Settings API and are the best, in my opinion, to not overcomplicate things, but it’s often that I need more advanced fields (map, repeater etc.)

I investigated Meta Box, CMB2, Redux, Options Tree and Titan Framework and can’t decide what is the best to use to include in the plugin/theme. I liked the Redux design fields and also the fact that Titan Framework is called as a class instance (less compatibility issues with other plugins?). The online Meta Box generator is also a cool thing.

So the question is, what is the best framework you like to use/tried?

Thank you and happy coding 🙂


Get this bounty!!!

#StackBounty: #plugins #php #plugin-development #functions #publish HELP: Integrating WP with raw PHP code once published button is hit

Bounty: 50

Hello guys let me just open up, I am not good in both Wp coding, I will like to integrate my wp site so that once the published/update button is hit, it will automatically import external mp3 file to my server and as well change the external mp3 link to the that is just imported to my server, however this has been done, here is the code I used though its a plugin.

class DX_Auto_Save_Images{

    function __construct(){     

        //filter and action hook
        add_filter( 'content_save_pre',array($this,'post_save_images') );   //save images
        add_action( 'admin_menu', array( $this, 'menu_page' ) );        //menu page
        add_filter( 'intermediate_image_sizes_advanced', array( $this, 'remove_tmb' ) );    //remove tmb
        add_action( 'submitpost_box', array( $this, 'submit_box' ) );   //submit_box
        add_action( 'submitpage_box', array( $this, 'submit_box' ) );   //submit_box
    }



    //save post exterior images
    function post_save_images( $content ){
        if( ($_POST['save'] || $_POST['publish']) && ($_POST['DS_switch']!='not_save') ){
            set_time_limit(240);
            global $post;
            $post_id=$post->ID;
            $preg=preg_match_all('/<a.*?href="(.*?)"/',stripslashes($content),$matches);
            if($preg){
                $i = 1;
                foreach($matches[1] as $image_url){
                    if(empty($image_url)) continue;
                    $pos=strpos($image_url,get_bloginfo('url'));
                    if($pos===false){
                        $res=$this->save_images($image_url,$post_id,$i);
                        $replace=$res['url'];
                        $content=str_replace($image_url,$replace,$content);
                    }
                    $i++;
                }
            }
        }
        remove_filter( 'content_save_pre', array( $this, 'post_save_images' ) );
        return $content;
    }



    //save exterior images
    function save_images($image_url,$post_id,$i){
        $file=file_get_contents($image_url);

                $_filter = true; // For the anonymous filter callback below.
add_filter( 'upload_dir', function( $arr ) use( &$_filter ){
    if ( $_filter ) {


         $arr['path'] = $arr['basedir'] . '/music' .$arr['subdir'];
        $arr['url'] = $arr['baseurl'] . '/music' .$arr['subdir'];



      //  $folder = '/org_logos'; // No trailing slash at the end.
      //  $arr['path'] .= $folder;
      // $arr['url'] .= $folder;
      // $arr['subdir'] .= $folder;




        /*THE BELOW IS FOR IS TO UPLOAD IT TO MUSIC CATEGORY WITHOUT YEAR AND MONTH BY ENTERMASTER. THIS SCRIPT IS WORKING FINE
        $arr['path'] = $arr['basedir'] . '/music';
        $arr['url'] = $arr['baseurl'] . '/music';
        $arr['subdir'] = '/music';
        */
    }

    return $arr;
} );

        $filename=basename($image_url);
        $options = get_option( 'dx-auto-save-images-options' );



        if( $options['chinese']=='yes' ){
          preg_match( '/(.*?)(.w+)$/', $filename, $match );
          $im_name = md5($match[1]).$match[2];      
        }
        else $im_name = $filename;
        $res=wp_upload_bits($im_name,'',$file);
    //  $res=wp_upload_bits($im_name,'',$file);
    //  $attach_id = $this->insert_attachment($res['file'],$post_id);
    //  if( $options['post-tmb']=='yes' && $i==1 ){
        //  set_post_thumbnail( $post_id, $attach_id );
    //  }
        return $res;
        $_filter = false; // Disables the filter.
    }

    //insert attachment
    function insert_attachment($file,$id){
    //  $dirs=wp_upload_dir();
        $filetype=wp_check_filetype($file);
/*      $attachment=array(
        //  'guid'=>$dirs['baseurl'].'/music/'._wp_relative_upload_path($file),
            'post_mime_type'=>$filetype['type'],
            'post_title'=>preg_replace('/.[^.]+$/','',basename($file)),
            'post_content'=>'',
            'post_status'=>'inherit'
        ); */
    //  $attach_id=wp_insert_attachment($attachment,$file,$id);
    //  $attach_data=wp_generate_attachment_metadata($attach_id,$file);
    //  wp_update_attachment_metadata($attach_id,$attach_data);
    //  return $attach_id;
    }

    //menu page
    function menu_page(){
        add_menu_page( 'DX-auto-save-mp3','Auto Import Mp3 File locally', 'manage_options', 'DX-auto-save-mp3', array( $this, 'options_form' ), plugins_url( 'icon.png', __FILE__ ) );
    }

    //options form
    function options_form(){
        $options = $this->save_options();
        include( 'options-form.php' );
    }

    //form bottom action
    function form_bottom(){
?>
    <div id="form-bottom" style="width:650px;border:1px dotted #ddd;background-color:#f7f7f7;padding:10px;margin-top:20px;">
        <p>For more coding by entermaster visit: <a href="https://www.gidiportal.com/" target="_blank">https://www.gidiportal.com</a></p>

    </div>  
<?php
    }

    //save options
    function save_options(){
        if( $_POST['submit'] ){
            $data=array(
                'tmb' => $_POST['tmb'],
                'chinese' => $_POST['chinese'],
                'switch' => $_POST['switch'],
                'post-tmb' => $_POST['post-tmb']
            );
            update_option( 'dx-auto-save-images-options', $data );
        }
        return get_option( 'dx-auto-save-images-options' );
    }

    //remove tmb
    function remove_tmb( $sizes ){
        $options = get_option( 'dx-auto-save-images-options' );
        if( $options['tmb']=='yes' ){
            $sizes = array();
        }
        return $sizes;
    }

    //get_sample_permalink_html
    function submit_box(  ){
        $options = get_option( 'dx-auto-save-images-options' );
        if( $options['switch'] == 'yes' ){
            echo '<span style="padding-bottom:5px;display:inline-block;"><input type="checkbox" name="DS_switch" value="not_save"/> 不保存远程图片.</span>';
        }
    }

}

//new
new DX_Auto_Save_Images();

Though I modified a plugin to get this result working.

Now i want to integrate this code to work with ID3 php music script i already have, so that i can be able to change both the album art, the title of the song and artiste name will just match exactly the one on the wp post title, then the imported external url in the wp content will pass through this php script once the publish button is hit it will just work on the back end and change the link on wordpress editor. here is the below php script, how ever the php part of the script it is working fine if i run it on browser, this is just the index of the script i want to integrate with wp to work together.

<?php
error_reporting(0);
require ( 'getid3/getid3.php' ) ;

require ( 'getid3/join.php' ) ;


if( isset($_POST['submit'])){
$now = time() ;
$default_mp3_directory =  "../wp-content/uploads/music/";
$default_album = "Example.com";
$default_year = date("Y", $now);
$default_genre = "Example.com";
$default_producer = '';
$default_cover = './music.jpg';
$shownUrl = 'https://www.Example.com/wp-content/uploads/music/';
# To the real uploads

$mp3_filepath = trim($_POST['url']);
$mp3_songname = trim($_POST['title']);
$mp3_comment = "Downloaded from Example.com";;
$mp3_artist = trim($_POST['artiste']);
$artiste = $mp3_artist;
$pFilename = trim($_POST['filename']);
$mp3_filename = empty( $pFilename ) ? $mp3_artist.' - '.$mp3_songname : $pFilename;
$mp3_album = empty ( $_POST['album'] )  ? $default_album : trim ( $_POST['album'] );
$mp3_year = empty ( $_POST['year'] ) || !is_numeric($_POST['year']) || strlen($_POST['year']) != 4 ? $default_year : $_POST['year'];
$mp3_genre = empty ( $_POST['genre'] ) ? $default_genre : $_POST['genre'];
$extra = array ( 'year' => $mp3_year, 'genre' => trim($_POST['genre']), 'album' => trim($_POST['album']), 'producer' => ! empty ( $_POST['producer']) ? trim($_POST['producer']) : $default_producer );
$error = '';

# Checking the mp3

if( !filter_var($mp3_filepath, FILTER_VALIDATE_URL)){
$error .= 'Invalid File URL<br>';
} else if ( empty($mp3_filename) OR empty ($mp3_songname) OR empty($mp3_artist)){
$error .= "Fields Marked * Are Required<br>";
} else if ( !file_exists($default_cover) ) {
$error .= 'The Photo Cover Has Not Been Uploaded';
} else {
$timeFolder .= date('Y', $now) . '/' . date('m', $now) . '/';
if(!file_exists($default_mp3_directory . $timeFolder)){ mkdir($default_mp3_directory . $timeFolder, 0777, true); }
$invalidchars = array("'", '"', '.', ',');
$storeName = str_replace($invalidchars, '', $mp3_filename); // . '_[Example.com].mp3';
$storeName = preg_replace('/[^A-Z-a-z0-9-_]/', '_', $storeName);
$storeName = preg_replace("/_{2,}/", "_", $storeName);
$storeName .= '_Example.com_.mp3';
$sname = $default_mp3_directory . $timeFolder . $storeName;
if (file_exists($sname) ) {
$error = 'File Has Alread Been Uploaded As <a href="' . $shownUrl . $timeFolder . $storeName . '">' . $storeName . '</a>';
} else {
if(copy($mp3_filepath, $sname)){
# Rewrite tags
$mp3_tagformat = 'UTF-8';
$mp3_handler = new getID3;
$mp3_handler->setOption(array('encoding'=>$mp3_tagformat));



//Add audio file

$tmp_name= "tmp/$storeName";

copy($sname,$tmp_name);

//$file_go_in[] = "voice.mp3";
$file_go_in[] = $tmp_name;
$file_go_in[] = "voice.mp3";
$file_go_out = $sname;

merge_mp3($file_go_out,$file_go_in);

unlink($tmp_name);





# The writer class
require ( 'getid3/write.php' ) ;

$mp3_writter = new getid3_writetags;


$mp3_writter->filename       = $sname;
$mp3_writter->tagformats     = array('id3v1', 'id3v2.3');
$mp3_writter->overwrite_tags = true;
$mp3_writter->tag_encoding   = $mp3_tagformat;
$mp3_writter->remove_other_tags = true;

$mp3_data['title'][]   = $mp3_songname.' | Example.com';
$mp3_data['artist'][]  = $mp3_artist;
$mp3_data['album'][]   = $mp3_album;
$mp3_data['year'][]    = $mp3_year;
$mp3_data['genre'][]   = $mp3_genre;
$mp3_data['comment'][] = $mp3_comment;
$mp3_data['attached_picture'][0]['data'] = file_get_contents($default_cover);
$mp3_data['attached_picture'][0]['picturetypeid'] = "image/jpeg";
$mp3_data['attached_picture'][0]['description'] = "Downloaded from Example.com";
$mp3_data['attached_picture'][0]['mime'] = "image/jpeg";
$mp3_writter->tag_data = $mp3_data;

if ( $mp3_writter->WriteTags() ) {
$link = $sname ;
$shownUrl .= $timeFolder . $storeName;
} else {
unlink ( $sname );
$error .= "Failed To Write Tags!<br><br><em>" . implode( "<br><br>", $mp3_writter->errors ) . '</em><br>';
}
} else {
$error .= "Unable To Copy File";
}
}
}
}
?> <!DOCTYPE html> <html> 
<meta name="viewport" content="width=device-width, initial-scale=1" />
</html>


<?php if ( isset ( $link ) && ! empty ( $link ) ) { ?>
<div class="successbox">
File Uploaded Successfully
<p class="copy"><input type="text" value="<?php echo $shownUrl; ?>"></p>
</div>

<?php } else {  ?>
<?php if ( ! empty ( $error ) ) { ?>
<div class="error"><?php echo $error; ?></div>
<?php } ?>
<form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
<div>
<div class="dark1"><b><font size="2">Link</font><br></b>
<input type="text" name="url" value="<?php echo $_POST['url']; ?>">
</div></div>

<div>
<div class="dark1"><b><font size="2">Title</font><br></b>
<input type="text" name="title" value="<?php echo $_POST['title']; ?>">
</div>
</div>

<div>
<div class="dark1"><b><font size="2">Artiste</font><br></b>
<input type="text" name="artiste" value="<?php echo $_POST['artiste']; ?>">
</div>

<div>
<div class="dark1"><b>Album<br></b>
<input type="text" name="album" value="Example.com">
</div>
<div>
<div class="dark1"><b>Producer<br></b>
<input type="text" name="producer" value="Example.com">
</div></div>
<div>

<div class="">
<input type="submit" name="submit" value="Upload">
</div>
</form></div>
<?php } ?>
<br />

</body>
</html>


Get this bounty!!!