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?

setup JWT auth milan parmar [closed]


namespace AppHttpControllers;

use AppModelsAdmin;
use IlluminateSupportFacadesAuth;
use IlluminateSupportFacadesFile;
use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;
use TymonJWTAuthFacadesJWTAuth;

class AdminAuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');
        if (! $token = auth('admin')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }


    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:admins',
            'password' => 'required|string|min:6',
        ]);

        $admin = Admin::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = JWTAuth::fromUser($admin);

        return response()->json(compact('admin', 'token'), 201);
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('admin')->factory()->getTTL() * 60
        ]);
    }

    public function fetch(){
        // Check if the admin is authenticated
        if (! Auth::guard('admin')->check()) {
            return response()->json(['error' => 'Unauthorized'], 401);
        } else {
            // If authenticated, proceed
            $data = Auth::guard('admin')->user(); // Use guard to get the admin data
            return response()->json($data);
        }

    }
}


namespace AppModels;

use IlluminateFoundationAuthUser as Authenticatable; // Important!
use IlluminateNotificationsNotifiable;
use TymonJWTAuthContractsJWTSubject; // For JWT support

class Admin extends Authenticatable implements JWTSubject
{
    use Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    // This is needed for JWT
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    }
}

this are the code by help to add the jwt auth into you laravel project

How can I add a replace for a br in a .php-file? [closed]

Here is my .php-file:
index.php:

<html lang="sv-gibraltar">
   <head>
      <title>Eliseshundar.se&reg;</title>
      <meta charset="utf-8">
      <link rel="stylesheet" href="/reset.css">
      <link rel="stylesheet" href="/https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
   </head>
   <body>
      <?php echo "<table class='table'>";
         echo "t";
         echo "<td class='tableSub'>";
         echo "<br>";
      ?>
      PLEASE REGISTER AN ACCOUNT HERE
      <!-- Here I have entered a simple registration form, without credentials. -->
      <script src="Array.js"></script>
...

And here is the JS-file:
Array.js:)

// Squeeky clean files go everywhere!
this.HTMLTableCaptionElement
// Here I have selected, a null table
this.table = "";
this.table.trimEnd.querySelector('.tableSub');
this.table.querySelector('')

Below tableSub I want to select <br>, but I want to replace it with randomColors of cats from a generator I have created.

Error message in php $_SESSION is couldn’t be reached after it is generated in another page [closed]

i am executing this private method by call in another part of class. the session is started already at the top of script(source of problem is not related with session_start()).
This is where I generate the error message :

private function isValidOthers($parentId, $title, $keywords, $description, $status, $slug)
{     
    if (empty($parentId) || empty($title) || empty($keywords) || 
        empty($description) || empty($status) || empty($slug)) 
    {
        $_SESSION["error"] = "All inputs are necessary. Please fill all fields.";
        header("Location:admin/category_add.php");
        exit;
    }
}

And this is where i want to handle the error message (admin/category_add.php) :

<?php
session_start();

var_dump($_SESSION);


if (isset($_SESSION["error"])) {
    echo "

        Swal.fire({
            icon: 'error',
            title: 'Error!',
            text: '" . $_SESSION['error'] . "',
            timer: 3000,
            showConfirmButton: false
        });
    ";

unset($_SESSION['error']);
}

if I uncomment the line var_dump($_SESSION) i can reach the error message as i expect. but i want to handle my error message without reaching $_SESSION.

I think i misunderstood one simple point, is there anyone to help?

Get list of private Dailymotion videos

I want to get list of private Dailymotion videos.

I am able to receive an access token with a private key. But then when I send Get request to retrieve the list of videos, I see the following “400 Bad Request: malformed Host header”.

<?php
            //Perform authentication
            // Specify the URL and data
$url = "https://partner.api.dailymotion.com/oauth/v1/token";

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$headers = array(
   "Host: partner.api.dailymotion.com",
   "Content-Type: application/x-www-form-urlencoded",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

$data = "grant_type=client_credentials&client_id=xxx&client_secret=xxx&scope=manage_videos";

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

$resp = curl_exec($curl);
curl_close($curl);
$data = json_decode($resp, true);
$access_token = $data['access_token'];
$url = "https://partner.api.dailymotion.com/user/userid/videos?fields=id&limit=30&private=true";

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$headers = array(
    "Host: partner.api.dailymotion.com/rest",
);

$auth = "Authorization: Bearer " . $access_token;
$headers[1] = $auth;
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

$resp = curl_exec($curl);
curl_close($curl);
//var_dump($resp);
?>

When I omit host in headers I get 404 Not Found.

    $headers = array(

);

$auth = "Authorization: Bearer " . $access_token;
$headers[0] = $auth;

I also tried to use the following url. I get 404 Not Found.

$url = "https://partner.api.dailymotion.com/videos?fields=id&private=true&owners=userid;

Laravel can’t get redis key value in For loop

I have a problem with Laravel when getting a Redis value in loop

public function testLoop()
{
    for($i = 0; $i < 3; $i++) {

        Redis::set('key_'.$i, 'value_'.$i);
        Log::info(Redis::get('key_'.$i));
    }
   
    return true;
}

Laravel successfully set the key but any error while trying to get key

here is the logs, it only gets first

[2024-10-21 09:05:13] local.INFO: value_0
[2024-10-21 09:05:13] local.ERROR: Error while reading line from the server. [tcp://docker.for.mac.localhost:6379] {“userId”:569,”exception”:”[object] (PredisConnectionConnectionException(code: 0): Error while reading line from the server. [tcp://docker.for.mac.localhost:6379] at /var/www/html/vendor/predis/predis/src/Connection/AbstractConnection.php:144)
[stacktrace]

and here is the redis key

enter image description here

I’m tried both predis and phpredis but both have same issue

I have set redis timeout to 0

127.0.0.1:6379> config get timeout
1) "timeout"
2) "0"

I’ve also set read_write_timeout in config/database.php to 0

'read_write_timeout' => 0,

value from redis-cli

enter image description here

redis-cli monitor (stuck at key_1)

enter image description here

Optional route params

I have to setup a multi-language application with Laravel 11, this is the first time that I use multi-language feature in laravel, I will not use any package, I will set it manually, so I prepared the web.php file like this :

Route::group(['middleware' => ['setLocale']], function () {
    Route::get('/products/{slug}', [ProductController::class, 'fetchProduct']);
});
Route::group(['middleware' => ['setLocale'], 'prefix' => '{locale?}', 'where' => ['locale' => 'en|fr|de|jp']], function () {
    Route::get('/', LandingController::class);
    Route::get('/products/{slug}', [ProductController::class, 'fetchProduct']);
});

When I access to ‘/products/fr/exemple-product’ it works but when I tried to acces to the default route like this : ‘/products/exemple-product’ it deosn’t work and handle an error:
Too few arguments to function App\Http\Controllers\Front\ProductController::fetchProduct(), 1 passed in C:\...\ControllerDispatcher.php on line 46 and exactly 2 expected

this is the definiion of the fetchProduct method :

public function fetchProduct($locale = null, $slug) {dd($slug');}

even if I setted $locale to null but it deos’t work, can you please tell me what is the problem?

Why does empty($object->arrayProperty) result in true while array elements are set and filled? [duplicate]

Without any other changes the following three lines in the same spot result in (for me) incomprehensible results. The first result in my head does not match to what the other lines return:

var_dump(empty($this->table)); //results in "bool(true)"
var_dump($this->table); //results in an array of 75 elements
var_dump(empty($this->table[0])); //results in "bool(false)"

First of all:

  • My question is NOT what to do, to make my code work. Many other topics explain this very good and I don’t want duplication here.

  • My question is NOT why PHP has an error here. As PHP is what it is and it is the behaviour that it is.

  • As !isset() for non-false elements is an equivalent to empty() in this case it obviously has same results. I could have interchanged “…does empty($array) result in true…” inside the title with “…why does an array not exist…”. I decided for more specific wording.

I search for the explanation that leads to this (at least for me) confusing result. I have a guess that it might be a mechanic related to __get() or ob_get_clean() but I have no real clue how these work internally.

The Environment:

  1. I have a method inside an object that extracts an array out of a csv-file. (changed names)
   $object = new Class();
   
   empty($object->method()); //results in false - as I would expect as an array with 75 elements is returned
  1. I wrap this together with other variables of different types into a params-array.
   $params =['table' => $object->method(),...];
   
   empty($params['table']); //still results in false here
  1. Via a View object I pass the params-array to a view
   return (new View('transactions/show',$params))->render();

For the passing inside the View object I use the __get magic method

   public function __get(string $name) {
      return $this->params[$name] ?? null;
   }

The render function includes the view with output buffering

   public function render() {
       ob_start();
       include VIEW_PATH . DIRECTORY_SEPARATOR . $this->view . '.php';
       return ob_get_clean();
   }
  1. Inside the view (‘transactions/show’) I am able to access the params by $this->variable and as mentioned above the array is accessible and working fine but the result “true” of the empty($this->table) confuses me.

All my testing lead me to the point that step 3. is responsible for the results I experience inside step 4.

To show a reproducible version hereafter complete files:

Controller class:

<?php

declare(strict_types=1);

namespace AppController;

use AppModelDemoClass;
use AppView;

class Demo {
    public function index() {
        $object = new DemoClass();

        empty($object->demoMethod()); //results in false - as I would expect as an array with 75 elements is returned

        $params =['table' => $object->demoMethod()];

        empty($params['table']); //still results in false here

        return (new View('demo/show',$params))->render();
    }
}

The Model class (here only simulating to get an array of arrays from a source (csv, Database, whereever)

<?php

declare(strict_types=1);

namespace AppModel;

class DemoClass {
    public function demoMethod() {
        $array = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
        ];
        return $array;
    }
}

the View class (only the needed excerpt):

<?php

declare(strict_types=1);

namespace App;

use FrameworkExceptionViewNotFoundException;

class View {

    public function __construct(protected string $view, protected array $params =[]) {
    }

    public static function make(string $view, array $params =[]): static {
        return new static($view, $params);
    }
    
    public function render(): string {
        $viewPath = VIEW_PATH . DIRECTORY_SEPARATOR . $this->view . static::PHP_TYPE;
        
        if(!file_exists($viewPath)) {
            throw new ViewNotFoundException();
        }
        ob_start();
        include $viewPath;
        return (string) ob_get_clean();
    }
    
    public function __get(string $name) {
        return $this->params[$name] ?? null;
    }

    public function __toString():string {
        return $this->render();
    }
}

The view/html – kept it short without HTML header (it makes no difference here)

<?= var_dump(empty($this->table)); //results in "bool(true)" ?>
</br>

<?= var_dump($this->table); //results in an array of 75 elements ?>
</br>

<?= var_dump(empty($this->table[0])); //results in "bool(false)" ?>
</br>

with calling the Demo->index() (e.g. via Router) the result is:

bool(true)

array(3) { 
    [0]=> array(3) { 
        [0]=> int(1) 
        [1]=> int(2) 
        [2]=> int(3) 
    } 
    [1]=> array(3) { 
        [0]=> int(4) 
        [1]=> int(5) 
        [2]=> int(6) 
    } 
    [2]=> array(3) { 
        [0]=> int(7) 
        [1]=> int(8) 
        [2]=> int(9) 
    } 
}

bool(false)

Laragon Virtual Host doesn’t work for Laravel App

I know this question maybe duplicate, but from any answers and questions that I have looked at, no one of them can solve my problem. I use Laragon for my Laravel App project and i want to open the project by using the virtual host. I think I have changed the version of PHP on my Laragon but I doubt about that. After several months not using the Laragon, when I open the Virtual Host, the browser said

enter image description here

whaI have tried many methods, such as:

  1. Reinstall laragon, add new php version, etc
  2. Checking the Read-only setting of hosts file in Windows/System32/driver/etc/…
  3. Turn off the firewall
  4. Check the httpd.conf, but all is clear
  5. Check the auto.test.test.conf, and all is clear
    And many checking file, but no one solved my problem.
    Any suggestion and solution for this problem please? Thank you

Why is stdout not a tty?

Why is stdout not a tty, even though stderr is? Please let me know if you need more context, added this line to pass stackoverflow’s validation.

$ php -r 'var_dump(exec("test -t 1 && echo y"));'
string(0) ""
$ php -r 'var_dump(system("test -t 1 && echo y"));'
string(0) ""
$ php -r 'var_dump(passthru("test -t 1 && echo y"));'
NULL
$ php -r 'var_dump(exec("test -t 2 && echo y"));'
string(1) "y"
$ php -r 'var_dump(system("test -t 2 && echo y"));'
y
string(1) "y"
$ php -r 'var_dump(passthru("test -t 2 && echo y"));'
y
NULL
$ php -v
PHP 8.2.20 (cli) (built: Jul  4 2024 02:23:40) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.20, Copyright (c) Zend Technologies
$ uname -rsm
FreeBSD 13.3-RELEASE-p1 amd64

How do I pass a hidden text field as well as changle the form action

I have a script that will take a page name and change the form action, which will then take me to that page. However, I also want the ID for the page content to be passed to it. I assumed that a hidden field would work. I get the page, but there is no content.

<script language="javascript">
<!-- Script courtesy of http://www.web-source.net - Your Guide to Professional Web Site Design and Development
function goto(form) { var index=form.select.selectedIndex
if (form.select.options[index].value != "0") {
location=form.select.options[index].value;}}
//-->
</script>
<form name="form1">
<input type="hidden" name="id" id="id" value="<?php echo $row['id'];?>">
<select name="select" onchange="goto(this.form)">
<option value="">-------Choose a Selection-------
<option value="view.php">View
<option value="download.php">Download
</select>
</form>

I then capture the ID on the receiving page with.

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collect value of input field
    $app_id = $_POST['id'];
}