Why does passing an instance of IlluminateHttpUploadedFile to a custom cast result in an infinite loop?

I have a Configuration model in which I have implemented a custom cast, the getter works perfectly but let’s look at the setter.

For clarity, I have trimmed down the code samples to only what’s relevant to the context.

App/Models/Configuration.php

use IlluminateDatabaseEloquentModel;

class Configuration extends Model
{ 
    protected function casts(): array
    {
        return [
            'value' => AppCastsConfigValue::class,
        ];
    }
}

App/Casts/ConfigValue.php

use IlluminateContractsDatabaseEloquentCastsAttributes;
use IlluminateDatabaseEloquentModel;
use IlluminateHttpUploadedFile;

class ConfigValue implements CastsAttributes
{ 
    public function set(Model $model, string $key, mixed $value, array $attributes): mixed
    { 
        $saveable = $value instanceof UploadedFile || 
                     (isset($value[0]) && $value[0] instanceof UploadedFile);

        echo 1; // Take note of this

        return match (true) {
            ...// Other conditions
            $saveable => $this->doUpload(UploadedFile|array $value),
            ...// Other conditions
            default => (string) $value,
        };
    }
}

Let’s also not bother about the logic for the file uploads, the problem here is that X-Debug throws an infinite loop error after terminating the script when proccessing the upload. But if I straight out return the output, you can see from the image below that the script is run several times before it returns the response, adding upload logic to this ends us in an infinite loop.

example response from postman, here you can see that 1 is being outputed several times.

App/Controllers/ConfigController.php

$config = Configuration::where('key', $key)->first();

$config->value = $value;
$config->save();

On the Controller $key and $value are from a foreach loop of $request->configurations, the above works well when $value is anything but an instance of IlluminateHttpUploadedFile in which case we fall into the infinite loop.

What am I doing wrong here?

Has anybody success with PHP sqlsrv-connection on macOS Sonoma 14.6.1 with XAMPP 8.1.17?

I could install und use the sqlsrv and sqlsrv_pdo driver packages from Microsoft on Windows and Ubuntu24.04 but for MacOS always failed to load connect to the driver at runtime!!!! Not even any php screen error logging works as in the php-file enabled:

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);

$serverName = "1nnnnn“; // Or your server name
$connectionOptions = array(
    "Database" => "Ifffffff“, // Your database name
    "Uid" => "ddddddd“,
    "PWD" => „passwoooord“,
);
//echo "???"; // when this two commented lines are uncommented the site shows ???
//exit(); // when this two commented lines are uncommented the site shows ???
$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === false) {
    die(print_r(sqlsrv_errors(), true));
}
echo "Connection successful!";
?>

XAMPP/Apache works fine for any php but when calling sqlsrv_connect the browser shows ‘unable to open’ and error in php_error_log-file is:

dyld[8251]: Assertion failed: (this->magic == kMagic), function loadAddress, file Loader.cpp, line 163.

The driver files are in correct location:

@MacBook-Pro-von-Ha---en no-debug-non-zts-20210902 % ls
opcache.so  pdo_dblib.so    pdo_sqlsrv.so   pgsql.so    sqlsrv.so

In the php.ini file extensions are loaded:

extension=sqlsrv.so
extension=pdo_sqlsrv.so

Correct access given:

-rwxr-xr-x@ 1 root  admin   26720  6 Apr  2023 pdo_dblib.so
-rwxr-xr-x@ 1 root  admin  333216 11 Sep 15:42 pdo_sqlsrv.so
-rwxr-xr-x@ 1 root  admin  117680  6 Apr  2023 pgsql.so
-rwxr-xr-x@ 1 root  admin  336880 11 Sep 17:14 sqlsrv.so

ODBC installed

g@MacBook-Pro-von-Ha---en no-debug-non-zts-20210902 % odbcinst -j

unixODBC 2.3.12
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /Users/hjbeling/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

How to add dynamic frequency for scheduled command in laravel 11

I have a custom command for taking backups of my laravel website and I want to make its frequency dynamic, how to achieve that??

My command takes two optional options –only-files and –only-db.
These options and the its frequency based on user preference.

my custom command:

<?php

namespace AppConsoleCommands;

use AppModelsScheduledBackup;
use IlluminateConsoleCommand;
use IlluminateConsoleSchedulingSchedule;

class BackupWebsite extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'BackupWebsite:run';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Backup db and files of the website';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $scheduleBackup = self::scheduledBackups();
        if($scheduleBackup){
            $this->call('backup:run', [
                '--only-files' => $scheduleBackup['onlyFiles'],
                '--only-db' => $scheduleBackup['onlyDb'],
            ]);
        }
    }

    function scheduledBackups(){
        $scheduleBackup = ScheduledBackup::first();
        $files = $scheduleBackup->files;
        $database = $scheduleBackup->database;
        $repetition = $scheduleBackup->repetition;
        if($scheduleBackup->is_active){
            if($files && $database){
                return  ['onlyFiles' => false, 'onlyDb' => false, 'repetition' => $repetition];
            }elseif($files){
                return ['onlyFiles' => true, 'onlyDb' => false, 'repetition' => $repetition];
            }elseif($database){
                return ['onlyFiles' => false, 'onlyDb' => true, 'repetition' => $repetition];
            }
        }
        return false;
    }
}

this is my routesconsole.php

// I wanna make "daily()" dynamic. Its value stored in db model "ScheduledBackup" column "repetition"
Schedule::command(BackupWebsite::class)->daily() 

I did it before in laravel 9 like this:

protected function schedule(Schedule $schedule)
    {
        $scheduleBackup = self::scheduledBackups();
        if($scheduleBackup){
            $schedule->command($scheduleBackup['cmd'])->{$scheduleBackup['repetition']}();
        }


    }

Database Query Error with Dibi in PHP Script

I am having a script written like this:

<?php
date_default_timezone_set('Europe/Prague');

// Start time recording
$time_start = microtime(true);

include('./_includes.php');
$db = db_connector::connect();
if (!$db) {
    die('Database connection failed.');
}

// Instantiate audit object
$audit = new Audit(Audit::$udalost_typ[1]);

// Function to fetch data from DB using Dibi with error handling
function fetchFromDB($query, $params = []) {
    global $db;
    try {
        $result = $db->query($query, ...$params)->fetch();
        if (!$result) {
            throw new Exception('Query failed.');
        }
        return $result;
    } catch (Exception $e) {
        throw new Exception('Database query error: ' . $e->getMessage());
    }
}

try {
    // Retrieve JSON input
    $data = json_decode(file_get_contents('php://input'), true);

    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception('Invalid JSON input.');
    }

    // Validate input data
    $requiredFields = ['uuid', 'task_id', 'typ_pozadavku', 'tel_cislo', 'datum'];
    $missingFields = array_filter($requiredFields, fn($field) => empty($data[$field]));

    if (!empty($missingFields)) {
        throw new Exception('Missing fields: ' . implode(', ', $missingFields));
    }

    // Extract and sanitize data
    $uuid = $data['uuid'];
    $task_id = (int)$data['task_id'];
    $typ_pozadavku = $data['typ_pozadavku'];
    $tel_cislo = $data['tel_cislo'];
    $datum = $data['datum'];

    // Begin transaction
    $db->begin();

    // Fetch org_id from device table
    $device = fetchFromDB('SELECT org_id, id, active FROM device WHERE uuid = %s', [$uuid]);
    if (!$device->active) {
        throw new Exception(ERROR_MSG['user_inactive']);
    }
    $org_id = (int)$device->org_id;

    // Fetch szif_task_id from task table
    $task = fetchFromDB(
        'SELECT szif_task_id FROM task WHERE org_id = %i AND id = %i',
        [$org_id, $task_id]
    );
    if (!$task) {
        throw new Exception('Task not found.');
    }
    $szif_task_id = (int)$task->szif_task_id;

    // Validate typ_pozadavku and phone number
    $valid_types = ['0', '1', '2'];
    if (!in_array($typ_pozadavku, $valid_types, true)) {
        throw new Exception(ERROR_MSG['input_validation_error']);
    }
    if (!validate_phonenumber($tel_cislo)) {
        throw new Exception(ERROR_MSG['input_validation_error']);
    }

    // Fetch last request and determine if another request can be sent
    $last_request = fetchFromDB(
        'SELECT last_time_sent, number_sent FROM contact_requests WHERE org_id = %i AND task_id = %i ORDER BY sent_at DESC LIMIT 1',
        [$org_id, $task_id]
    );

    $now = new DateTime();
    $can_send = true;

    if ($last_request) {
        $last_time_sent = new DateTime($last_request->last_time_sent);
        $interval = $now->diff($last_time_sent);

        if (($interval->h < 1 && $last_request->number_sent >= 2) || $interval->days < 1) {
            $can_send = false;
        }
    }

    if (!$can_send) {
        throw new Exception(ERROR_MSG['sync_needed']);
    }

    // Prepare and send IS_MACH request
    $ismach_data = [
        'ji' => $org_id,
        'task_id' => $szif_task_id,
        'typ_pozadavku' => $typ_pozadavku,
        'tel_cislo' => $tel_cislo,
        'datum' => $datum
    ];

    $ch = curl_init('http://localhost/ws/ismach/test_rozhrani.php');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($ismach_data));

    $ismach_result = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if ($http_code !== 200 || $curl_error) {
        throw new Exception('IS_MACH Request Failed: ' . $curl_error);
    }

    // Check IS_MACH Response
    $ismach_response = json_decode($ismach_result, true);
    if (json_last_error() !== JSON_ERROR_NONE || $ismach_response['status'] !== 'success') {
        throw new Exception('IS_MACH response error: ' . ($ismach_response['message'] ?? 'Unknown error'));
    }

    // Determine platform from audit logs
    $platform = 'web';
    $audit_log = fetchFromDB('SELECT poznamka FROM audit WHERE uuid = %s ORDER BY created DESC LIMIT 1', [$uuid]);
    if ($audit_log) {
        $note = $audit_log->poznamka;
        $platform = (strpos($note, 'android') !== false) ? 'Android' : ((strpos($note, 'iOS') !== false) ? 'iOS' : 'web');
    }

    $query = 'INSERT INTO contact_requests 
    (org_id, task_id, typ_pozadavku, tel_cislo, datum, last_time_sent, number_sent, platform_of_request, uuid, request_status, request_note, szif_task_id) 
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';

$params = [
    $org_id, $task_id, $typ_pozadavku, $tel_cislo, $datum,
    $now->format('Y-m-d H:i:s'),
    ($last_request ? $last_request->number_sent + 1 : 1),
    $platform, $uuid, 'ok', 'Request successfully sent to IS_MACH', $szif_task_id
];

    $db->query($query, $params);

    // Commit transaction
    $db->commit();

    // Log success in audit
    $audit->set_dulezitost(Audit::$udalost_dulezitost[0]);
    $audit->execute('Interface - success', json_encode($data), $ismach_result);

    echo json_encode(['status' => 'ok', 'message' => 'Request successful']);

} catch (Exception $e) {
    // Rollback transaction
    $db->rollback();

    // Log error in audit
    $audit->set_dulezitost(Audit::$udalost_dulezitost[1]);
    $audit->execute('Interface - error', json_encode($data), $e->getMessage());

    // Return error response
    echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}

// End time recording and log execution time
$time_end = microtime(true);
$audit->set_exec_time($time_end - $time_start);
?>

It throws an error like:

Array
(
    [status] => error
    [message] => Database query error: Query failed.
)
{"status":"error","message":"Database query error: Query failed."}

But I really don’t know why so…

Why I am having the email protected problem in laravel? [closed]

I have a view on which I am displaying some text. That is generating through API url. When I am printing that page in flutter application. I am getting the problem that the email in that text is converting to email protected. What is the solution to this.

this is the code:

<center style="margin-bottom: 30px;" class="">
        <strong class="company-header">{!! nl2br(e(str_replace(',', "n", $adminUser->company_header))) !!}</strong>
      
    </center>

And this is the output of the view on web:
enter image description here

When I am printing this in the flutter application, the email changes to email protected.

Getting error:invalid_grant in Salesforce for grant type authorization_code if giving authorization from another org

I am having issue on granting authorization for user that is outside of my app’s org.

here is the http post request I am trying to make, I am using authorization_code so I can get refresh token as I need it.

$response = $client->post($tokenUrl, [
 'form_params' => [
  'grant_type' => 'authorization_code',
  'client_id' => $clientId,
  'client_secret' => $clientSecret,
  'redirect_uri' => $redirectUri,
  'code' => $authorizationCode,
 ],
]);

I am not sure if I’m missing something on my salesforce set up, below are screenshots:

Screenshot of Oauth Settings 1

Screenshot of Oauth Settings 2

Oauth Policy Settings

Here is a screenshot of granting permission

Permission Grant

The error I got

{“error”:”invalid_grant”,”error_description”:”authentication failure”}

I want to successfully grant any org to access my connected app

How to get the time hh:mm:ss of any state starting by seconds from midnight without changing date_default_timezone_set regardless of the state I am in

For some reason in my code at the top of the page there’s date_default_timezone_set('America/Belize'); and I don’t want to change it.

For getting the current London seconds from midnight (or any other timezone) regardless of the state I am in I’ve tryied with a small function (just a little modded) found here on StackOverflow:

function seconds_from_midnight($iana_timezone = 'Europe/London'){
    $time_now = time(); //UNIX TIMESTAMP (IT'S THE SAME EVERYWHERE)
    $date = new DateTime(); 
    $date->setTimestamp( $time_now );
    $date->setTimezone(new DateTimeZone($iana_timezone));
    $date->modify('today midnight');
    $midnight_time = $date->getTimestamp();
    $seconds_since_midnight = $time_now - $midnight_time;
    return $seconds_since_midnight;
}

I think this first part it’s correct because it use a unix timestamp (UTC-0 starting from 1970).

Then I check the time in London with:

$r = seconds_from_midnight();
echo 'Time London now: '.date('H:i:s', $r).'<br>'; //How to do this for each state?

[It should be the correct time if you are a person in London looking at the clock right now]

Now see the problem that occurs:

date it’s refers to the server, so gives me back a wrong time (I don’t know why but I think the reason it’s date_default_timezone_set at the beginning of the page, that I don’t want to change).

Please note: The timezone given by the variable $iana_timezone may be different from Europe/London.

I don’t live in America/Belize and the PHP server it is in an other state (I don’t know which one and honestly I don’t care).

So, how to get the time from midnight in London (or in another state) in this conditions?

How to fetch WordPress page with exact style and render on a PHP website?

I was looking for a way to render a WordPress page in a custom PHP based website. I succeeded in that but it is not styled as it is on WordPress.

Please tell me how can I fetch the page exactly as it is on WordPress?

I have this code to display the webpage:

<?php include('view/header_copy.php'); ?>

<div class="pt-20 pt-md-18 pt-lg-20 pb-13 pb-md-17 pb-lg-33 px-10 px-md-20 px-lg-20 px-xl-30">
  <div id="wp-content-container"></div>
</div>

<script>
  fetch('https://blogs.domainnamehere.com/wp-json/wp/v2/pages?slug=success-stories')
  .then(response => response.json())
  .then(data => {
    const page = data[0];
    document.getElementById('wp-content-container').innerHTML = page.content.rendered;
  })
  .catch(error => console.error('Error fetching page:', error));
</script>

<?php include('view/footer_copy.php'); ?>

PHP-DI invalid definition exception, factory is neither a callable nor a valid container entry

I am trying to use php-di in a project for creating a renderer that renders my default views.

This is how my index.php looks like :

<?php
require "../vendor/autoload.php";
use DIContainerBuilder;
use FrameworkRendererRendererInterface;
use FrameworkRendererTwigRendererFactory;
use function DIfactory;

$builder= new ContainerBuilder();
$builder->addDefinitions([
    RendererInterface::class => factory(TwigRendererFactory::class),
    'views.path'=> dirname(__DIR__) . '/views'
]);
$container= $builder->build();
$renderer= $container->get(RendererInterface::class);//<-- Line causing the error
var_dump($renderer);
die();

My TwigRenderFactory looks like this :

<?php
namespace FrameworkRenderer;
use PsrContainerContainerInterface;
class TwigRendererFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new TwigRenderer($container->get('views.path'));
    }
}

My directory hierarchy is like this :

+---public
|   |   index.php
+---src
|   +---Blog
|   |   |   BlogModule.php
|   |   ---views
|   |           index.php
|   |           index.twig
|   |           show.php
|   |           show.twig
|   ---Framework
|       |   App.php
|       |   Router.php
|       |   TwigRendererFactory.php
|       +---Renderer
|       |       PHPRenderer.php
|       |       RendererInterface.php
|       |       TwigRenderer.php
|       ---Router
|               Route.php
+---vendor   
---views
        footer.php
        header.php
        layout.twig
    

And I have my autoload set in my composer.json like this :

"autoload": {
    "psr-4": {
        "Framework\": "src/Framework",
        "App\": "src",
        "Tests\": "tests"
    }
},

With this setup I get this exception from php-di :

Fatal error: Uncaught DIDefinitionExceptionInvalidDefinition:
Entry "FrameworkRendererRendererInterface" cannot be resolved:
factory 'Framework\Renderer\TwigRendererFactory' is neither a callable nor a valid container entry in E:____MQBAKAPOO-pratiquevendorphp-diphp-disrcDefinitionResolverFactoryResolver.php:91
Stack trace:
#0 E:____MQBAKAPOO-pratiquevendorphp-diphp-disrcDefinitionResolverResolverDispatcher.php(71): DIDefinitionResolverFactoryResolver->resolve(Object(DIDefinitionFactoryDefinition), Array)
#1 E:____MQBAKAPOO-pratiquevendorphp-diphp-disrcContainer.php(390): DIDefinitionResolverResolverDispatcher->resolve(Object(DIDefinitionFactoryDefinition), Array)
#2 E:____MQBAKAPOO-pratiquevendorphp-diphp-disrcContainer.php(139): DIContainer->resolveDefinition(Object(DIDefinitionFactoryDefinition))
#3 E:____MQBAKAPOO-pratiquepublicindex.php(23): DIContainer->get('Framework\Rende...')
#4 {main} thrown in E:____MQBAKAPOO-pratiquevendorphp-diphp-disrcDefinitionResolverFactoryResolver.php on line 91

I’ve double-checked everything that I could, I tried to put an echo inside the __invoke() method of the TwigRendererFactory class but it seems the __invoke() method is never called for some reason so I don’t know what to do.

trouble sending post request with to laravel end point for razorpay order ceration

when i send a get request here every thing works perfectly fine but post request gives me errors
react method for sending to payment.razorpay route

`const handlePayment = ()=>{
localStorage.setItem(‘selectedSeats’, selectedSeats);

axios.post(route('seats.checkAvailability'), { selectedSeats })
.then(response => {
  console.log('Success:', response.data);
  try{
      axios.post(route('payment.razorpay'), {
        selectedSeats,
        totalAmount: total,
        user: auth.user
      },
      {headers:{"Content-Type" : "application/json"}}
    );
  } catch (error) {
    console.error(error.response.data);
  }
})
.catch(error => {
  console.log('in catch');
  setErr(error.response.data.error);
});

};`

here is the route
Route::post('/razorpay', [PaymentController::class, 'processPayment'])->middleware(['auth'])->name('payment.razorpay');

function in PaymentController
` public function processPayment( Request $request)
{

    dd('here');

    $request->validate([
        'selectedSeats' => 'required|array',
        'total' => 'required|numeric|min:0',
        '$user' => 'required'
    ]);

    $selectedSeats = $request->input('selectedSeats');
    $totalAmount = $request->input('total'); 
    $user = $request->user();

    $api_key = config('services.razorpay.razorpay_key');
    $api_secret = config('services.razorpay.razorpay_secret');
    $api = new Api($api_key, $api_secret);
    
    try {
    $order = $api->order->create([
        'amount' => $totalAmount * 100,
        'currency' => 'INR',
        'receipt' => 'order_receipt_id_123',
        'payment_capture' => 1 // Auto capture payment
    ]);
    } catch (Exception $e) {
        return response()->json(['status' => 'error', 'message' => 'Failed to create Razorpay order'], 500);
    }

    $data = [
        "key"  => $api_key, 
        "amount" => $order['amount'], // In paise
        "currency" => $order['currency'],
        "name" => $user->name,
        "description" => "Ticket Purchase",
        "image" => "https://cdn.razorpay.com/logos/GhRQcyean79PqE_medium.png",
        "prefill" => [
            "name" => $user->name,
            "email" => $user->email
        ],
        "theme" => [
            "color"  => "#3399cc"
        ],
        "order_id" => $order['id'], // Pass the order ID from Razorpay
    ];

    return Inertia::render('Checkout', [
        'data' => $data, // No need to json_encode here, Inertia will handle it
        'selectedSeats' => $selectedSeats, // Pass selected seats to the view
        'totalAmount' => $totalAmount, // Pass the total amount
    ]);
}`

i tried adding a dd() at the start of the function but the request wont even reach there
i also tried using Inertia.post

should i keep this as a get route cause it works perfectly fine, if yes where should i pass the data ?

xdebug not installed on php 8.3 docker container

I’m using this Dockerfile

FROM php:8.3-apache

RUN pecl install xdebug-3.3.2 && docker-php-ext-enable xdebug

RUN apt-get update && apt-get install -y 
    libfreetype6-dev 
    libjpeg62-turbo-dev 
    libpng-dev 
    libzip-dev 
    zip 
    && docker-php-ext-configure gd --with-freetype --with-jpeg 
    && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql zip

RUN echo "xdebug.mode=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

RUN a2enmod rewrite

EXPOSE 9003

WORKDIR /var/www/html

COPY apache-config.conf /etc/apache2/sites-available/000-default.conf

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

CMD ["apache2-foreground"]

when I check phpinfo() I see that xdebug is no t installed, the same Dockerfile with

FROM php:8.1-apache

RUN pecl install xdebug-3.1.1 && docker-php-ext-enable xdebug

works with no problems

I checked on xdebug web and xdebug 3.3.2 is compatible with php 8.3

In the group chat, my bot always forces me to reply every time I launch Telegram

I’ve made a simple Telegram bot that invites a user to a Trello board and notifies all users in the group chat when a card is moved from one list to another. I’m facing a problem. Every time I launch Telegram and select the group chat, I get this. In a private chat between me and the bot, everything is fine.

This is the GitHub repo of my project: https://github.com/loglinn05/loglinn05_chatos_bot/

To handle webhook requests from Telegram, I use defstudio/telegraph. This is what my handler class looks like:

<?php

namespace AppTelegram;

use AppModelsUser;
use DefStudioTelegraphEnumsChatActions;
use DefStudioTelegraphHandlersWebhookHandler;
use GuzzleHttpClient;

class Handler extends WebhookHandler
{
  private $trelloApiBaseUrl;
  private $trelloApiKey;
  private $trelloApiToken;
  private $boardId;

  public function __construct()
  {
    $this->trelloApiBaseUrl = env("TRELLO_API_BASE_URL");
    $this->trelloApiKey = env("TRELLO_API_KEY");
    $this->trelloApiToken = env("TRELLO_API_TOKEN");
    $this->boardId = env("BOARD_ID");
  }

  public function start()
  {
    $from = $this->message->from();
    $fromUser = User::where('telegram_user_id', $from->id())->first();

    $this->chat->action(ChatActions::TYPING)->send();

    // saying hello
    $name = $from->firstName();
    $this->reply("Hi, $name!");

    // adding a user to the database if they're not there
    if (!$fromUser) {
      $user = new User();
      $user->telegram_user_id = $from->id();
      $user->first_name = $from->firstName();

      if ($from->lastName()) {
        $user->last_name = $from->lastName();
      }

      $user->telegram_username = $from->username();
      $user->save();

      if ($user) {
        $this->chat->action(ChatActions::TYPING)->send();
        $this->reply("You've been added to the database.");
      }
    }

    $this->chat->action(ChatActions::TYPING)->send();
    $this->reply("If you need further assistance, enter /help.");
  }

  public function help()
  {
    $this->chat->action(ChatActions::TYPING)->send();
    $this->reply("
      I can invite you to our Trello board. Let's work _together_! xE2x9CxA8
      n*Enter /invite to proceed.*
    ");
  }

  public function invite()
  {
    $from = $this->message->from();
    $fromUser = User::where('telegram_user_id', $from->id())->first();

    $fromUser->status = "providing email";
    $fromUser->save();
    $this->forceToEnterEmail();
  }

  public function handleUnknownCommand(IlluminateSupportStringable $text): void
  {
    $this->chat->action(ChatActions::TYPING)->send();
    $this->reply("What do you mean?
    nI don't know this command! xF0x9Fx98x85");
  }

  public function handleChatMessage($email): void
  {
    $from = $this->message->from();
    $fromUser = User::where('telegram_user_id', $from->id())->first();

    if ($fromUser->status == "providing email") {
      $fullName = [];

      // set the user's email if it's not set
      // and set the full name for the invitation request
      if ($fromUser) {
        $fullName = ['fullName' => "{$fromUser->first_name} {$fromUser->last_name}"];
      }

      $invitationResponse = $this->sendInvitationRequest($email, $fullName);

      if (
        $invitationResponse->getStatusCode() == 200
      ) {
        if (!$fromUser->email) {
          $fromUser->email = $email;
          $fromUser->save();
        }
        $this->onSuccessfulInvitation();
      } elseif (
        $invitationResponse->getBody() == 'Member already invited'
      ) {
        $this->clearFromUserStatus();

        $this->chat->action(ChatActions::TYPING)->send();
        $this->reply("You're already invited. Enjoy the experience!");

        $this->getLinkToTheBoard();
      } elseif (
        json_decode($invitationResponse->getBody())->message == "invalid email address"
      ) {
        $this->chat->action(ChatActions::TYPING)->send();
        $this->reply("Invalid email address.");

        $this->forceToEnterEmail();
      } else {
        $this->clearFromUserStatus();

        $this->chat->action(ChatActions::TYPING)->send();
        $this->reply("Unknown error occurred during invitation attempt.");
      }
    }
  }

  private function forceToEnterEmail()
  {
    $this->chat->action(ChatActions::TYPING)->send();
    $this->chat->message("Please, enter your email so I can invite you:")->forceReply("Enter your email here...", selective: true)->send();
  }

  private function sendInvitationRequest($email, $fullName)
  {
    $client = new Client();
    $invitationResponse = $client->put(
      "$this->trelloApiBaseUrl/boards/$this->boardId/members?email=$email&key=$this->trelloApiKey&token=$this->trelloApiToken",
      [
        'http_errors' => false,
        'json' => $fullName
      ]
    );
    return $invitationResponse;
  }

  private function clearFromUserStatus()
  {
    $from = $this->message->from();
    $fromUser = User::where('telegram_user_id', $from->id())->first();

    $fromUser->status = null;
    $fromUser->save();
  }

  private function onSuccessfulInvitation()
  {
    $this->clearFromUserStatus();

    $this->chat->action(ChatActions::TYPING)->send();
    $this->reply("You've been successfully invited.");
    $this->getLinkToTheBoard();
  }

  private function getLinkToTheBoard()
  {
    $client = new Client();

    $getBoardResponse = $client->get("$this->trelloApiBaseUrl/boards/$this->boardId?key=$this->trelloApiKey&token=$this->trelloApiToken");

    if ($getBoardResponse->getStatusCode() == 200) {
      $linkToTheBoard = json_decode($getBoardResponse->getBody())->url;

      $this->chat->action(ChatActions::TYPING)->send();
      $this->reply("Here's the link to the board:
      n$linkToTheBoard");
    } else {
      $this->chat->action(ChatActions::TYPING)->send();
      $this->reply("Unfortunately, we couldn't get the link to the board.");
    }
  }
}

As you can see, the selective field is set to true:

private function forceToEnterEmail()
{
  $this->chat->action(ChatActions::TYPING)->send();
  $this->chat->message("Please, enter your email so I can invite you:")->forceReply("Enter your email here...", selective: true)->send();
}

But the bot still forces a user to enter their email.

So I decided to write something to the log in this function. And I noticed that nothing was added into the log file when I started Telegram again. In a PowerShell terminal where ngrok was running, I didn’t notice any requests to the Telegram API when the app launches.

If you have any ideas on how to solve this issue, please, share them. I’ll appreciate any help.

If you need something else to understand my question, feel free to ask.

Create an image to specific size and fill any space with black infill in PHP

Looking to resize images to set dimensions of (1080×1350) without cropping, just fill the dead space with black boarders/buffers.

As we can’t control what size and aspect ratios users uploads images. Im looking to create a php function that creates a ‘canvas’ that has set dimensions of 1080×1350.

I then place the users image in the middle this ‘canvas’ (without cropping) and fill any dead space with black boards.

Here’s what I’ve developed so far:

// orignal image size
$width = imageSX($image);
$height = imageSY($image);


// canvas size
$thumb_width = 1080;
$thumb_height = 1350;


$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
        
if ( $original_aspect >= $thumb_aspect ) {
    $new_height = $thumb_height;
    $new_width = $width / ($height / $thumb_height);
} else {
    $new_width = $thumb_width;
    $new_height = $height / ($width / $thumb_width);
}
        
$tmp = imagecreatetruecolor( $thumb_width, $thumb_height );
imagealphablending($tmp, false);
imagesavealpha($tmp, true);
        
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
imagefilledrectangle($tmp, 0, 0, round($new_width), round($new_height), $transparent);
        
                
// Resize and crop
imagecopyresampled($tmp, $image, round(0 - ($new_width - $thumb_width) / 2), round(0 - ($new_height - $thumb_height) / 2), 0, 0, round($new_width), round($new_height), round($width), round($height));


what changes would I need to achieve the expected results. I think i’m close, but just would like to bounce some ideas around.
Thank you.

Issues After Upgrading Laravel from 7 to 11 and Passport from 9 to 12

I have upgraded Passport from version 7 to 12 and uploaded my files to the server, which is now running Laravel 11. I’m wondering if the existing customers’ access tokens and refresh tokens will remain valid or if they will become invalid after the upgrade. In the case that the tokens do become invalid, what steps should I take to resolve this issue and ensure that customers can continue accessing their accounts seamlessly?

Shgow WooCommerce Total price With & Without VAT Tax on Checkout

In WooCommerce I need to show the price inclusive VAT and without VAT. The price is including VAT. On checkout and cart, the price is show including VAT.

Below the total price (including VAT), I need a line with the price exclusive VAT. Preferable with the amount of VAT which is charged.

I cannot see how to do this.
Does anyone has an idea?