Add text to image path when image has unique id in htaccess

I have a multilingual website. This website has over 10.000 images in different articles and growing.

I need to be able – if possible – to random rename the images as long as the unique image-id is also displayed in the end.

Lets take this image for example: gallery_964/15471298.webp

I would like to be able to use the image like this

<img src="gallery_964/green-elephant-15471298.webp" /> //english
<img src="gallery_964/elefante-verde-15471298.webp" /> //portugese
<img src="gallery_964/grøn-elefant-15471298.webp" /> //danish

I have tried the following which did not work

RewriteRule ^.*(d+)gallery_964.(jpg|gif|png|webp)$ /gallery_964/$1.$2

I really can’t figure it out at this point. Is it even possible?

Bind params create error while to upload the data in phpMyAdmin [duplicate]

I have created an HTML form for uploading the email through input[type="text"] in phpMyAdmin. I have also created a button for adding more input fields for those users who have more than one email ID. By default it shows one input field but when we have to upload more than one email ID and click add email one remove button is also generated for removing that field. For this functionality, I have used JavaScript. When we finish to adding the emails then we have to submit the data. This will redirect to another page i.e. submit_data.php for handling the backend queries. Now in this, I have created a for loop for multiple input data, two more variables I have also added for the member name and date as I have those rows in my table.

My database name is tui_test
The table name is member_email
I have the following rows in my table-
sno, member_name, member_email, date_upload

I error I have seeing after submit the form is-

Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn’t match number of bind variables in D:XAMPPhtdocsachievementtestingsubmit_data.php on line 30

Following are the submit_data.php page for handling the backend queries-

<?php
    if ($_SERVER['REQUEST_METHOD']=='POST') {
        // Database connection settings
        $servername = "localhost";
        $username = "root";
        $password = "";
        $database = "tui_test";

        // Create connection
        $conn = new mysqli($servername, $username, $password, $database);

        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        // Email start
        // Get the email data
        $emails = $_POST['email'];
        $upload_name = 'name';
        date_default_timezone_set('Asia/Kolkata');
        $date = date('Y-m-d H:i:s');

        // Prepare SQL statement to insert data into table "member_email"
        $sqlEmail = "INSERT INTO member_email (member_name, member_email, date_upload) VALUES (?, ?, ?)";
        $stmt1 = $conn->prepare($sqlEmail);

        // Insert each email and date into the table
        for ($i = 0; $i < count($emails); $i++) {
            $stmt1->bind_param("ss", $upload_name, $emails[$i], $date);
            $stmt1->execute();
        }

        // Close the statement and connection
        $stmt1->close();
        // Email end
    }
?>

Sending telegram messages via madelineProto does not work

I try to send a message to a telegram supergroup in two ways:
tinker(working method):

> $api = new danogMadelineProtoAPI('session.madeline');
> $api->start();
> $api->sendMessage(peer: -1002056889962, message: 'TEST test <br /> TEST test', parseMode: danogMadelineProtoParseMode::HTML, replyToMsgId: 11164, topMsgId: 11164);

Console command launched in scheduler(not working method):

<?php

namespace AppConsoleCommands;

use AppMailingStatusEnum;
use AppModelsMailing;
use AppModelsTelegramGroup;
use AppModelsTelegramUser;
use AppModelsTopic;
use danogMadelineProtoAPI;
use danogMadelineProtoLocalFile;
use danogMadelineProtoParseMode;
use IlluminateConsoleCommand;
use Throwable;

class SendMailingsCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:send-mailings-command';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'check and send mailings';

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        $lockFile = '/tmp/telegram_bot_mailing.lock';
        $hour = now()->hour;
        $minute = now()->minute;
        $second = now()->second;
        $startTime = "startTime $hour:$minute:$second:";

        if (file_exists($lockFile)) {
            exit();
        }

        file_put_contents($lockFile, 'running');

        if (Mailing::query()->where('status', MailingStatusEnum::PROCESSING)->count() > 0) {
            return;
        }

        $madelineProto = new API('session.madeline');

        $mailing = Mailing::query()
            ->where('status', MailingStatusEnum::NEW)
            ->first();

        if (!$mailing) {
            return;
        }

        try {
            $mailing->update(['status' => MailingStatusEnum::PROCESSING]);

            foreach ($mailing->telegram_group_ids as $telegramGroupId) {
                $group = TelegramGroup::query()->find($telegramGroupId);

                $text = str_replace('&nbsp;', ' ', $mailing->text) . '<br /><br />';

                $group
                    ->usersWithRoles()
                    ->whereIn('role_id', $mailing->role_ids)
                    ->each(function (TelegramUser $telegramUser) use (&$text) {
                        $text .= $telegramUser->telegram_tag ? ' @'.$telegramUser->telegram_tag : " <a href='tg://user?id={$telegramUser->id}'>$telegramUser->name</a>";
                    });
                $media = [];

                $mediaFiles = $mailing->getMedia();

                foreach ($mediaFiles as $index => $mediaFile) {
                    if ($file = $this->handleFile($mediaFile, $index, $text, $mediaFiles->count())) {
                        logger('file', [$file]);
                        $media[] = $file;
                    }
                }



                $mailing->update([
                    'media_files' => $media
                ]);

                $resultMailing = null;

                $group
                    ->topics()
                    ->whereIn('name', $mailing->topic_ids)
                    ->each(function(Topic $topic) use ($media, $madelineProto, $group, $text, $startTime) {
                        $resultMailing = count($media) === 0
                            ? $madelineProto
                                ->sendMessage(
                                    peer: $group->telegram_id,
                                    message: $text,
                                    parseMode: ParseMode::HTML,
                                    replyToMsgId: $topic->topic_id,
                                    topMsgId: $topic->topic_id,
                                )
                            : $madelineProto
                                ->messages
                                ->sendMultiMedia(
                                    peer: $group->telegram_id,
                                    reply_to_msg_id: $topic->topic_id,
                                    top_msg_id: $topic->topic_id,
                                    multi_media: $media,
                                );
                        logger()
                            ->channel('mailing_sending_log')
                            ->info("$startTime sending mailing", ['resultMailing' => $resultMailing, 'group' => $group]);
                    });

            }

            $mailing->update(['status' => MailingStatusEnum::SENDED]);
        } catch (Throwable $e) {
            logger()
                ->channel('mailing_sending_log')
                ->info("$startTime ошибка рассылки", ['error' => $e, 'mailing' => $mailing]);
            $mailing->update([
                'status' => MailingStatusEnum::FAILED,
                'error' => [$e],
            ]);
        }

        unlink($lockFile);
    }

    protected function handleFile($mediaFile, int $index, string $text, $count): array|null
    {
        $filePath = $mediaFile->getPath();
        $mimeType = mime_content_type($filePath);

        return [
            '_' => 'inputSingleMedia',
            'media' => [
                '_' => 'inputMediaUploadedDocument',
                'force_file' => true,
                'file' => new LocalFile($filePath),
                'mime_type' => $mimeType,
                'attributes' => [
                    ['_' => 'documentAttributeFilename', 'file_name' => basename($filePath)]
                ]
            ],
            'message' => $index === $count - 1 ? $text : '',
            'parse_mode' => ParseMode::HTML,
        ];
    }
}

As a result, when sending a message through Tinker, it is sent perfectly, but if I use the console command called by the scheduler, I get the error: This peer is not present in the internal peer database

I’ve already tried a lot, although when I noticed that everything works through the tinker, but not through the scheduler, now I can’t get it out of my head and I don’t know where to go next

——-

ADDITION:
Not in all cases when working with the scheduler I get an error, but here is one of the rather strange cases that I don’t know how to solve

My php file which is online with Hostinger is not working even though it works perfectly fine on XAMPP

Ive been developing this project for a while and after finishing developing it on my local server I uploaded it to Hostinger. However now the inc files whic process the users input wont work. Ive checked and the database connection has the correct credentials.

Ive added in var_dumps to show that it is correctly taking in the data

https://emilyanddavid2025.co.uk/02_guest_login.php

<?php

if ($_SERVER["REQUEST_METHOD"] === "POST") {

    $username = $_POST["username"]; // ADD FEATURE TO SANITIZE THE USER INPUT TO PREVENT ATTACKS
    
    var_dump($username);

    try {
        
        require_once 'dbh.inc.php';
        require_once 'guest_login_model.inc.php';
        // VIEW WOULD GO HERE IF NEEDED
        require_once 'guest_login_contr.inc.php';

        $errors = [];

        if (is_input_empty($username)) {
            $errors["empty_input"] = "Fill in username!";
        }

        $result = get_user($pdo, $username);
        
        var_dump($result);

        if (!isset($errors["empty_input"])) {
            if (is_username_wrong($result)) {
                $errors["login_incorrect"] = "Incorrect username!";
            }
        }

        require_once 'config_session.inc.php';

        if ($errors) {
            $_SESSION["errors_login"] = $errors;

            header("location: ../02_guest_login.php");
            die();
        }

        $newSessionId = session_create_id();
        $sessionId = $newSessionId . "_" . $result["id"];
        session_id($sessionId);

        $_SESSION["user_id"] = $result["id"];
        $_SESSION["user_username"] = htmlspecialchars($result["username"]);
        $_SESSION["user_guest_one"] = htmlspecialchars($result["guest_one"]);
        $_SESSION["user_guest_two"] = htmlspecialchars($result["guest_two"]);
        $_SESSION["user_guest_three"] = htmlspecialchars($result["guest_three"]);
        $_SESSION["user_guest_four"] = htmlspecialchars($result["guest_four"]);
        $_SESSION["last_regeneration"] = time();
        
        var_dump($_SESSION["user_guest_one"]);

        header("location: ../03_rsvp.php");
        $pdo = null;
        $statement = null;

        die();

    } catch (PDOExeption $e) {
        die("Query failed: " . $e->getMessage());
    }

} else {
    header("location: ../02_guest_login.php");
    die();
}

This file should correct identify whether the guest username exists via checks and it would then redirect them accordingly.

insert associative array to a unique variable

I wrote a associative array and wanna define a key to a unique variable:

<?php
$birthday = [
    'Kevin' => '20-10-1990',
    'Max' => '11-11-2007',
    'Nadia' => '02-03-2000'
];
$birthday['Nadia'] = $nadia;
echo 'Nadia's Birthday is: ' . $nadia;
?>

But there is warning:

**Warning: Undefined variable $nadia

**

and the Result is empty:

Nadia’s Birthday is:

why don’t recognize php this variable ? Or recognized the variable, but can’t read the value from Nadia?

How to prevent BIN attack on a Laravel v11 Livewire-based checkout system?

I am currently facing a BIN attack on the checkout page of my web application, which is built using Laravel and Livewire. Fraudulent users (or bots) are attempting to perform card testing by using a series of invalid or stolen credit card numbers with similar BINs (Bank Identification Numbers). These repeated attempts are affecting my payment gateway and creating issues with legitimate transactions.

I want to implement a solution that will prevent these attacks by adding additional security layers to my checkout process.

Here’s what I’ve done so far:

  • I am using Laravel Livewire to handle form submissions for the checkout process.

  • Payments are processed using a third-party payment gateway(Stripe).

  • I have basic validation in place for form inputs, but this doesn’t seem to prevent the BIN attack.

I am looking for recommendations on how to prevent these attacks effectively.

Specifically, I want to:

  • Detect and block bots or malicious users performing rapid multiple transactions with invalid card details.
  • Rate-limit requests or add CAPTCHA where appropriate.
  • Implement better protection strategies like logging suspicious activities or blocking repeated failed transactions from the same IP address

this is what i used in livewire function:

     public function initializePayment()
        {
          $application = Application::findOrFail($this->applicationId);
    
           $stripe = new StripeClient(env('STRIPE_SECRET'));

    // Define line items for the Stripe session
    $lineItem = [
        [
            'price_data' => [
                'currency' => 'usd',
                'product_data' => [
                    'name' => 'Test Name', // Set the product name
                    'description' => "Description", // Set the product description
                    'images' => [asset('assets/images/1.jpeg')], // Add image URL
                ],
                'unit_amount' => 49 * 100, // Amount in cents
            ],
            'quantity' => 1,
        ],
    ];

    // Create a Stripe checkout session
    $stripeSession = $stripe->checkout->sessions->create([
        'payment_method_types' => ['card'],
        'line_items' => $lineItem,
        'mode' => 'payment',
        'metadata' => [
            'application_id' => $application->id,
            'application_number' => $application->application_number,
        ],
        'customer_email' => $this->email, // Optional: Prefill customer's email in the 
            payment form
        'payment_intent_data' => [
            'description' => "Payment for Application #{$application- 
               >application_number}",
            'metadata' => [
                'application_id' => $application->id,
                'application_number' => $application->application_number,
                'email' => $this->email,
                'phone' => $this->phone_number,
                'first_name' => $this->first_name,
                'last_name' => $this->last_name,
               ],
             ],
            'success_url' => route('stripe.success', [], true) . '?session_id= 
              {CHECKOUT_SESSION_ID}',
            'cancel_url' => route('stripe.cancel', [], true) . '?session_id= 
            {CHECKOUT_SESSION_ID}',
          ]);

         // redirect to stripe gateway
       return redirect()->away($stripeSession->url);
     }

WordPress multisite loop 302 ERR_TOO_MANY_REDIRECTS

I have a fresh install of wordpress in /var/www/html/, also we use CloudFlare(I think the problem can be here). All is okay when I try to use default site with one subdir. But as far as I enable subdir multisite define( 'MULTISITE', true ); site starts to loop with 302 error code(ERR_TOO_MANY_REDIRECTS) on every page I try to access, if I disable it all returns to normal conditions.
ere is my wp-config.php:

<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the installation.
 * You don't have to use the website, you can copy this file to "wp-config.php"
 * and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * Database settings
 * * Secret keys
 * * Database table prefix
 * * ABSPATH
 *
 * @link https://developer.wordpress.org/advanced-administration/wordpress/wp-config/
 *
 * @package WordPress
 */

// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'db' );

/** Database username */
define( 'DB_USER', 'user' );

/** Database password */
define( 'DB_PASSWORD', 'pass' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

/**#@+
 * Authentication unique keys and salts.
 *
 * Change these to different unique phrases! You can generate these using
 * the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
 *
 * You can change these at any point in time to invalidate all existing cookies.
 * This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define( 'AUTH_KEY',         '***' );
define( 'SECURE_AUTH_KEY',  '***' );
define( 'LOGGED_IN_KEY',    '***' );
define( 'NONCE_KEY',        '***' );
define( 'AUTH_SALT',        '***' );
define( 'SECURE_AUTH_SALT', '***' );
define( 'LOGGED_IN_SALT',   '***' );
define( 'NONCE_SALT',       '***' );

/**#@-*/

/**
 * WordPress database table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the documentation.
 *
 * @link https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/
 */
define( 'WP_DEBUG', true );

/* Add any custom values between this line and the "stop editing" line. */


//define('ADMIN_COOKIE_PATH', '/');
//define('COOKIE_DOMAIN', '');
//define('COOKIEPATH', '');
//define('SITECOOKIEPATH', '');


define('WP_ALLOW_MULTISITE', true);
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false );
define( 'DOMAIN_CURRENT_SITE', 'site.domain' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );




define('FORCE_SSL_ADMIN', true);
// in some setups HTTP_X_FORWARDED_PROTO might contain
// a comma-separated list e.g. http,https
// so check for https existence
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
    $_SERVER['HTTPS']='on';


define('WP_HOME', 'https://site.domain');
define('WP_SITEURL', 'https://site.domain');


/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

I had a problem with sending some requests using http instead of https so I added:

define('FORCE_SSL_ADMIN', true);
// in some setups HTTP_X_FORWARDED_PROTO might contain
// a comma-separated list e.g. http,https
// so check for https existence
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
    $_SERVER['HTTPS']='on';

here is my.htaccess:

# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.


Options +FollowSymLinks

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*.php)$ $2 [L]
RewriteRule . index.php [L]



# END WordPress

photo of one of the many loop requests

I think the problem can also be in my apache virtual host config:

<VirtualHost *:80>
    ServerName site.domain
    DocumentRoot /var/www/html

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =site.domain
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]


    <Directory "/var/www/html">

        AllowOverride All
        Order allow,deny
        Allow from all

    </Directory>

</VirtualHost>


<IfModule mod_ssl.c>
<VirtualHost *:443>
    DocumentRoot /var/www/html
    ServerName site.domain

   SSLCertificateFile /etc/letsencrypt/live/site.domain/fullchain.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/site.domain/privkey.pem
   Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

so far I tried almost every solution with same title:

  1. adding define('ADMIN_COOKIE_PATH', '/'); ...
  2. clearing cache
  3. checking if mod_rewrite enabled
  4. change all permissions to files and directorys
  5. setting TLS/SSL Full encryption

How am I misusing in_array? [duplicate]

Consider the following PHP:

<?php
if (in_array('cookie_name', $_GET, false)) {
    echo "Found";
}
var_dump($_GET);
echo $_GET['cookie_name'] . "n";
?>

If I put this on a webserver and use curl with cookie_name=xxx, I get the following output, which does not include the string Found.

array(1) {
  ["cookie_name"]=>
  string(3) "xxx"
}
xxx

I feel that I must be using in_array incorrectly but I do not see how.

Any hints?

How to correctly format the date field? [closed]

I’m currently working on a Zoho CRM integration using PHP and facing issues when trying to submit a date field (API_Date). The required format for the date is YYYY-MM-DD, and I want to ensure I’m using the right approach for formatting this date before sending it to the API.

What are the recommended methods for formatting the current date in PHP to ensure compatibility with Zoho CRM?

I appreciate any insights or advice you can share on best practices for handling date fields in Zoho CRM API integrations.

Additional Context:

I’m using PHP version 7.4 and the latest version of the Zoho CRM PHP SDK (zohocrm/php-sdk-2.0).

Other fields in the record submission are working without any issues; the problem seems to be isolated to the date field.

What I’ve Tried(Till Now):

  1. Used PHP’s DateTime:
$currentDate = new DateTime();
$recordInstance->addKeyValue('Current_date', $currentDate->format('Y-m-d'));
  1. Used date function:
$recordInstance->addKeyValue('API_Date', date('Y-m-d'));

Despite trying the above methods, I keep receiving an error when attempting to submit the record. The error message is as follows:

Exception: in /path/to/zoho/crm/api/util/Converter.php on line 177
#0 /path/to/zoho/crm/api/util/JSONConverter.php(460): comzohocrmapiutilConverter->valueChecker('comzohocrmap...', 'apiDate', Array, '2024-10-21', Array, 0)

how to load page into a div when click on a link without reload the window?

i have this html+php code :

<div class="categories_menu">               
<?php foreach($pt->categories as $key => $category) {
if (1) { ?>
<div class="items">
<a class="item_link" href="{{LINK videos/category/<?php echo $key?>}}" ><?php echo $category?></a>
</div>
<?php } }?>
</div>

<div id="load_cats" class="load_cats">  
 <!--load categories contents in this div -->         
</div>

the first code create a menu for categories by the php foreach methode.

this code :
<a class="item_link" href="{{LINK videos/category/<?php echo $key?>}}" ><?php echo $category?></a>
when click on it will open category page as a new page outside the current page.

i want to open category page inside the div id="load_cats" without reload/refresh the current page .
the matter is open category inside the div instead of open the url in a full new window in browser.

this code can help but what is the code to load categories pages !!

$(".item_link").click(function() {
    $("load_cats").load("???");
});

i see on this site many topics speak about this , but because my code based on php foreach i cant use them .

Filament Resource: Grand Total Not Updating on Product/Quantity Changes

I’m building an order management system using Filament in Laravel. However, I’m running into an issue where the grand total only updates when the discount field is changed, but it does not recalculate when products or quantities are added/updated.

// OrderResource.php

namespace AppFilamentResources;

use AppModelsOrder;
use AppModelsProduct;
use FilamentForms;
use FilamentResourcesForm;
use FilamentResourcesResource;
use IlluminateSupportFacadesLog;

class OrderResource extends Resource
{
    protected static ?string $model = Order::class;

    public static function form(Form $form): Form
    {
        return $form->schema([
            FormsComponentsRepeater::make('order_details')
                ->relationship('orderDetails')
                ->schema([
                    FormsComponentsSelect::make('product_id')
                        ->options(Product::pluck('name', 'id'))
                        ->reactive()
                        ->required()
                        ->afterStateUpdated(fn($state, callable $set, callable $get) =>
                            self::updateProductSelection($state, $get, $set)
                        ),

                    FormsComponentsTextInput::make('quantity')
                        ->numeric()
                        ->reactive()
                        ->default(1)
                        ->afterStateUpdated(fn($state, callable $get, callable $set) =>
                            self::updateProductTotal($get, $set)
                        ),

                    FormsComponentsTextInput::make('total')->disabled(),
                ])
                ->afterStateUpdated(fn(callable $get, callable $set) =>
                    self::recalculateGrandTotal($get, $set)
                ),

            FormsComponentsTextInput::make('discount')
                ->reactive()
                ->afterStateUpdated(fn($state, callable $get, callable $set) =>
                    self::recalculateGrandTotal($get, $set)
                ),

            FormsComponentsTextInput::make('grand_total')->disabled(),
        ]);
    }

    protected static function updateProductSelection($state, callable $get, callable $set)
    {
        $product = Product::find($state);
        $set('price', $product->price ?? 0);
        self::recalculateGrandTotal($get, $set);
    }

    protected static function updateProductTotal(callable $get, callable $set)
    {
        $price = (float) $get('price');
        $quantity = (int) $get('quantity');
        $set('total', $price * $quantity);
        self::recalculateGrandTotal($get, $set);
    }

    protected static function recalculateGrandTotal(callable $get, callable $set)
    {
        $orderDetails = $get('order_details') ?? [];
        $discount = (float) $get('discount') ?? 0;

        $grandTotal = collect($orderDetails)
            ->sum(fn($detail) => (float) ($detail['total'] ?? 0));

        if ($discount > 0) {
            $grandTotal -= ($grandTotal * $discount) / 100;
        }

        $set('grand_total', $grandTotal);

        Log::info('Grand Total recalculated:', ['grandTotal' => $grandTotal]);
    }
}

The grand total only updates if the discount field is changed, but not when I change products or quantities.
Logs show correct product/quantity updates, but the grand total stays at 0.How can I ensure that grand total updates dynamically when products or quantities change? I don’t want the discount field to control the grand total calculation.IN THIS IMAGE AS YOU CAN SEE GRAND TOTAL FIELD NOT UPDATING

PHP Google Sheets copy sheet from one spreadsheet to another

This needs to be using Google Sheets API and PHP
I have a singleton wrapper class (lets face it, most Google PHP apis need them) of which an instance in my client class is

$gsheets

I have had this working previously and still demonstrating I having API access I create a new Spreadsheet by running:

$newspreadsheetTitle="ABC123456";
$newdocument = $gsheets->newSpreadsheetDocument($newspreadsheetTitle);

Which calls my own wrapper class method:

  public function newSpreadsheetDocument($title) {
    $newspread = new Google_Service_Sheets_Spreadsheet([
    'properties' => [
        'title' => $title
    ]
    ]);
    $newspread = $this->service->spreadsheets->create($newspread);
    $id = $newspread->getSpreadsheetId();
    return ["ID" => $newspread->getSpreadsheetId(), "url" => $newspread->getSpreadsheetUrl()];
  }

At this point the new spreadsheet is created titled ABC123456 and returns the expected ID and url, accessable by pasting the link into address bar on browser, with the returned ID.
This demonstrates that

$this->service

is a fully functioning client of Google Sheets in my wrapper class and creates a spreadsheet document named $spreadsheetRef.

So now my question:

I then wish to copy a content (a whole tab/sheet) from this template to this newly created spreadsheet so I call

  $gsheets->copySheetFromTo($POtemplateID, $newdocument["ID"], 0);

to my wrapper instance method

  public function copySheetFromTo($sourceSpreadsheetFileId, $destinationSpreadsheetFileId, $sourceTabRef) {
    $requestBody = new Google_Service_Sheets_CopySheetToAnotherSpreadsheetRequest();
    $requestBody->setDestinationSpreadsheetId($destinationSpreadsheetFileId);
    $response = $this->service->spreadsheets_sheets->copyTo($sourceSpreadsheetFileId, $sourceTabRef, $requestBody);

    /*
        $request = new Google_Service_Sheets_CopySheetToAnotherSpreadsheetRequest([
            "destinationSpreadsheetId" => $toFileID
        ]);
        $this->service->spreadsheets_sheets->copyTo($fromFileID, $fromTabName, $request);
    */
    return $response;
  }

I have tried several permuations eg

      $gsheets->copySheetFromTo($POtemplateID, $newdocument["ID"], 0);

error:

The sheet (0) does not exist.

and

      $gsheets->copySheetFromTo($POtemplateID, $newdocument["ID"], 1);

error:

The sheet (1) does not exist.

and

  $gsheets->copySheetFromTo($POtemplateID, $newdocument["ID"], "template_sheet");//the name of the sheet tab to copy

error

Invalid value at 'sheet_id' (TYPE_INT32), "template_sheet"

Please could somebody advise what parameters are incorrect here.

repeat different numbers the result when write the while loop [closed]

I wrote a sample code of while loop for a Dice Roll :
if dice is 6 the player is winner, otherwise the program shows just a text

<?php
$a = 0;
while ($a != 6) {
  $a = rand(1,6);
  echo 'The Dice is: ' . $a;
  if ($a == 6) {
    echo '<p>Super! You are the Winner</p>';
  }else{
        echo '<p>Sorry! You can try later...</p>';
  }
}
echo '<p>Thank you for the Play!</p>';
?>

After refresh the page each time during this code, it shows different numbers of result?

And how can I set the specific time of repeating the code just with while?