Array to string conversion in Laravel 11 Models

I am having a problem with my relationships in model using composite key. I am using the package ThiagoprzCompositeKeyHasCompositeKey. If i am only using a single key for the relationships in models, I am not having a problem. I also wanna ask too if what is the correct usage for the controllers. Here is my current controller

Here is so far what I got from debugging From PHP Tinker

public function index(Request $request)
    {
        try {
            $crse_id = $request->input('crse_id');
            $crse_offer_nbr = $request->input('crse_offer_nbr');
            $strm = $request->input('strm');
            $session_code = $request->input('session_code');
            $class_section = $request->input('class_section');

            $classData = ClassTbl::with([
                'classChrstc',
                'institution:institution,descr', 
                'termTable:strm,descr',         
                'academicSubject:subject'     
            ])
            ->where('crse_id', $crse_id)
            ->where('crse_offer_nbr', $crse_offer_nbr)
            ->where('strm', $strm)
            ->where('session_code', $session_code)
            ->where('class_section', $class_section)
            ->first();

            if (!$classData) {
                return response()->json([
                    'success' => false,
                    'message' => 'Class data not found.'
                ], 404);
            }

            return response()->json([
                'success' => true,
                'data' => $classData,
                'message' => 'Class data retrieved successfully.'
            ]);

        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve class data.',
                'error' => $e->getMessage()
            ], 500);
        }
    }
    public function classTbl()
    {
        return $this->belongsTo(ClassTbl::class, 'crse_id', 'crse_id')
            ->whereColumn('class_tbl.crse_offer_nbr', 'class_chrstcs.crse_offer_nbr')
            ->whereColumn('class_tbl.strm', 'class_chrstcs.strm')
            ->whereColumn('class_tbl.session_code', 'class_chrstcs.session_code')
            ->whereColumn('class_tbl.class_section', 'class_chrstcs.class_section');
    }
    public function classChrstc()
    {
        return $this->hasMany(ClassChrstc::class, 'crse_id', 'crse_id')
            ->whereColumn('class_chrstcs.crse_offer_nbr', 'class_tbl.crse_offer_nbr')
            ->whereColumn('class_chrstcs.strm', 'class_tbl.strm')
            ->whereColumn('class_chrstcs.session_code', 'class_tbl.session_code')
            ->whereColumn('class_chrstcs.class_section', 'class_tbl.class_section');
    }

Why does Carbon::createFromFormat() not throw an exception when given a UK format and a US date?

I have this code:

try {
    Carbon::createFromFormat('dmY', $rawDate)->format('Ymd');
} catch (InvalidFormatException $e) {
    echo 'Oops, bad date format.';
}

If I feed in 31012024 as my $rawDate value, I get 20240131 back as the output. This is correct. Carbon has correctly read and then formatted the date as I would expect it to.

If, instead, I feed in 01312024 (the 1st day of the 31st month of the year), I get back 20260701 as the output. This is not what I’d expect, as the 31st month does not exist, and I would have assumed that Carbon would throw an InvalidFormatException exception because the month simply cannot exist.

I could run the string through a script to validate that the first two characters are lower than 31 and the third and fourth characters are lower than 12, but I don’t want to account for the different month lengths and leap years.

My question is, is there a different Carbon method I could call before the createFromFormat to validate that the date format is correct first?

I cannot use parse as this would successfully parse the American date format, which I do not want the script to do; it must accept and validate a UK date format.

No other format but ddmmyyyy should be accepted.

For reference, I am using Carbon 2.72.5 and am not in a Laravel environment, so I cannot use Laravel validation tools.

How to Map GridDB Data Types to Laravel Eloquent Models When Using the GridDB PHP Client?

I’m building a Laravel application where I need to store and retrieve data from GridDB. I’ve successfully established a connection to GridDB and can perform basic operations like creating containers and inserting data.

However, I’m facing challenges with mapping GridDB data types to Eloquent model attributes.

What I’ve Done:

  • I have a container in GridDB with the following schema:

    id (INTEGER)

    sensor_id (STRING)

    value (DOUBLE)

    timestamp (TIMESTAMP)

  • Laravel Eloquent Model:

<?php



namespace AppModels;



use IlluminateDatabaseEloquentModel;



class SensorData extends Model
{
protected $table = 'sensor_data';
protected $primaryKey = 'id';
public $incrementing = false;
public $timestamps = false;



protected $fillable = [
'id',
'sensor_id',
'value',
'timestamp',
];



protected $casts = [
'id' => 'integer',
'sensor_id' => 'string',
'value' => 'double',
'timestamp' => 'datetime',
];
}
  • Data Retrieval:
$data = SensorData::where('sensor_id', 'sensor_001')
->whereBetween('timestamp', [$startDate, $endDate])
->get();

and for this i get:

Undefined Table or Column:
Base table or view not found: 1146 Table 'mydatabase.sensor_data' doesn't exist

If I try to fetch data directly using the GridDB PHP client and map it to the model, I get errors related to data type mismatches, especially with the timestamp field.

How can I correctly map GridDB data types to Laravel Eloquent model attributes?

How to define a service for mailer with a specific transport

I am using Monolog with HTML email formatter to send some alerts.

monolog:
    # ....
    symfony_mailer:
        type:           symfony_mailer
        from_email:     "%admin_email%"
        to_email:       "%admin_email%"
        subject:        "A problem occurred"
        level:          info
        content_type:   text/html
        formatter:      monolog.formatter.html

I want sending email with a specific email account defined as transport “monolog”

# config/packages/mailer.yaml
framework:
    mailer:
        transports:
            main: '%env(MAILER_DSN)%'
            monolog: '%env(MAILER_DSN_IMPORTANT)%'

For that, I can specify a service to use in the monolog config like mailer: 'monolog_mailer_transport' but I am not able to define the service to use the “monolog” transport.

service:
    # ....
    # NOT WORKING : HOW TO DEFINE THE SERVICE TO USE THE TRANSPORT 'MONOLOG' ?
    monolog_mailer_transport:
        class: SymfonyComponentMailerTransportTransportInterface
        factory: ['@mailer.transports', 'get']
        arguments: ['monolog']

Why does Laravel Sanctum return 401 Unauthorized even with a valid token in the database?

I am using Laravel Sanctum to authenticate API requests in my application, which involves two models: User and Customer, as the application supports two separate frontends. Currently, I am focusing on authenticating the User model. However, when I try to access the “/me” route, I consistently receive a 401 Unauthorized error, despite having a valid token stored in the database.

Can someone help me pls ?

api . php

<?php

use AppHttpControllersAuthAuthController;
use IlluminateSupportFacadesRoute;


Route::post('/users/login', [AuthController::class, 'loginUser']);
Route::post('/customers/login', [AuthController::class, 'loginCustomer']);


Route::middleware('auth:sanctum')->group(function () {
    // Shared protected routes
});
Route::middleware(['auth:user'])->group(function () {
    Route::get('/me', [AuthController::class, 'getMe']);
});
Route::middleware('auth:customer')->group(function () {
});

AuthController . php

<?php

namespace AppHttpControllersAuth;

use AppHttpControllersController;
use AppHttpRequestsLoginRequest;
use AppModelsUser;
use AppServicesApiResponse;
use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;
use IlluminateHttpJsonResponse;

class AuthController extends Controller
{
    public function loginUser(LoginRequest $request): JsonResponse
    {
        $credentials = $request->validated();

        $user = User::whereEmail($credentials['email'])->first();
        if (!$user || !Hash::check($credentials['password'], $user->password)) {
            return ApiResponse::error('Email or Password is wrong');
        }

        return ApiResponse::success('', ['token' => $user->createToken('web', ["role:$user->role"])->plainTextToken]);

    }
    public function loginCustomer()
    {

    }

    public function getMe(Request $request): JsonResponse
    {
        return ApiResponse::success('', ['user' => $request->user()]);
    }
}

env file

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:Idi0Gxc+nRsE6rdrg45645gdfgthhtesoAv6jttFfck=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://localhost:8084

APP_LOCALE=de
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database

PHP_CLI_SERVER_WORKERS=4

BCRYPT_ROUNDS=12

LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=root
DB_PASSWORD=

SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8787

BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database

CACHE_STORE=redis
CACHE_PREFIX=

MEMCACHED_HOST=127.0.0.1

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

VITE_APP_NAME="${APP_NAME}"

auth . php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option defines the default authentication "guard" and password
    | reset "broker" for your application. You may change these values
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'web'),
        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | which utilizes session storage plus the Eloquent user provider.
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'user' => [
            'driver' => 'sanctum',
            'provider' => 'users',
        ],

        'customer' => [
            'driver' => 'sanctum',
            'provider' => 'customers',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | If you have multiple user tables or models you may configure multiple
    | providers to represent the model / table. These providers may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsUser::class,
        ],

        'customers' => [
            'driver' => 'eloquent',
            'model' => AppModelsCustomer::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | These configuration options specify the behavior of Laravel's password
    | reset functionality, including the table utilized for token storage
    | and the user provider that is invoked to actually retrieve users.
    |
    | The expiry time is the number of minutes that each reset token will be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    | The throttle setting is the number of seconds a user must wait before
    | generating more password reset tokens. This prevents the user from
    | quickly generating a very large amount of password reset tokens.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | window expires and users are asked to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),

];

cors . php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['http://localhost:8787'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

];

sanctum.php

<?php

use LaravelSanctumSanctum;

return [

    /*
    |--------------------------------------------------------------------------
    | Stateful Domains
    |--------------------------------------------------------------------------
    |
    | Requests from the following domains / hosts will receive stateful API
    | authentication cookies. Typically, these should include your local
    | and production domains which access your API via a frontend SPA.
    |
    */

    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
        '%s%s',
        'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
        Sanctum::currentApplicationUrlWithPort()
    ))),

    /*
    |--------------------------------------------------------------------------
    | Sanctum Guards
    |--------------------------------------------------------------------------
    |
    | This array contains the authentication guards that will be checked when
    | Sanctum is trying to authenticate a request. If none of these guards
    | are able to authenticate the request, Sanctum will use the bearer
    | token that's present on an incoming request for authentication.
    |
    */

    'guard' => ['web'],

    /*
    |--------------------------------------------------------------------------
    | Expiration Minutes
    |--------------------------------------------------------------------------
    |
    | This value controls the number of minutes until an issued token will be
    | considered expired. This will override any values set in the token's
    | "expires_at" attribute, but first-party sessions are not affected.
    |
    */

    'expiration' => null,

    /*
    |--------------------------------------------------------------------------
    | Token Prefix
    |--------------------------------------------------------------------------
    |
    | Sanctum can prefix new tokens in order to take advantage of numerous
    | security scanning initiatives maintained by open source platforms
    | that notify developers if they commit tokens into repositories.
    |
    | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
    |
    */

    'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),

    /*
    |--------------------------------------------------------------------------
    | Sanctum Middleware
    |--------------------------------------------------------------------------
    |
    | When authenticating your first-party SPA with Sanctum you may need to
    | customize some of the middleware Sanctum uses while processing the
    | request. You may change the middleware listed below as required.
    |
    */

    'middleware' => [
        'authenticate_session' => LaravelSanctumHttpMiddlewareAuthenticateSession::class,
        'encrypt_cookies' => IlluminateCookieMiddlewareEncryptCookies::class,
        'validate_csrf_token' => IlluminateFoundationHttpMiddlewareValidateCsrfToken::class,
    ],

];

php-vips throw an error unable to find libvips-42.so in laravel 11x

I try php-vips with laravel and getting following error,

enter image description here

can anyone please give some solution on that.

i tried troubleshoot using setting path but its not working again.
Path.

i also try changing my php.ini but its still hang on same error.

i also try it with different OS like mac, Window, Linux, but getting a same error.

linux
Unable to ope library 'libvips-42.so'. Make sure that you've installed libvips and that  'libvips-42.so' is on your system's library search path.

window
Unable to ope library 'libvips-42.dll'. Make sure that you've installed libvips and that  'libvips-42.dll' is on your system's library search path.

mac
Unable to ope library 'libvips-42.dylib'. Make sure that you've installed libvips and that  'libvips-42.dylib' is on your system's library search path.

My configuration is:

OS: Ubuntu 24.04 LTS
php : 8.3.11
laravel : 11x
vips : 8.15.1
composer : 2.7.7

How to deploy atomically on Nginx+Php-fpm without losing requests?

During deployment I need to change php-fpm source code (more files), but I don’t want to lose ANY http requests. Old pending requests could be handled by new source code (let’s not worry about compatibility).

I don’t think a reload (USR2 signal) of the php-fpm service is sufficient (it’s not possible to atomically swap the source code because opcache.revalidate_freq), it probably has to do:

  1. php-fpm stop
  2. source code update (mv command)
  3. php-fpm start,

but in that case nginx doesn’t wait for php-fpm to start and starts returning 503 to visitors.

Does anyone know a simple way how to deploy atomically and process 100% of requests?

I have a solution that might work (another server in nginx upstream waiting for php-fpm to start…, configure graceful php-fpm stop…) but it seems complicated.

Why don’t Yii2 views load properly in a Git worktree setup?

I’m using Yii2 Advanced Template with Git and have set up a worktree to work on a different branch. When I access the worktree copy in the browser:

  1. I can navigate directories and see the files directly (e.g., /frontend/web/index.php).
  2. However, no views are rendered; the application does not behave as expected.

Here’s what I’ve already checked:

  • Dependencies are installed in the worktree using composer install.
  • Database migrations are applied with php yii migrate.
  • Permissions for runtime and web/assets are set correctly.
  • Configuration files (main.php and main-local.php) in the common/config directory are identical to the main branch and correctly point to the database and other resources.

This issue does not happen in the main branch but occurs only in the worktree.

Are there specific considerations or limitations when running a Yii2 Advanced application in a Git worktree? Could this be related to paths, symbolic links, caching, or some missing configuration?

Any insights or debugging tips would be highly appreciated!

Duplicating/Wrong photos visualizing in php with Firebase Storage/DB

I’m working on a system where ESP32 cameras send images to Firebase Storage upon detecting motion. A Python script runs YOLOv8 on these images to detect objects and saves the results in Firebase. On my PHP website, I’m trying to display the results and match the images with their corresponding detection message. However, I’m encountering two issues:

The first photo displayed is incorrect and doesn't match the result.
The message is duplicated in the list.
    <h2>Last Messages</h2>
    <?php if ($results): ?>
        <ul>
            <?php
            // Get all the user devices' MAC addresses
            $userMacAddresses = array_column(array_filter($userDevices, function ($device) use ($username) {
                return isset($device['username']) && $device['username'] === $username;
            }), 'macAddress');

            $messagesWithTimestamp = [];
            $lastPhotos = []; // Initialize an array to store the last photos

            // Firebase Storage bucket name
            $bucketName = "*****";
            $folder = "checkedPhotos";

            // API URL to list items in the folder
            $url = "https://firebasestorage.googleapis.com/v0/b/$bucketName/o?prefix=$folder/";

            // Initialize cURL session to fetch photos from Firebase Storage
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

            // Execute cURL request
            $response = curl_exec($ch);

            // Check for cURL errors
            if (curl_errno($ch)) {
                echo "cURL Error: " . curl_error($ch);
            } else {
                $data = json_decode($response, true);

                // Check if items exist
                if (isset($data['items'])) {
                    foreach ($data['items'] as $item) {
                        // Generate the download URL for each item
                        $fileName = $item['name']; // Full filename (e.g., "checkedPhotos/80:7D:3A:EA:FE:F8_18_11_11_19_18.jpg")
                        $imageUrl = "https://firebasestorage.googleapis.com/v0/b/$bucketName/o/" . urlencode($fileName) . "?alt=media";

                        // Extract MAC address and timestamp from the filename
                        if (preg_match('/([^/]+)_(d{2}_d{2}_d{2}_d{2}_d{2}).jpg$/', $fileName, $matches)) {
                            $macAddress = $matches[1]; // Extracted MAC address
                            $timestampPart = $matches[2]; // Extracted timestamp (e.g., "18_11_11_19_18")

                            // Store the photo along with its MAC address and timestamp
                            $lastPhotos[] = [
                                'macAddress' => $macAddress,
                                'timestamp' => $timestampPart,
                                'url' => $imageUrl
                            ];
                        }
                    }
                }
            }
            curl_close($ch);

            // Loop through each result and prepare the messages with their timestamps
            foreach ($results as $key => $message) {
                $keyParts = explode('_', $key);
                $macAddress = $keyParts[0];

                if (in_array($macAddress, $userMacAddresses)) {
                    if (count($keyParts) >= 6) {
                        $timestamp = implode('_', array_slice($keyParts, 1, 5)); // Create timestamp (e.g., "18_11_11_19_18")
                    } else {
                        $timestamp = null;
                    }

                    $nickname = null;
                    foreach ($cameraInfo as $camera) {
                        if ($camera['macAddress'] === $macAddress) {
                            $nickname = $camera['nickname'];
                            break;
                        }
                    }

                    $displayName = $nickname ? $nickname : $macAddress;

                    $alreadyDisplayed = false;
                    foreach ($messagesWithTimestamp as $existingMessage) {
                        if ($existingMessage['macAddress'] === $macAddress && $existingMessage['timestamp'] === $timestamp) {
                            $alreadyDisplayed = true;
                            break;
                        }
                    }

                    if (!$alreadyDisplayed) {
                        $messagesWithTimestamp[] = [
                            'message' => $message,
                            'nickname' => $displayName,
                            'macAddress' => $macAddress,
                            'timestamp' => $timestamp
                        ];
                    }
                }
            }

            // Match messages to photos
            foreach ($messagesWithTimestamp as &$message) {
                $matchedPhoto = null;

                foreach ($lastPhotos as $photo) {
                    if ($photo['macAddress'] === $message['macAddress'] && $photo['timestamp'] === $message['timestamp']) {
                        $matchedPhoto = $photo['url'];
                        break;
                    }
                }

                $message['photo'] = $matchedPhoto ?: 'No matching photo available.';
            }

            // Display messages and matched photos
            foreach ($messagesWithTimestamp as $message): ?>
                <li>
                    Camera in <strong><?= htmlspecialchars($message['nickname']); ?></strong> detected:
                    <?= htmlspecialchars($message['message']); ?>
                    (Time: <?= htmlspecialchars($message['timestamp']); ?>)
                </li>
                <?php if ($message['photo'] !== 'No matching photo available.'): ?>
                    <img src="<?= htmlspecialchars($message['photo']); ?>" alt="Matched Photo" style="width: 50%; height: auto;">
                <?php else: ?>
                    <p>No matching photo available.</p>
                <?php endif; ?>
            <?php endforeach; ?>
        </ul>
    <?php else: ?>
        <p>No messages available.</p>
    <?php endif; ?>
</div>    ```


Expected Behavior:

    The image should match the result correctly using the MAC address and timestamp from Firebase.
    Each detection message should only appear once.

Actual Behavior:

    The first image displayed on the website doesn’t match the detection result.
    The message gets duplicated.

What I’ve Tried:

    I’ve verified the consistency of the filenames and timestamps.
    I ensured that the photos are fetched and stored correctly from Firebase Storage.
    I checked for duplicates in the messages array before displaying them, but the issue persists.

Any advice on how to debug this or how to fix the matching logic?

How to upload a File from Nuxt JS and Symfony api without any CORS error

i am trying to upload a file from Nuxt3 frontend and Symfony backend. but i am getting this error

Access to fetch at ‘http://localhost:8070/upload-book’ from origin ‘http://localhost:8060’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: It does not have HTTP ok status.

let file = ref<File | null>();

const onSelectFile = (event: any): void => {
  file.value = event.target.files[0];
}

const onSaveBook = () => {
  try {
    if (!file.value) return;

    const formData = new FormData();
    formData.append('file', file.value);

    fetch('http://localhost:8070/upload-book', {
      method: 'POST',
      headers: {
        'Content-Type': 'multipart/form-data',
        'Accept': 'application/json',
        'Access-Control-Allow-Origin': '*',
      },
      body: formData,
    })

  } catch (error) {
    console.log(error);
  }
#[Route('/upload-book', name: 'app_upload_book', methods: ['POST'])]
public function newBook(Request $request): JsonResponse
{
   $file = $request->files->get('file');

    if ($file) {
        $fileName = uniqid() . '.' . $file->getClientOriginalExtension();
        $file->move($this->getParameter('kernel.project_dir') . '/public/uploads', $fileName);

        return new JsonResponse('File uploaded successfully', Response::HTTP_OK);
    }

    return new JsonResponse('No file uploaded', Response::HTTP_BAD_REQUEST);
}

PHP : How to enable ZipArchive manually on Linux

In order to use ZipArchive, we need to install php-zip. But we can not do it by the following method due to the constraint of the server.

sudo apt-get install -y php-zip

How to install php-zip manually to the Linux server?

PHP Version 8.0.30

Build System : Red Hat Enterprise Linux release 8.8 (Ootpa)

I can’t install the GRPC extension for PHP

I tried installing GRPC on Laradock in various ways.

  • First in laradock/php-fpm/Dockerfile:

    RUN apt-get update && apt-get install -y -q git rake ruby-ronn zlib1g-dev && apt-get clean
    RUN pecl install grpc
    
  • Second I did everything according to this instruction

But I always get an error and the download continues indefinitely (as if it goes into recursion):

https://i.imgur.com/Q7ib73P.png

https://i.imgur.com/D1rOz5Y.png

These two errors periodically appear on the screen

Solution with https://cloud.google.com/php/grpc :

In laradock/php-fpm/Dockerfile:

RUN apt-get install autoconf zlib1g-dev php-dev php-pear
RUN pecl install grpc

Result:
https://i.imgur.com/j6yvSMI.png

I have this problem, it says Fatal error: Cannot use $this as parameter in [duplicate]

function before ($this, $inthat)
{
    return substr($inthat, 0, strpos($inthat, $this));
}
function between($this, $that, $inthat)
{
    return before ($that, after($this, $inthat));
}
function after ($this, $inthat)
{
    if (!is_bool(strpos($inthat, $this)))
    return substr($inthat, strpos($inthat,$this)+strlen($this));
}

Fatal error: Cannot use $this as parameter in /home/u550540499/domains/matureguide.in/public_html/application/helpers/global_helper.php
on line **991

We are facing this when we upload my website in hostinger hosting. Can anyone help to resolve it?

Issue with Elementor Custom Query Using an ACF Relationship Field

I’m working on a WordPress site where I use ACF to create relationships between “training programs” and “jobs”. Here’s the setup:

  • I have a custom field group named “Training Program”.
  • In this group, there’s a relational field called “job” that links to a custom post type named “job”.

My goal is to create a custom query in Elementor to display only the jobs associated with a specific training program. Here’s the code I used for the query:

function jobs_query( $query ) {
    $jobs_id = get_field('job', get_the_ID());

    $query->set( 'post_type', 'job' );

    $query->set( 'post__in', $jobs_id );
}
add_action( 'elementor/query/13600', 'jobs_query' );

Problem:
When I use this code, the entire page becomes blank. No specific error is displayed, but it seems that the custom query is causing the issue.

To debug, I added another hook in the footer to check if get_field retrieves the expected data:

add_action( 'wp_footer', function() {
    if ( is_singular( 'training_program' ) ) {
        $training_program_id = get_the_ID();
        $jobs = get_field( 'job', $training_program_id );
        echo '<pre>';
        print_r( $jobs );
        echo '</pre>';
    }
});

With this code, the related jobs are displayed correctly. The ACF field seems well-configured, and the relationships are in place.

Question: Why does the Elementor custom query fail while the get_field function retrieves the data correctly? How can I resolve this issue to display the related jobs in an Elementor loop?

Thank you in advance for your help!