How to return blob in Joomla 5 API

I am writing a custom plugin API that should return PDF, I am using Joomla 5 but I see that it only supports JSON as a return via the View, not only that, but it also requires you to be working with Full MVC structure, is there a away to not do that? I want the flexibility to return a blob or text or whatever from inside the Controller.

class ProductsController extends ApiController
{
 protected $contentType = '';
 protected $default_view = '';

 public function displayList()
 {
 // I need to be able to return here a blob or whatever i want, right now if i return anything the content type in postmen is always "text/html; charset=UTF-8"
 }
}

And this is the view that I don’t really need, but it’s mandatory by Joomla:

class JsonapiView extends BaseApiView
{
        protected $fieldsToRenderList = [];

        protected $fieldsToRenderItem = [];
}

For reference, these are the docs: https://docs.joomla.org/J4.x:Adding_an_API_to_a_Joomla_Component/en

I did try to just return inside the displayList method but it’s not working.

Mail function in php not sending emails

Im trying to send an alert to an email depending on the value of a variable $alert. However, I can’t send any emails no matter what email address I use, but I do get the echo “Email enviado(sent)”, so I know the if structure is working properly! I don’t know if it is of any relevance, but I’m hosting my php file at IONOS. Any help please!

<?php
    date_default_timezone_set('America/Mexico_City');
    $hoy = getdate();
    $fecha = $hoy['hours'] . ":" . $hoy['minutes'] . ":" . $hoy['seconds'] . " " . $hoy['mday'] . "/" . $hoy['mon'] . "/" . $hoy['year'];

    $servername = "db5001424197.hosting-data.io";

    // REPLACE with your Database name
    $dbname = "dbs1200873";
    // REPLACE with Database user
    $username = "dbu300985";
    // REPLACE with Database user password
    $password = "Batman1998#";

    // Keep this API Key value to be compatible with the ESP32 code provided in the project page. If you change this value, the ESP32 sketch needs to match
    $api_key_value = "tPmAT5Ab3j7F9";

    $api_key = $ID = $porcentaje = "";

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $api_key = test_input($_POST["api_key"]);
        if($api_key == $api_key_value) {
            $ID = test_input($_POST["ID"]);
            $alarma = test_input($_POST["alarma"]);
            $pin = test_input($_POST["pin"]);

            if ($pin == 0 ){
                $pin = "none";
            }
            // Create connection
            $conn = new mysqli($servername, $username, $password, $dbname);
            // Check connection
            if ($conn->connect_error) {
                die("Connection failed: " . $conn->connect_error);
            } 
            //**********SISTEMA ANTERIOR**********//
            $sql = "UPDATE instituto SET ultCon = '$fecha' WHERE ID = '$ID'";
            $sql2 = "UPDATE instituto SET pin = '$pin' WHERE ID = '$ID'";
              
            $alter = $conn->query($sql);
            $alter2 = $conn->query($sql2);
            
            if ($alarma == 1){
                $email_from ="[email protected]";

                $email_subject = "Alarma encendida";

                $email_body = "Pin Activado: $pin.n".
                    "Botonera Activada: Si.n".
                    "Sirena Activada: Si.n";

                $to = "[email protected]";

                $headers = "From: $email_from rn";

                $headers .= "Reply-To: $email_from rn";

                mail($to,$email_subject,$email_body,$headers);

                echo "Email enviado";
            }


            echo "¡Conexión exitosa!";
        
            $conn->close();
        }
        else {
            echo "Wrong API Key provided.";
        }

    } else {
        echo "No data posted with HTTP POST.";
    }

    function test_input($data) {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
    }
    ?>

Laravel Defer on API requests

Is it possible to use defer functions on API requests? I can run defer on my website, but through API is not working at all.

Sample scenario:

// Endpoint accessible through browser https://mywebsite.com/something
public function index(Request $request): void
{
    Log::info('Before response sent');
    defer(function () {
        Log::info('Deferred task executed');
    });
    Log::info('After response sent');
}

// Endpoint accessible through API request https://mywebsite/api/something
public function search(Request $request): JsonResponse
{
    Log::info('Before response sent.');
    defer(function () {
        Log::info('Deferred task executed.');
    });
    Log::info('After response sent.');
    
    return response()->json(true);
}

This sample only works when acessing the endpoint through browser. With the API endpoint, by using either tests or Postman, the message Deferred task executed. is never written.

I tried to create a middleware, applied to the API endpoints, in order to make sure the app is terminated so the defer functions execute, but got no luck.

class EnforceDeferForApi
{
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }

    public function terminate(Request $request, $response): void
    {
        app()->terminate();
    }
} 

Any solution?

The update and destroy parameters cannot be used in CRUD Laravel 11

I have a problem when editing my CRUD. When I click edit on my index.tsx page, I can’t display the data stored in the database for editing and can’t be deleted, how is the solution?

Here’s the route for my crud

Route::resource('galeri', GalleryController::class);

this is my index.tsx

import React from "react";
import { Link, usePage, router } from "@inertiajs/react";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { PageProps } from "@/types";
import { route } from 'ziggy-js';


const createPostRoute = route('galeri.create');

// Define the type for a single post
interface Post {
    id: number;
    nama: string;
    deskripsi: string;
    image: string;
}

// Adjust the type to reflect the correct structure of posts
interface Posts {
    data: Post[];
}

const Index = ({ auth }: PageProps) => {
    const { posts } = usePage<{ posts: Posts; auth: PageProps["auth"] }>().props;
    const data: Post[] = posts.data; 

    console.log(data); 

    // Function to handle delete action
    const handleDelete = (id: number) => {
        if (confirm("Are you sure you want to delete this post?")) {
            router.delete(route("galeri.destroy", id));
        }
    };
    

    return (
        <AuthenticatedLayout
            header={<h2 className="font-semibold text-xl text-gray-800 leading-tight">Dashboard</h2>}
        >
            <div className="container mx-auto max-w-7xl mt-4">
                <h1 className="mb-8 text-4xl font-bold text-center">Posts Index</h1>
                <div className="flex items-center justify-between mb-6">
                    <Link
                        className="px-3 py-1.5 text-white bg-blue-500 rounded-md focus:outline-none"
                        href={route("galeri.create")}
                    >
                        Create Post
                    </Link>
                </div>

                <div className="overflow-x-auto">
                    <table className="min-w-full bg-white">
                        <thead>
                            <tr>
                                <th className="px-4 py-2 bg-gray-200 text-gray-600 border-b border-gray-300 text-left text-sm uppercase font-semibold">
                                    #
                                </th>
                                <th className="px-4 py-2 bg-gray-200 text-gray-600 border-b border-gray-300 text-left text-sm uppercase font-semibold">
                                    Nama
                                </th>
                                <th className="px-4 py-2 bg-gray-200 text-gray-600 border-b border-gray-300 text-left text-sm uppercase font-semibold">
                                    deskripsi
                                </th>
                                <th className="px-4 py-2 bg-gray-200 text-gray-600 border-b border-gray-300 text-left text-sm uppercase font-semibold">
                                    image
                                </th>
                                <th className="px-4 py-2 bg-gray-200 text-gray-600 border-b border-gray-300 text-left text-sm uppercase font-semibold">
                                    Actions
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            {data && data.length > 0 ? (
                                data.map(({ id, nama, deskripsi, image }) => (
                                    <tr key={id}>
                                        <td className="px-4 py-2 border-b border-gray-300">{id}</td>
                                        <td className="px-4 py-2 border-b border-gray-300">{nama}</td>
                                        <td className="px-4 py-2 border-b border-gray-300">{deskripsi}</td>
                                        <td className="px-4 py-2 border-b border-gray-300">
                                            
                                            <img 
                                                src={`/storage/${image}`} 
                                                alt={nama} 
                                                className="h-20 w-20 object-cover rounded"
                                            />
                                        </td>
                                        <td className="px-4 py-2 border-b border-gray-300">
                                            <Link
                                                className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 rounded text-xs mr-1"
                                                href={route("galeri.edit", id)}
                                            >
                                                Edit
                                            </Link>
                                            <button
                                                className="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 rounded text-xs"
                                                onClick={() => handleDelete(id)}
                                            >
                                                Delete
                                            </button>
                                        </td>
                                    </tr>
                                ))
                            ) : (
                                <tr>
                                    <td className="px-4 py-2 border-b border-gray-300" colSpan={5}>
                                        No posts found.
                                    </td>
                                </tr>
                            )}
                        </tbody>

                    </table>
                </div>
            </div>
        </AuthenticatedLayout>
    );
};

export default Index;

this is my controller

<?php

namespace AppHttpControllers;

use AppHttpRequestsStoreGalleryRequest;
use AppModelsGallery;
use IlluminateSupportFacadesAuth;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRedirect;
use InertiaInertia;

class GalleryController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
{
    $postgaleris = Gallery::all();

    return Inertia::render('Gallery/index', [
        'auth' => [
            'user' => [
                'name' => Auth::user()->name,
                'email' => Auth::user()->email,
            ],
        ],
        'posts' => ['data' => $postgaleris],
    ]);
}


    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return Inertia::render('Gallery/post');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreGalleryRequest $request)
    {

        $data = $request->validated();


        if ($request->hasFile('image')) {
            $imagePath = $request->file('image')->store('gallery_fotos', 'public');
            $data['image'] = $imagePath;
        } else {
            $data['image'] = null;
        }

        Gallery::create($data);

        return Redirect::route('galeri.index');
    }


    /**
     * Display the specified resource.
     */
    public function show(Gallery $gallery)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Gallery $gallery)
{
    return Inertia::render('Gallery/edit', [
        'post' => [
            'id' => $gallery->id,
            'nama' => $gallery->nama,
            'deskripsi' => $gallery->deskripsi,
            'image' => $gallery->image ? asset('storage/' . $gallery->image) : null,
        ],
    ]);
}


    /**
     * Update the specified resource in storage.
     */
    public function update(StoreGalleryRequest $request, Gallery $gallery)
    {
        $data = $request->validated();

        if ($request->hasFile('image')) {
            if ($gallery->image && Storage::disk('public')->exists($gallery->image)) {
                Storage::disk('public')->delete($gallery->image);
            }
            $data['image'] = $request->file('image')->store('gallery_fotos', 'public');
        }

        $gallery->update($data);

        return Redirect::route('galeri.index');
    }



    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Gallery $gallery)
    {
        $gallery->delete();

        return Redirect::route('galeri.index');
    }

}

I’ve tried to find the problem, but I don’t know where it is because there is no error message for the destroy and update functions

Sweetalert2 not showing in the code, but show in the console

i’m using sweetalert2 for my code, it not works when i use in my code. So, i test the script on the inspect element console on my app. And it works. Anyone can help?

$query = mysqli_query($koneksi,"SELECT `name` FROM `tb_bengkel` WHERE `name` = '$name'");
if(mysqli_num_rows($query) == true)
{
"<script>
var Toast = Swal.mixin({
    toast: false,
    position: 'center',
    showConfirmButton: false,
    timer: 2000
  });
Toast.fire({
    icon: 'error',
    title: 'Name has been used!'
  })
  </script>";
}

Facing issues in integrating payment gateway in php Laravel

I am a novice in php and am facing a issue while integrating Razor Pay in my website.

It gives me this array when asked for payment gateway page. This array is probably from the dd($input)

array:2 [▼ // Modules/Gateways/Http/Controllers/RazorPayController.php:77
  "_token" => "A String with random data"
  "payment_id" => "A String with random data"
]

In the url, if I change /payments? with /pay?, it starts working.

hitpay payment integration not able to implement in PHP

I am trying to implement the HitPay payment gateway.

I can successfully get the response from the payment request.
I am also able to complete the payment.
However, after the payment is made, I need to store the transaction details such as: Transaction ID, Transaction Status, and other relevant details.
For some reason, this part is not working as expected.
I have tried many approaches, but I am unable to identify the issue.

Here is the documentation.

    <!DOCTYPE html>
   <html lang="en">
  <head>
    <meta charset="utf-8">
    <title>HitPay Checkout Drop-in Test Page</title>
  </head>
  

    <body>    
        <script src="https://hit-pay.com/hitpay.js"></script>
        <script>
          // Callback for successful payment
          function onSuccess(data) {
            console.log('onSuccess called:', data);
    
            // Verify if valid data is received
            if (!data) {
              console.error('No data received in onSuccess');
              const el = document.createElement('p');
              el.innerHTML = 'Payment Success, but no data received.';
              document.body.appendChild(el);
              return;
            }
    
            // Display a success message
            const el = document.createElement('p');
            el.innerHTML = 'Payment Success';
            document.body.appendChild(el);
    
            // Send payment details to backend for storage
            fetch('store_payment_details.php', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(data), // Sending received data
            })
              .then((response) => response.json())
              .then((response) => {
                console.log('Payment details stored successfully:', response);
              })
              .catch((error) => {
                console.error('Error storing payment details:', error);
              });
          }
    
          // Callback when payment is closed
          function onClose(data) {
            console.log('onClose called:', data);
            const el = document.createElement('p');
            el.innerHTML = 'Payment Closed';
            document.body.appendChild(el);
          }
    
          // Callback for errors
          function onError(error) {
            console.error('onError called:', error);
            const el = document.createElement('p');
            el.innerHTML = 'Error: ' + (error.message || error);
            document.body.appendChild(el);
          }
    
          // Function to initiate payment
          function onClick() {
            const carttotalValue = 1; // Dynamic total value (e.g., 100 for testing)
            const paymentData = {
              amount: carttotalValue, // Ensure amount matches cart total
              currency: 'SGD',
              email: '[email protected]',
              phone: '1111',
              order_id: '123',
            };
    
            // Make AJAX request to backend to create the payment request
            fetch('hitpay_payment_request.php', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(paymentData), // Send dynamic data
            })
              .then((response) => response.json())
              .then((response) => {
                const data = response.data;
                console.log("data=",data);
                if (data && data.id) {
                  // Initialize HitPay only once
                  if (!window.HitPay.inited) {
                    window.HitPay.init(
                      'https://securecheckout.hit-pay.com/payment-request/@curvv-tech-private-limited',
                      {
                        domain: 'hit-pay.com',
                        apiDomain: 'hit-pay.com',
                      },
                      {
                        onClose: onClose,
                        onSuccess: onSuccess,
                        onError: onError,
                      }
                    );
                  }
    
                  // Trigger the payment gateway toggle with the provided payment_url
                  window.HitPay.toggle({
                    paymentRequest: data.id, // Dynamic payment ID
                    amount: carttotalValue,
                    name: 'Anbu',
                    phone: '93500239',
                  });
                } else {
                  // Handle error if no payment URL is received
                  console.error('Error: Payment URL not received');
                }
              })
              .catch((error) => {
                console.error('AJAX Error:', error);
              });
          }
        </script>
    
        <button onclick="onClick()">Pay</button>
      </body>
    </html>

hitpay_payment_request.php:

 <?php
//hitpay_payment_request.php
header("Content-Type: application/json");
header("X-Content-Type-Options: nosniff");

$data = json_decode(file_get_contents('php://input'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    echo json_encode(["error" => "Invalid JSON payload"]);
    exit;
}

// Sanitize input
$amount = filter_var($data['amount'] ?? 0, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$currency = filter_var($data['currency'] ?? 'SGD', FILTER_SANITIZE_STRING);
$email = filter_var($data['email'] ?? '[email protected]', FILTER_VALIDATE_EMAIL);
$phone = filter_var($data['phone'] ?? '00000000', FILTER_SANITIZE_STRING);
$order_id = filter_var($data['order_id'] ?? 'ORD123456', FILTER_SANITIZE_STRING);

$requestData = [
    "amount" => $amount,
    "currency" => $currency,
    "email" => $email,
    "phone" => $phone,
    "reference_number" => $order_id,
    "redirect_url" => "https://domain.sg/hit-pay/hitpay_payment_success.php",
    "webhook" => "https://domain.sg/hit-pay/hitpay_payment_details.php",
];

$apiKey = 'my_api_key';
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.hit-pay.com/v1/payment-requests",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode($requestData),
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-BUSINESS-API-KEY: $apiKey"
    ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
    error_log("cURL Error: $err");
    http_response_code(500);
    echo json_encode(["error" => "cURL Error: $err"]);
} else {
    $responseData = json_decode($response, true);
    error_log("API Response: " . $response);
    if (isset($responseData['id'])) {
        echo json_encode(["data" => $responseData]);
    } else {
        http_response_code(500);
        echo json_encode(["error" => "Invalid response from HitPay API"]);
    }
}
?>

response getting:

    {
    "data": {
        "id": "9de0c639-c986-4743-a1ae-70b998068536",
        "name": null,
        "email": "[email protected]",
        "phone": "1111",
        "amount": "1.00",
        "currency": "SGD",
        "is_currency_editable": false,
        "status": "pending",
        "purpose": null,
        "reference_number": "123",
        "payment_methods": [
            "card",
            "paynow_online"
        ],
        "url": "https://securecheckout.hit-pay.com/payment-request/@curvv-tech-private-limited/9de0c639-c986-4743-a1ae-70b998068536/checkout",
        "redirect_url": "https://domain.sg/hit-pay/hitpay_payment_success.php",
        "webhook": "https://domain.sg/hit-pay/hitpay_payment_details.php",
        "send_sms": false,
        "send_email": false,
        "sms_status": "pending",
        "email_status": "pending",
        "allow_repeated_payments": false,
        "expiry_date": null,
        "address": null,
        "line_items": null,
        "executor_id": null,
        "created_at": "2025-01-03T14:53:59",
        "updated_at": "2025-01-03T14:53:59",
        "staff_id": null,
        "business_location_id": null
    }
}

hitpay_payment_details.php:

<?php
// hitpay_payment_deatils.php
header("Content-Type: application/json");
header("X-Content-Type-Options: nosniff");

// Include database connection
include '../rest_api/config.php';

$data = json_decode(file_get_contents("php://input"), true);

if (isset($data['payment_id'], $data['order_id'], $data['payment_status'], $data['payment_gross'], $data['currency_code'], $data['datetime'])) {
    $payment_id = $data['payment_id'];
    $order_id = $data['order_id'];
    $payment_status = $data['payment_status'];
    $payment_gross = $data['payment_gross'];
    $currency_code = $data['currency_code'];
    $datetime = $data['datetime'];

    $stmt = $conn->prepare("INSERT INTO payments (payment_id, item_number, txn_id, payment_gross, currency_code, payment_status, datetime, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, 1)");
    $stmt->bind_param("sssssss", $payment_id, $order_id, $payment_id, $payment_gross, $currency_code, $payment_status, $datetime);

    if ($stmt->execute()) {
        echo json_encode(["status" => "success", "message" => "Payment details inserted successfully."]);
    } else {
        echo json_encode(["status" => "error", "message" => "Failed to insert payment details."]);
    }

    $stmt->close();
} else {
    echo json_encode(["status" => "error", "message" => "Invalid input data."]);
}
?>

hitpay_payment_success.php

<?php
//hitpay_payment_success
// Database connection
include '../rest_api/config.php';

// Get query parameters
$order_id = $_GET['order_id'] ?? null; // Retrieve order_id
$paymentRequestId = $_GET['payment_request_id'] ?? null;
$status = $_GET['status'] ?? null;
$userIp = $_SERVER['REMOTE_ADDR'];

if ($paymentRequestId && $status && $order_id) {
    // Insert into database
    $stmt = $conn->prepare("INSERT INTO payment_redirect_logs (order_id, payment_request_id, status, user_ip) VALUES (?, ?, ?, ?)");
    $stmt->bind_param("ssss", $order_id, $paymentRequestId, $status, $userIp);
    $stmt->execute();
    $stmt->close();

    echo $status === 'completed' ? "<h1>Payment Successful</h1>" : "<h1>Payment Failed</h1>";
} else {
    echo "<h1>Invalid Request</h1>";
}
?>

Php based parser script for WhatsApp webhook json [closed]

I have a working WhatsApp Webhook json dumped into a text file.

Rather than writing from scratch, is there some kind of readymade PHP based script that would parse that json to a readable format (combine messages from same number along with displaying downloaded media, something like WhatsApp web gives).

Only display received messages, no sending required.

Any lead would helpful.

Thanks.

Issue with Assigning Planned Values for Only Start and End Dates in PHP Date Range Logic

I am working on a PHP function that processes planned values for a given date range. The logic should assign specific values based on the following conditions:

Intended Logic:
Special Value (1601852832698) should only be assigned to:

The start_date of the range.
The end_date of the range.
Normal Value (1479103953946) should be assigned to all other days within the range.

If the range spans across multiple months, the logic should correctly handle boundaries:

Process only the days within the current month.
Respect the start_date and end_date across months without assigning the special value to unintended days.

The function incorrectly assigns the special value to additional days, particularly:

The last day of the previous month (if start_date falls in the current month).
The first day of the current month (if end_date falls in the next month).
This error occurs when adjusting start_date and end_date to fit the current month’s boundaries.
For example:

If start_date = 2024-12-03 and end_date = 2024-12-31:
The logic assigns the special value (1601852832698) to November 30 and December 1, which is incorrect.
Only December 3 and December 31 should receive the special value.
Code Snippet:
Here’s the relevant portion of my function:

foreach ($daysInMonth as $day) {
    $currentDate = strtotime($day);

    // Assign special value for start_date and end_date
    if ($currentDate == $startDate || $currentDate == $endDate) {
        $plannedValue = $plannedValues['first_last_day']; // 1601852832698
    } else {
        $plannedValue = $plannedValues['normal_day']; // 1479103953946
    }

    $results[$day] = $plannedValue;
}

Questions:
How can I ensure the special value (1601852832698) is assigned only to the actual start_date and end_date, without impacting other days in the range?
What’s the best way to handle multi-month ranges, ensuring only the correct days in the current month are processed?

WhatsApp cloud API update profile pic error

For unknown reason I am not able to update the profile pic using php curl.

Here is my json response:
(“pic_profile” is the response from /whatsapp_business_profile after tried updating pic image)

"media_ext": "jpg",
"media": "1735806494_b5b3b5c51f19759913fc.jpg",
"media_mime": "image/jpeg",
"media_size_bytes": 4275,
"media_size_mb": "0.004",
"media_size_kb": "4.175",
"media_original_name": "app_archivo.jpg",
"pic_profile": {
    "error": {
        "message": "An unknown error occurred",
        "type": "OAuthException",
        "code": 1,
        "error_subcode": 3441012,
        "is_transient": false,
        "error_user_title": "Image type not supported",
        "error_user_msg": "Upload a JPG image.",
        "fbtrace_id": "AvNAqSXGFVmYsy5cccNApxs"
    }
}

As you can see it’s a real jpg file, also I tried with many other jpg files but anytime it falls.

FYI: I am receiving the handle $file->h without any issue from resumable upload.

Any clue?
Is an error/issue from WA Cloud API side?

Thanks a lot.

I have multiple forms on the page but first one is not working [duplicate]

Good morning i need help with an issue im experiencing day 2 now. This is my code:


<?php 
    $germanCars = array("Bmw","Mercedes","Volkswagen","Porsche");
    $japaneseCars = array("Nissan","Toyota","Honda","Subaru");
    setcookie("fav_vehicle", "{$germanCars[1]}", time() + 86400, "/");

    function defaultList(array $cars): void{
        foreach($cars as $car){
            echo "
        <li>
            $car 
            <form action='selectedCar.php' method='get' style='display:inline;' autocomplete='off'>
                <button type='submit' name='selectedCar' value='$car'>Select</button>
            </form>
        </li>";
        }
    }

    function sortedCars(array $sortedCars): void{
        sort($sortedCars);
        foreach($sortedCars as $sortedCar){
            echo "
        <li>
            $sortedCar 
            <form action='selectedCar.php' method='get' style='display:inline;' autocomplete='off'>
                <button type='submit' name='selectedCar' value='$sortedCar'>Select</button>
            </form>
        </li>";
        }
    }

    function reverseSortedCars(array $reverseSortedCars): void{
        rsort($reverseSortedCars);
        foreach($reverseSortedCars as $car){
            echo"<li>
            $car 
            <form action='selectedCar.php' method='get' style='display:inline;' autocomplete='off'>
                <button type='submit' name='selectedCar' value='$car'>Select</button>
            </form>
            </li>";
        }
    }

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <form action="index.php" method="post">
    <div>
        <span id="orderBtns">
            <button type="submit" name="sortBtn">Sort by name</button>
            <button type="submit" name="reverseBtn">Sort by name (descending)</button>
        </span>

        <h2>German Cars:</h2>
        <ul>
        <?php
            if(isset($_POST["sortBtn"])){
                sortedCars($germanCars);
            }
            else if(isset($_POST["reverseBtn"])){
                reverseSortedCars($germanCars);
            }
            else{
                defaultList($germanCars);
            }
         ?> 
        </ul>

        <h2>Japanese Cars:</h2>
        <ul>
            <?php
                if(isset($_POST["sortBtn"])){
                    sortedCars($japaneseCars);
                }
                else if(isset($_POST["reverseBtn"])){
                    reverseSortedCars($japaneseCars);
                }
                else{
                    defaultList($japaneseCars);
                }
             ?>
        </ul>
    </div>
    </form>
    
</body>
</html>

So the problem is that no matter how the arrays are sorted, the first element in germancars array doesnt have a form tag in it as i checked in the inspect menu. All of the rest are working properly. Im new to php and still learning it is there something in the syntax that causes this problem?

How PHP APCu works in memory segmentation

I am confused about how APCu works and its various configurations.

First question:

For example, we have allocated 3 segments with 32 MB of memory to APCu
According to the technical description of APCu, when we store some variables in this memory, these values ​​are stored in memory after the header block, in other words, this storage starts from the beginning of the first segment. The problem for me starts from where APCu specifies a number of slots for these segments (in the image below, 4099 slots for 96 MB) and when storing information, this information is stored in different slots (according to the image below in the slot distribution, slots 2762 and 3941 have stored information)
According to the technical description, information is stored at the beginning of the segment after the header (in which case the information should be stored in slot 1 from the beginning and the subsequent slots should be filled in order)
And according to the slot distribution, the information is scattered in different slots (in which case each part of the information is located in different segments)
This issue It has caused me to not understand how to store information.
How do segments and slots work?

enter image description here

The second question is:

When we specify the number of slots by apc.entries_hint, for example apc.entries_hint=1000, the value of this number is considered slightly higher in the num_slots section. For example, if we consider this number as 1000, the num_slots number is equal to 1032, and when we consider it as 2000, the num_slots number is 2056. Why is this additional section created?

And the third question:

When more variables are stored by APCu than apc.entries_hint, the number opposite each slot changes (in the number of variables stored less than the value specified in apc.entries_hint, the number opposite each slot is 1). What do these numbers mean?

I changed the APCu settings but still don’t understand how segments and slots work.

Can I achieve zero-downtime deployment by modifying the Nginx configuration file?

I have a PHP project, and the Nginx configuration before releasing a new version is:

        location ~ .php$ {
            root   /data/web/php-project-v1.0.0;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
        }

The server is still handling a large volume of requests. At this point, I modified the Nginx configuration file.

        location ~ .php$ {
            root   /data/web/php-project-v1.1.0;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
        }

Please note that I have pointed the root directive to a new directory. Then I executed: nginx -s reload.

Can this achieve zero-downtime deployment? Advantages, disadvantages, and points to pay attention to, especially during high traffic periods.

I have tested this approach, and it at least doesn’t cause server-side 500 errors. After modifying the configuration, requests that were not yet completed still return results based on the old project’s logic once their processing finishes. However, from my observation, this change doesn’t take effect immediately after executing nginx -s reload. It seems the logic of the old project persists for a while. I hope developers familiar with Nginx can explain this phenomenon and answer my question from a deeper, underlying perspective. Additionally, while searching for this issue on Google, I noticed that very few people use this method. Why don’t more people adopt this technique for automated deployment, especially in scenarios where there aren’t many redundant hosts? Is it because they haven’t thought of it, or are there potential risks involved?

How to Render Product Images in Invoice PDF Using mPDF with Dynamic Image Paths in PHP

I’m using mPDF in my PHP application to generate invoices. When I use a direct live URL for product images, they don’t show up in the PDF. However, when I use base64 encoding, the first product’s image is displayed correctly, but the images for the remaining products don’t show. Interestingly, the images are rendered correctly in the PDF before it’s printed, but only the first product image shows after printing. I’ve tested the URLs and base64 images, and they work fine during PDF rendering. Any suggestions for fixing this?

Invoice controller:

public function printinvoice()
    {
        if (!$this->input->get()) {
            exit();
        }
        $tid = intval($this->input->get('id'));
        $token = $this->input->get('token');
        $validtoken = hash_hmac('ripemd160', $tid, $this->config->item('encryption_key'));
        if (hash_equals($token, $validtoken)) {
            $data['id'] = $tid;
            $data['invoice'] = $this->invocies->invoice_details($tid);
            $data['title'] = "Invoice " . $data['invoice']['tid'];
            $data['products'] = $this->invocies->invoice_products($tid);
            $data['employee'] = $this->invocies->employee($data['invoice']['eid']);
            if (CUSTOM) {
                $data['c_custom_fields'] = $this->custom->view_fields_data($data['invoice']['cid'], 1, 1);
                $data['i_custom_fields'] = $this->custom->view_fields_data($tid, 2, 1);
            }


            $data['round_off'] = $this->custom->api_config(4);
            if ($data['invoice']['i_class'] == 1) {
                $pref = prefix(7);
            } elseif ($data['invoice']['i_class'] > 1) {
                $pref = prefix(3);
            } else {
                $pref = $this->config->item('prefix');
            }
            $data['general'] = array('title' => $this->lang->line('Invoice'), 'person' => $this->lang->line('Customer'), 'prefix' => $pref, 't_type' => 0);
            ini_set('memory_limit', '2048M');
            ini_set('max_execution_time', 120);
            if ($data['invoice']['taxstatus'] == 'cgst' || $data['invoice']['taxstatus'] == 'igst') {
                $html = $this->load->view('print_files/invoice-a4-gst_v' . INVV, $data, true);
            } else {
                $html = $this->load->view('print_files/invoice-a4_v' . INVV, $data, true);
                //    $html=str_replace("strong","span",$html);
                //     $html=str_replace("<h","<span",$html);
            }
            //PDF Rendering
            $this->load->library('pdf');
            if (INVV == 1) {
                $header = $this->load->view('print_files/invoice-header_v' . INVV, $data, true);
                $pdf = $this->pdf->load_split(array('margin_top' => 40));
                $pdf->SetHTMLHeader($header);
            }
            if (INVV == 2) {
                $pdf = $this->pdf->load_split(array('margin_top' => 5));
            }
            $pdf->SetHTMLFooter('<div style="text-align: right;font-family: serif; font-size: 8pt; color: #5C5C5C; font-style: italic;margin-top:-6pt;">{PAGENO}/{nbpg} #' . $data['invoice']['tid'] . '</div>');
            $pdf->WriteHTML($html);
            //  dd($html);            

            if ($this->input->get('d')) {
                $pdf->Output('Invoice_#' . $data['invoice']['tid'] . '.pdf', 'D');
            } else {
                $pdf->Output('Invoice_#' . $data['invoice']['tid'] . '.pdf', 'I');
            }
        }
    }

View invoice pdf page:

<table id="items">
        <tr>
            <th><?php echo $this->lang->line('Products') ?></th>
            <th> <?php echo $this->lang->line('Description') ?></th>
            <th><?php echo $this->lang->line('Price') ?></th>
            <th><?php echo $this->lang->line('Qty') ?></th>
            <th><?php echo $this->lang->line('Amount') ?></th>
        </tr>

        <?php
        $sub_t = 0;

        foreach ($products as $row) {
            $sub_t += $row['price'] * $row['qty'];

            if ($row['serial']) {
                $row['product_des'] .= ' - ' . $row['serial'];
            }

            echo '
        <tr class="item-row">
             <td class="item-name">' . '<div style="display: flex; align-items: center; justify-content: center;">';
            if (!empty($row['product_image'])) {
                try {
                    $imagePath = FCPATH . 'userfiles/product/thumbnail/' . $row['product_image'];
                    if (file_exists($imagePath)) {
                        $imageData = base64_encode(file_get_contents($imagePath));
                        $imageMime = mime_content_type($imagePath);
                        $base64Image = 'data:' . $imageMime . ';base64,' . $imageData;
                        echo '<img src="' . $base64Image . '" alt="' . $row['product'] . '" style="max-width: 200px; margin-right: 5px;">';

                    } else {
                        if ($index === array_key_last($products)) {
                            throw new Exception("Image file not found for the last product: " . $row['product']);
                        }
                        echo "<p>No image found</p>";
                    }
                } catch (Exception $e) {
                    echo '<p>Error: ' . $e->getMessage() . '</p>';
                }
            } else {
                echo "<p>No image</p>";
            }
            echo '</span>&nbsp;' . $row['product'] . '</div></td>
            <td class="description">' . $row['product_des'] . '</td>
            <td>' . amountExchange($row['price'], $invoice['multi'], $invoice['loc']) . '</td>
            <td>' . $row['qty'] . ' ' . $row['unit'] . '</td>
            <td>' . amountExchange($row['subtotal'], $invoice['multi'], $invoice['loc']) . '</td>
        </tr>';
        }
        ?>
</table>

Composer error: Unable to get Local issuer certificate

I am trying to install a library in my web app in a network folder.

Here is my sample terminal:

PS Microsoft.PowerShell.CoreFileSystem::\172.27.45.115htmldrb> C:xamppphpphp.exe C:xamppcomposer.phar require phpoffice/phpspreadsheet

By the way, PHP.exe is not installed in that resource folder(drb website). I have separated my composer.phar in my own local folder as my own solution to install the library but still not works. I’m getting this error:

curl error 60 while downloading https://repo.packagist.json/packages.json: SSL certificate problem: unable to get local issuer certificate 

I’m aware it is blocked by our company’s firewall thing but I’m in need of installing the library. How can I achieve that? I have no connection with our network security guys so I cannot request and address this issue to them. Please help.