How to resolve the Composer dependencies conflicts symfony 7 ? Install FOSUserBundle

I’m writing a PHP application based on Symfony v6. Now I want to upgrade Symfony to the 7.0.
And I have problem with install FOSUserBundle
composer require friendsofsymfony/user-bundle "^3.0"

composer require friendsofsymfony/user-bundle "^3.0"
./composer.json has been updated
Running composer update friendsofsymfony/user-bundle
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - friendsofsymfony/user-bundle[v3.0.0, ..., v3.0.2] require symfony/config ^4.4 || ^5.0 -> found symfony/config[v4.4.0, ..., v4.4.44, v5.0.0, ..., v5.4.31] but it conflicts with your root composer.json require (7.0.*).
    - friendsofsymfony/user-bundle[v3.1.0, ..., v3.2.1] require symfony/config ^4.4 || ^5.0 || ^6.0 -> found symfony/config[v4.4.0, ..., v4.4.44, v5.0.0, ..., v5.4.31, v6.0.0, ..., v6.4.0] but it conflicts with your root composer.json require (7.0.*).
    - Root composer.json requires friendsofsymfony/user-bundle ^3.0 -> satisfiable by friendsofsymfony/user-bundle[v3.0.0, ..., v3.2.1].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

Is it possible to install FOSUserBundel for Symfony7?

Uncaught ErrorException: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in even though I am checkng for nulll

I am getting following error on line 42 of my code. But strange thing is I am already checking for null and the actual error seems to be happening on line 44. How to fix this issue?

Error

Uncaught ErrorException: htmlspecialchars(): Passing null to parameter
#1 ($string) of type string is deprecated in /var/www/mysite/mypage.php:42

Code

while($row3 = mysqli_fetch_assoc($result3))
{
   $emailbody .= "<b>Keyword:</b> ". htmlspecialchars($row2["keyword"]) ."<br>";

   if(!is_null($row3["summary"]))     //line 42
   {
      $emailbody .= "<b>Summary:</b> ". htmlspecialchars($row3["summary"]) ."<br>";
   }
}

Woocommerce sale shortcode not showing all updated products from dokan wordpress

We have dokan + woocommerce running platform. Currently when user update sale price from vendor dashboard dokan, its not showing in sale page. Apparently, it shows only product that updates from woocommerce directly. So i created custom sale shortcode but still it works like that not showing all sale products.

Below i attach the custom Shortcode. Meanwhile may i know is there any way can make Woocommerce update the products from third party plugin?

Thanks in advance.

` if( ! function_exists(‘get_preordable_products’) ) {

function get_preordable_products( $atts ) {
    // Shortcode Attributes
    extract( shortcode_atts( array(
        'columns'    => '4',
        'limit'      => '20',
    ), $atts, 'preordable_products' ) );

    // The WP_Query
    $query = new WP_Query( array (
        'post_type'         => 'product',
        'post_status'       => 'publish',
        'posts_per_page'    => $limit,
    ) );

    global $woocommerce_loop;

    $woocommerce_loop['columns']      = $columns;
    $woocommerce_loop['is_shortcode'] = 1;
    $woocommerce_loop['total']        = $query->post_count;
    $woocommerce_loop['total_pages']  = $query->max_num_pages;
    $woocommerce_loop['per_page']     = $limit;

    ob_start();

    if ( $query->have_posts() ) {
        woocommerce_product_loop_start();

        while ( $query->have_posts() ) {
           $query->the_post();
              $id = get_the_ID();
        $_product = wc_get_product();
        if($_product->is_on_sale()){  
         wc_get_template_part( 'content', 'product' );
        }
        }
        woocommerce_product_loop_end();
        woocommerce_reset_loop();
        wp_reset_postdata();
    } else {
        do_action( "woocommerce_shortcode_products_loop_no_results", $atts );

        echo '<p>'. __("Aucun article disponible à la précommande.") . '</p>';
    }

    $content = ob_get_clean();

    return '<div class="woocommerce columns-' . $columns . '">' . $content . '</div>';
}

add_shortcode( 'preordable_products', 'get_preordable_products' );`

}

How I can include all the files in a folder in the $sftp->put?

here is my code:

<?php

require_once('vendor/autoload.php');

use phpseclib3NetSFTP;

$sftp = new SFTP($ftp_server);
$sftp_login = $sftp->login($ftp_user_name, $ftp_user_pass);

$remote_file_path = "remote_folder/";
$local_file_path = "local_folder/";

$sftp->put($remote_file_path, $local_file_path, SFTP::SOURCE_LOCAL_FILE); 

?>

I’m trying to push all the files inside a local folder to be pushed to a remote server.

With this, I’m able to put one file only but not all.
Tried to use a foreach loop but it didn’t work.

Please guide. Thanks!

how to “destroy” and re-render the div that has foreach data in laravel livewire?

so, I have a livewire which the data come from json.gz. so it’s not from model laravel. In this livewire, I need to make custom pagination, custom data form and so on.

So, I have this select option “thing” that can show the data from 1-10 or 1-50 (I have no idea what this is called). the markup is like this :

<div>
    <select wire:change="changeCountRows($event.target.value)" class="form-select form-select-sm form-select-solid w-100px">
        <option value="10">10</option>
        <option value="50">50</option>
        <option value="100">100</option>
    </select>
</div>

the default value is 10. so the data will show 10/page.

now, the problem is that, when I tried to change from 10 to 50/page, it works fine.
but, when try to “descreased” it, for example form 50 to 10/page, the div ‘data view’ it still show 50. however, the data/rows from 1-10 is changed (so it works when I change the select option thing to 10).

so my problem is that, how to remove this 11-50 rows (remaining data)?

I’ve tried and follow these article :

  • Article 1
  • Article 1
  • and a couple youtube video
  • which basically show me to “refresh” component view using $refresh. but still no luck

here’s my couple function

  • render() :
public function render()
{
    if($this->items_json == null || $this->prev_search !== $this->search) {
        $this->getDatasJson();
        $this->prev_search = $this->search;
    }
    $this->arrayChunkJson($this->items_json, $this->filterEntries);

    if($this->page_custom >= $this->end_page){
        $this->end_page = $this->page_custom+1;
        $this->start_page = $this->page_custom - 4;
    }elseif ($this->page_custom < $this->start_page) {
        $this->start_page = $this->page_custom;
        $this->end_page = $this->page_custom + 5;
    }
    $datas = $this->single_cat[$this->page_custom];
    $this->last_total_cat = array_keys($datas)[0] + 1;
    $this->total_cat_show = $this->last_total_cat + ($this->filterEntries - 1);

    // dd($this->single_cat);
    return view('livewire.kategori.single-kategori-mobile', [
        'single_cats' => $this->single_cat[$this->page_custom],
        'page' => $this->page_custom,
        'total_page' => $this->total_page,
        'start_page' => $this->start_page,
        'end_page' => $this->end_page,
        'total_cat' => $this->total_cat,
        'last_total_cat' => $this->last_total_cat,
        'total_cat_show' => $this->total_cat_show
    ]);
}
  • changeCountRows() :
public function changeCountRows($filterEntries){
    $this->filterEntries = $filterEntries;
    $this->emit('refresh_me');
}
  • listener on top of file :
protected $listeners = ['refresh_me' => '$refresh'];
  • and this is how I fetched it in view :
<div class="flex flex-col" wire:loading.class="loading">
    {{-- @dd(count($single_cats)); --}}
    @foreach($single_cats as $val)
        my data
    @endforeach
</div>

Once again, my only problem is that, how to “remove” the remaining data from view. It’s like the view still “read” the “data chunk”. even tough, in render function, I’been “re-chunk” it with arrayChunkJson() function.

thank you in advance!

Buy Now Button PrestaShop – Attribute refreshing

I have made this Buy Now button on my website and works with number of items selected but how can I make it so it works with attribute selected without putting custom JS?

My code…

<div class="buton-cumpara-acum">
    
{if isset($static_token)}
<a class="button buy_now_button btn btn-default" href="{$link->getPageLink('cart',false, NULL, "add=1&id_product={$product->id|intval}&token={$static_token}", false)|escape:'html':'UTF-8'}" rel="nofollow" title="{l s='Buy Now'}" data-id-product="{$product->id|intval}"  onclick="this.href = this.href+ '&qty='+$('.buy_now_button').closest('form').find('#quantity_wanted').val() + '&ipa='+  $('.buy_now_button').closest('form').find('#idCombination').val(); " >
<span>{l s='Cumpără acum!'}</span>
</a>
{else}
<a class="button buy_now_button btn btn-default" href="{$link->getPageLink('cart',false, NULL, 'add=1&id_product={$product->id|intval}', false)|escape:'html':'UTF-8'}" rel="nofollow" title="{l s='Buy Now'}" data-id-product="{$product->id|intval}" onclick="this.href = this.href+ '&qty='+$('.buy_now_button').closest('form').find('#quantity_wanted').val() + '&ipa='+  $('.buy_now_button').closest('form').find('#idCombination').val(); " >
<span>{l s='Cumpără acum!'}</span>
</a></div>
{/if}
    {/block}  
  {/if}
</div><br>

to add in my code something like $product.id_product_attribute

Thank you!

Laravel: suddenly getting 419 CSRF Token Mismatch errors

I have been getting this error for the laste week on all my axios requests (except first one) on my laravel-vue app, it happens to all my api routes.

I’m attaching csrf token to all my axios requests inside bottstrap.js.

let token = document.head.querySelector('meta[name="csrf-token"]');


if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    console.log('CSRF token found');
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

and added the proper meta-tag to all my blade files:

<meta name="csrf-token" content="{{ csrf_token() }}">

My route/s are all inside api.php file, they don’t have sanctum middleware enabled.

Route::post('/chats/test-endpoint','AppHttpControllersApiChatController@testEndpoint');

Api middlewares:

'api' => [
            'throttle:api',
            IlluminateRoutingMiddlewareSubstituteBindings::class,
            EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            IlluminateRoutingMiddlewareSubstituteBindings::class,
        ],

When I inspect network tab I can see X-XSRF-TOKEN is added to request headers (no X-CRSF-TOKEN though):

Request headers:

Cookie : XSRF-TOKEN = eyJpd...; app_session = eyJpd...

X-XSRF-TOKEN = eyJpd...

Response headers:

Set-Cookie : app_session = eyJpd...

The thing is, when I console log inside my vue component the content of the meta tag token, I get a different one, not sure if this is becauseI get the unencrypted value.

let token = document.head.querySelector('meta[name="csrf-token"]').content;
console.log('token',token);

token gbczby2kuUI1nSMs6AEMsV7tv...

Please help me, this never happened while I was developing my laravel apps.

Reading javascript variables from php: variable is not updating after submit

I have a variable in javascript and i want to access this variable in my php code and assign to other variable and print.

Below is my code, but after click on submit my jvalue variable is not updating with new value (‘inside button click’) after click on submit, its printing old value (‘this is javascript value’) only. but in the alert jvalue is showing “inside button click”…and echo $abc is printing old one…
i want after submit to print jvalue as “inside button click”…

            <html>
            <head>
            <button onclick="myFunction()">Click me</button>

            <form action="speech_to_text_v2.php" method="post" enctype="application/x-www-form-urlencoded">
            <button type="submit" >Submit</button>
                
            </form>

            <!-- </uidiv> -->
            <p id="demo"></p>
            <script>
            var jvalue = 'this is javascript value';

            function myFunction() {
            document.getElementById("demo").innerHTML = "Hello World";
            jvalue='inside button click';
            alert(jvalue);
            }

            </script>
            </body>
            </html>
            <?php $abc= "<script>document.write(jvalue);</script>";
            echo $abc;

            ?>

cURL error 6: getaddrinfo() thread failed to start (PHP – Laravel)

Since several month I get the curl error 6 thread failed to start inside my laravel job queue on all my http call.

I understand that it’s related with the ulimit variable of my server but even with the ulimit set to 2048 I got this error.

It occurs only when code is processed in the job, the same code outside a job works perfectly.

It’s difficult to debug because I can’t reproduce this on local and when I push a new version on the prod, the errors disappears (until it come back hour or days later).

When it show up, the error remain for few minutes or few hours or doesn’t go away (in this case it need a manual restart of the prod).

Like I said, I’ve tried to increase the ulimit variable inside my job, but it doesn’t seems to fix the issue.

Did you ever face with a similar issue ?

Any help will be very appreciate, I’ve been struggle with that for days…

PHP : 8.2
Laravel : 10.35

Prevent order go to processing status if condition is true

I tried many scenarios and hooks and at the end even in child template file for thankyou page

So if order is not failed and global variable == true switch to pending:

<?php if ($order->has_status('failed')) : ?>

//code

<?php else : ?>

<?php if ($GLOBALS['variable'] == true) : ?>


    <?php $order->update_status('pending'); ?>


<?php endif; ?>

Status is changing but the problem is that it is going from processing to pending. How to prevent going to processing status if condition ($GLOBALS[‘variable’]) is true?

Thanks for help,

A

PHPStan: Child process error (exit code 255): PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in

When running PHPStan, I’m getting several error messages:

Child process error (exit code 255): PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in …

PHPStan process crashed because it reached configured PHP memory limit: 128M

See my own answer below.

Building a website from scratch: how to approach a flat file system [closed]

I learned some programming over a decade ago (html, css and php, only a little javascript though), but the web has changed a lot since them.

I want to build myself a website, just a gallery and a simple blog, no other users or anything like that. I’ve tried a couple of different CMS’es over the years, but they’ve either been annoyingly stubborn to work with, didn’t suit my purpose or ended up breaking somehow. I find myself in this odd in-between where I know enough to get things up and running, but not enough to fix them when something goes wrong.

So, I want to go old school, back to basics and just built it myself. It should be possible (plus would be a nice refresher and learning opportunity). I think I’ve got a pretty good handle on the html and css part, but I’m struggling a bit in figuring out how to structure the site and how to store and read data, which is what I’m hoping some of you could help me with.

I don’t want to use a database, mostly because I really like the idea of just opening up VScode, adding or editing a text file, hitting save (I have enabled save-to-server via ftp) and be done with it. I don’t want to log in or use a web-based interface, just write simple text files, manually upload images and add a bit of code where needed to fetch said data.

I imagine having a folder structure like blog > year > row of text files, and in each file have a couple of variables defined with their correlating data like “date”, “title”, “maintext” and so on. Can I use php to fetch the data in these variables from another document? Fx. in blog.php having a piece of code that makes a list (array) of all the text files in the folder, and then for each file output the title and maintext data (aka. have a row of blog posts on the page).

I’m assuming this is possible, but is it the right way to do it? Would javascript be better suited for part of it? Ideally I don’t want to install any libraries or extras on the server, but every guide I’ve come across always includes something like that. I just want to go real simple.

Update: To simplify, what I’m asking is if putting the blog text and relevant data in each their own file, and then fetching the data with php, is a good approach?

Custom gutenberg block fields are empty after refresh the edit page

I created a custom Gutenberg block which was working fine till wp 6.3.2 .

But after updating to 6.4.2 , it is not working.

when i am entering data it is showing the data and post is also updated. But on front end there is no data.

When I refresh the post edit page then also fields are empty.

Ref: I created the block to store and show products from different marketplace.

I set an attribute “products” for the row. and created a form to enter new product row.

here is my js code:

const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { InspectorControls, useBlockProps } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
const { TextControl } = wp.components;
/**
 * Register: custom products Gutenberg Block.
 *
 */
registerBlockType('wp-market/wp-market-products', {
    apiVersion: 2,
    title: __('Manual Products'),
    icon: 'shield',
    attributes: {
        products: {
            type: 'array',
            default: []
        }
    },

    /**
     * The edit function describes the structure of your block in the context of the editor.
     * This represents what the editor will render when the block is used.
     *
     */
    edit: function (props) {
        const { products, newProduct } = props.attributes;
        var blockProps = useBlockProps();

        // to create edit element
        function createEditEl() {
            let data = [];

            // Heading
            data.push(React.createElement(
                "h6",
                null,
                "Manual Products"
            ));

            // entered product
            data.push(React.createElement(
                "div",
                { class: 'product-rows-gutenberg' },
                createGutenbergManualProductRows()
            ));

            // new product
            data.push(React.createElement(
                "div",
                { class: 'new-manual-product-gutenberg' },
                createGutenbergManualProductNew()
            ));

            return data;
        }

        // function  for product rows
        function createGutenbergManualProductRows() {
            let data = [React.createElement("h6", { class: "sub-heading" }, ["Added products"])]
            // rows
            if (products && products.length > 0) {
                products.map((product, index) => {
                    data.push(React.createElement(
                        "div",
                        { className: 'manual-product-row-wrapper' },
                        formatProductRow(product, index)
                    ));
                });
            } else {
                data.push(React.createElement(
                    "div",
                    { className: 'manual-product-row-wrapper no-product' },
                    "No product added"
                ));
            }

            return data;
        }

        // to create product row
        function formatProductRow(product, index) {
            let data = [];

            data.push(
                React.createElement(
                    'div',
                    { 
                        className: 'column column-id'
                    },
                    [
                        product.id ? product.id : '',
                        // edit field
                        createEditField('id',blockProps.id, index, product.id)
                    ]

                )
            );

            data.push(
                React.createElement(
                    'div',
                    { className: 'column column-title' },
                    product.title ? product.title : '',
                    // edit field
                    createEditField('title',blockProps.id, index, product.title)
                )
            );

            data.push(
                React.createElement(
                    'div',
                    { className: 'column column-price' },
                    product.price ? product.price : '',
                    // edit field
                    createEditField('price',blockProps.id, index, product.price)
                )
            );

            data.push(
                React.createElement(
                    'div',
                    { className: 'column column-link' },
                    product.link ? product.link : '',
                    // edit field
                    createEditField('link',blockProps.id, index, product.link)
                )
            );

            if (product.image) {
                data.push(
                    React.createElement(
                        'div',
                        { className: 'column column-image' },
                        [
                            React.createElement(
                                'img',
                                {
                                    src: product.image
                                }
                            ),
                            // edit field
                            createImageEdit(blockProps.id, index)
                        ]
                    )
                );
            } else {
                data.push(
                    React.createElement(
                        'div',
                        { className: 'column column-image no-img' },
                        // edit field
                        createImageEdit(blockProps.id, index)
                    )
                );
            }

            data.push(
                React.createElement(
                    'div',
                    { className: 'column column-store' },
                    product.store ? product.store : '',
                    // edit field
                    createEditField('store',blockProps.id, index, product.store, true)
                )
            );

            //button to delete the row
            data.push(
                React.createElement(
                    'button',
                    { className: '', onClick: function () { products.splice(index, 1); props.setAttributes({ products: products.slice() }); } },
                    '-'
                )
            );

            return data;
        }

        // refresh the image preview
        function refreshGutenbergManualUploadImage(src) {
            let imgEl = document.querySelector('#' + blockProps.id + 'new-image-preview');
            let textEl = document.querySelector('#' + blockProps.id + 'new-image-text');

            if (src.length) {

                imgEl.src = src;
                textEl.classList.add('hidden');
                imgEl.classList.remove('hidden');
            }
            else {
                imgEl.src = '';
                textEl.classList.remove('hidden');
                imgEl.classList.add('hidden');
            }
        }

        // create store options
        function createStoreOptions(value = '') {
            let data = [];
            if (wp_market_block_stores) {
                wp_market_block_stores.map(store => {
                    data.push(
                        React.createElement(
                            'option',
                            {
                                value: store.slug
                            },
                            store.name
                        )
                    );
                })
            }
            return data;
        }

        // editing image
        function createImageEdit(blockId, index){
            return React.createElement(
                'span',
                {
                    className: 'column-edit-button dashicons dashicons-edit',
                    onClick: function (e) {
                        e.preventDefault();
                        var image_frame;
                        if (image_frame) {
                            image_frame.open();
                        }
                        // Define image_frame as wp.media object
                        image_frame = wp.media({
                            title: 'Select Media',
                            multiple: false,
                            library: {
                                type: 'image',
                            }
                        });

                        image_frame.on('close', function () {
                            // On close, get selections and save to the hidden input
                            // plus other AJAX stuff to refresh the image preview
                            var selection = image_frame.state().get('selection');                           
                            var gallery_srcs = new Array();
                            var gallery_ids = new Array();
                            var my_index = 0;
                            selection.each(function (attachment) {
                                gallery_srcs[my_index] = attachment['attributes']['url'];
                                gallery_ids[my_index] = attachment['id'];
                                my_index++;
                            });
                            var srcs = gallery_srcs.join(",");
                            var ids = gallery_ids.join(",");

                            if(srcs){
                                products[index]['image'] = srcs;
                                props.setAttributes({ products: products.slice() });
                            }
                        });

                        image_frame.open();
                    }
                }
            );
        }

        // create edit field
        function createEditField(name, block_id, index, value, isStore = false) {
            return [
                React.createElement(
                    'span',
                    {
                        className: 'column-edit-button dashicons dashicons-edit',
                        onClick: () => showEditColumn(name, block_id, index, value)
                    }
                ),
                React.createElement(
                'div',
                {
                    className:'column-edit-field hidden',
                    id: 'edit-column-' + name + '_block-id_' + block_id + '_index_' + index
                },
                [
                    isStore ?
                    React.createElement(
                        'select',
                        {
                            className: 'edit-column-value'
                        },
                        createStoreOptions()                
                    )
                    :
                    React.createElement(
                        'input',
                        {
                            className: 'edit-column-value'
                        }                   
                    ),
                    React.createElement(
                        'button',
                        {
                            className: 'edit-column-save'
                        },
                        React.createElement(
                            'span',
                            {
                                className: 'dashicons dashicons-yes-alt',
                                onClick: () => saveEditColumn(name, block_id, index)
                            }
                        )
                    ),
                    React.createElement(
                        'button',
                        {
                            className: 'edit-column-cancel'
                        },
                        React.createElement(
                            'span',
                            {
                                className: 'dashicons dashicons-dismiss',
                                onClick: () => cancelEditColumn(name, block_id, index)
                            }
                        )
                    )
                ]
            )
            ]
        }

        // to show the edit field for a column
        function showEditColumn(name, blockId, index, value = '')  {
            let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
            if(field && field.classList.contains('hidden')) {
                field.classList.remove('hidden');
                field.querySelector('.edit-column-value').value = value;
            }
        }

        // to save the changes in edit field
        function saveEditColumn(name, blockId, index){
            let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
            if(field) {
                let newValue = field.querySelector('.edit-column-value').value;
                products[index][name] = newValue;
                field.classList.add('hidden');
                field.querySelector('.edit-column-value').value = '';
            }
            props.setAttributes({ products: products.slice() });
        }
        // to cancel the editing
        function cancelEditColumn(name, blockId, index){
            let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
            if(field) {
                field.classList.add('hidden');
                field.querySelector('.edit-column-value').value = '';
            }
        }

        // create new row
        function createGutenbergManualProductNew() {
            let data = [React.createElement("h6", { class: "sub-heading" }, ["Add new product"])]
            // id
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-id', class: 'manual-product-label' },
                    [
                        React.createElement("span", null, "Product ID"),
                        React.createElement(
                            "input",
                            { type: "text", name: 'manual-product-id', id: blockProps.id + 'new-id' },
                        )
                    ]
                )
            );
            // title
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-title', class: 'manual-product-label' },
                    [
                        React.createElement("span", null, "Title"),
                        React.createElement(
                            "input",
                            { type: "text", name: 'manual-product-title', id: blockProps.id + 'new-title' },
                        )
                    ]
                )
            );
            // price
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-price', class: 'manual-product-label' },
                    [
                        React.createElement("span", null, "Price"),
                        React.createElement(
                            "input",
                            { type: "text", name: 'manual-product-price', id: blockProps.id + 'new-price' },
                        )
                    ]
                )
            );
            // link
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-link', class: 'manual-product-label' },
                    [
                        React.createElement("span", null, "Link"),
                        React.createElement(
                            "input",
                            { type: "url", name: 'manual-product-link', id: blockProps.id + 'new-link' },
                        )
                    ]
                )
            );
            // image
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-image', class: 'manual-product-label image-upload' },
                    [
                        React.createElement("span", null, "Image"),
                        React.createElement(
                            "div",
                            {
                                id: blockProps.id + 'new-image-text',
                                className: 'new-image-text'
                            },
                            'No Image'
                        ),
                        React.createElement(
                            "img",
                            {
                                id: blockProps.id + 'new-image-preview',
                                className: 'hidden preview'
                            }
                        ),
                        React.createElement(
                            "input",
                            {
                                type: "button",
                                name: 'manual-product-image-upload',
                                id: blockProps.id + 'new-image-upload',
                                value: 'Select image',
                                onClick: function (e) {
                                    e.preventDefault();
                                    var image_frame;
                                    if (image_frame) {
                                        image_frame.open();
                                    }
                                    // Define image_frame as wp.media object
                                    image_frame = wp.media({
                                        title: 'Select Media',
                                        multiple: false,
                                        library: {
                                            type: 'image',
                                        }
                                    });

                                    image_frame.on('close', function () {
                                        // On close, get selections and save to the hidden input
                                        // plus other AJAX stuff to refresh the image preview
                                        var selection = image_frame.state().get('selection');
                                        var gallery_srcs = new Array();
                                        var gallery_ids = new Array();
                                        var my_index = 0;
                                        selection.each(function (attachment) {
                                            gallery_srcs[my_index] = attachment['attributes']['url'];
                                            gallery_ids[my_index] = attachment['id'];
                                            my_index++;
                                        });
                                        var srcs = gallery_srcs.join(",");
                                        var ids = gallery_ids.join(",");
                                        document.querySelector('#' + blockProps.id + 'new-image').value = srcs;
                                        refreshGutenbergManualUploadImage(srcs);
                                    });

                                    image_frame.open();
                                }
                            },
                        ),
                        React.createElement(
                            "input",
                            {
                                type: "hidden",
                                name: 'manual-product-image',
                                id: blockProps.id + 'new-image'
                            },
                        )
                    ]
                )
            );
            // store
            data.push(
                React.createElement(
                    "label",
                    { for: blockProps.id + 'new-store', class: 'manual-product-label' },
                    [
                        React.createElement("span", null, "Store"),
                        React.createElement(
                            "select",
                            {
                                name: 'manual-product-store',
                                id: blockProps.id + 'new-store'
                            },
                            createStoreOptions()
                        )
                    ]
                )
            );
            // add button
            data.push(
                React.createElement(
                    'button',
                    {
                        className: 'add-manual-product', onClick: function () {
                            products.push(
                                {
                                    id: document.querySelector('#' + blockProps.id + 'new-id').value,
                                    title: document.querySelector('#' + blockProps.id + 'new-title').value,
                                    price: document.querySelector('#' + blockProps.id + 'new-price').value,
                                    link: document.querySelector('#' + blockProps.id + 'new-link').value,
                                    image: document.querySelector('#' + blockProps.id + 'new-image').value,
                                    store: document.querySelector('#' + blockProps.id + 'new-store').value,
                                }
                            );
                            props.setAttributes({ products: products.slice() });
                        }
                    },
                    '+'
                )
            );

            return data;
        }

        let returnEL = createEditEl();
        return React.createElement('div', blockProps, returnEL);
    },
});

I entered the product details and added to the row and it was showing in the row. I click on update post, products were still showed in the row.

But when I am refreshing the post edit page the products is empty.
It should show the products which I have added.