Experiencing high loads for Apache/PHP-FPM site [closed]

Traditionally, the load average of our Alma Linux server running our Apache/PHP-FPM/MariaDB website has been 1-3. We’ve recently experienced some good press and it appears our server is getting more traffic and the load is sustaining at 4-6 with burst above 10. We use Cloudflare, when I turn on “Under Attack Mode”, which essentially puts up the page to verify visitors are human, it immediately subsides to back to traditional levels. I’ve been watching Apache server status and see the requests being processed jumps from 5-20 to above 50 and hits 100 causing the high loads and when I need to enable the setting in Cloudflare until it drops to acceptable loads. I can see the status in Cloudflare showing the number of requests on the rise as well when this happens and php-fpm status page shows maxed out active processes. If I increase max_children, the load just increases dramatically as active processes reach their max_children. We are a local newsroom, the high traffic usually traces back to a news story getting shared or picked up by a national company. We got some recent national press, I had to leave the Cloudflare protection on most of the day and week following, and it has been coming in waves since.

So, I am trying to determine if it is time to add another server and look at load balancing or if some optimization is what’s needed. Or both. We are running Apache 2.4.62, PHP-FPM 8.3.24 and MariaDB 10.11.14.

Looking at top it seems php-fpm may be the cause of the high load at 98% CPU for one process during periods of high loads and the rest of the php-fpm processes 10-40% with the MariaDB processlist showing little with no queries more than 0 time, I may have one pop in there for 2-3 seconds, but nothing more and I never see more than 20-25 sleep processes during the high load.

As far as php-fpm, here are the current pertinent settings with typical system info during high loads…

pm = ondemand
pm.max_children = 15
pm.process_idle_timeout = 10s;
pm.max_requests = 500

ATOP - alma1         2025/08/26  18:37:13         -----------------          10s elapsed
PRC |  sys    4.37s  | user  49.41s  |  #proc    189  |  #zombie    0 |  #exit     10  |
CPU |  sys      41%  | user    494%  |  irq       4%  |  idle     61% |  wait      1%  |
cpu |  sys       7%  | user     86%  |  irq       1%  |  idle      6% |  cpu003 w  0%  |
cpu |  sys       6%  | user     84%  |  irq       1%  |  idle      9% |  cpu004 w  0%  |
cpu |  sys       7%  | user     83%  |  irq       1%  |  idle      9% |  cpu001 w  0%  |
cpu |  sys       7%  | user     80%  |  irq       1%  |  idle     12% |  cpu005 w  0%  |
cpu |  sys       7%  | user     80%  |  irq       1%  |  idle     12% |  cpu002 w  0%  |
cpu |  sys       7%  | user     79%  |  irq       1%  |  idle     13% |  cpu000 w  0%  |
CPL |  avg1    9.03  | avg5    9.64  |  avg15   8.23  |  csw    81558 |  intr  104638  |
MEM |  tot    15.4G  | free  250.5M  |  buff   91.9M  |  slab  624.6M |  numnode    1  |
SWP |  tot   512.0M  | free    8.3M  |  swcac   5.9M  |  vmcom  16.1G |  vmlim   8.2G  |
PAG |  numamig    0  | migrate 14e3  |  swin       0  |  swout      0 |  oomkill    0  |
DSK |           sda  | busy      1%  |  read     151  |  write    517 |  avio 0.19 ms  |
NET |  transport     | tcpi   13312  |  tcpo   26862  |  udpi     891 |  udpo     891  |
NET |  network       | ipi    14203  |  ipo    19189  |  ipfrw      0 |  deliv  14203  |
NET |  eth0    ----  | pcki   14197  |  pcko   19173  |  si 3192 Kbps |  so   28 Mbps  |
NET |  lo      ----  | pcki      16  |  pcko      16  |  si    4 Kbps |  so    4 Kbps  |

    PID SYSCPU USRCPU  RDELAY  VGROW  RGROW   RDDSK  WRDSK S  CPUNR  CPU CMD         1/5
2064409  0.16s  8.07s   1.52s 112.8M  45.7M    5.1M     0B R      1  82% php-fpm
2036955  0.25s  3.31s   1.27s  -4.0M  -4.2M      0B     0B S      0  36% php-fpm
2035984  0.29s  3.26s   0.81s   6.0M 133.0M      0B     0B R      4  36% php-fpm
2032153  0.24s  3.16s   1.44s   2.0M   2.0M      0B     0B S      5  34% php-fpm
2032982  0.22s  3.06s   1.36s   8.0M   8.1M      0B     0B S      1  33% php-fpm
2036323  0.22s  2.95s   1.50s     0B 112.0K      0B     0B S      2  32% php-fpm
2036736  0.22s  2.86s   1.28s   2.0M   2.2M      0B     0B S      5  31% php-fpm
2063710  0.28s  2.62s   1.66s     0B 129.3M      0B     0B R      0  29% php-fpm
2039311  0.22s  2.67s   1.12s     0B     0B      0B     0B R      0  29% php-fpm
2035483  0.22s  2.65s   0.95s     0B     0B      0B     0B R      2  29% php-fpm
2033448  0.24s  2.57s   1.22s   4.0M   3.4M      0B     0B S      4  28% php-fpm
2032951  0.21s  2.57s   1.45s  -2.0M  -1.1M      0B     0B S      0  28% php-fpm
2031692  0.21s  2.41s   0.97s -40.2M -34.5M      0B     0B S      0  26% php-fpm
2032826  0.21s  2.38s   1.24s   2.0M   2.0M      0B     0B R      5  26% php-fpm
3480718  0.60s  1.63s   5m46s     0B  13.6M   16.0K   2.3M S      0  22% mariadbd
2064719  0.17s  1.49s   0.43s 841.9M 210.9M      0B     0B S      2  17% php-fpm

Server load: 9.38 9.71 8.25
Total accesses: 16713 - Total Traffic: 1.4 GB - Total Duration: 22404839
CPU Usage: u7.5 s2.7 cu15.16 cs5.47 - 1.77% CPU load
9.62 requests/sec - 0.8 MB/second - 90.0 kB/request - 1340.56 ms/request
29 requests currently being processed, 0 workers gracefully restarting, 67 idle workers

Seeing what is taking my memory, I have this script…

[root@alma1 ~]# cat apache_mem_usage.sh
#!/usr/bin/sh
ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache memory usage (MB): "x/1024; print "Average Apache Process Size (MB): "x/((y-1)*1024)}'
ps -ylC php-fpm | awk '{x += $8;y += 1} END {print "PHP-FPM memory usage (MB): "x/1024; print "Average PHP-FPM Process Size (MB): "x/((y-1)*1024)}'
ps -ylC mariadbd | awk '{x += $8;y += 1} END {print "MariaDB memory usage (MB): "x/1024}'
free
[root@alma1 ~]# ./apache_mem_usage.sh
Apache memory usage (MB): 279.188
Average Apache Process Size (MB): 27.9187
PHP-FPM memory usage (MB): 5103.15
Average PHP-FPM Process Size (MB): 318.947
MariaDB memory usage (MB): 6707.73
               total        used        free      shared  buff/cache   available
Mem:        16113200     9426012      307164      441444     7163324     6687188
Swap:         524284      516656        7628

Perhaps the PHP-FPM process memory usage is higher than it should be? The innodb_buffer_pool_size parameter for MariaDB is set to 6G and I found the query that shows it could possibly need to be 3 times that size or some db optimization may be needed…

MariaDB [(none)]> SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|    18 |
+-------+

So I don’t believe I can give up any of that memory for PHP unless I reduce that number. The largest innodb table I have is 19 million rows that tracks ads and has been running for many years with 3 indexes…

MariaDB [wmnf_www]> SHOW TABLE STATUS LIKE 'wp_ad_tracker' G;
*************************** 1. row ***************************
            Name: wp_ad_tracker
          Engine: InnoDB
         Version: 10
      Row_format: Dynamic
            Rows: 19829074
  Avg_row_length: 52
     Data_length: 1047511040
 Max_data_length: 0
    Index_length: 1000275968
       Data_free: 4194304
  Auto_increment: 146764111
     Create_time: 2025-04-20 09:53:51
     Update_time: 2025-08-26 17:39:10
      Check_time: NULL
       Collation: utf8mb4_unicode_ci
        Checksum: NULL
  Create_options:
         Comment:
Max_index_length: 0
       Temporary: N

I’ll leave it at that for now, looking for pointers or recommendations on best way to proceed to get the loads reduced.

Using the SDK, cloud tasks are always created with default deadline, ignoring setDispatchDeadline

We are creating tasks using the following code with the SDK:

use GoogleCloudTasksV2ClientCloudTasksClient;
use GoogleCloudTasksV2HttpMethod;
use GoogleCloudTasksV2HttpRequest;
use GoogleCloudTasksV2OidcToken;
use GoogleCloudTasksV2Task;

...

$client = new CloudTasksClient();
$parent = $client->queueName(self::PROJECTE, self::REGIO, $this->cua);
            
$httpRequest = new HttpRequest();
$httpRequest->setHttpMethod($metode);
$httpRequest->setUrl(self::prepararUrl($url, $metode, $this->parametres ?? null));
$httpRequest->setHeaders(self::prepararHeaders($headers));
            
if ($parametres && in_array($metode, [HttpMethod::POST, HttpMethod::PUT, HttpMethod::PATCH])) {
    $httpRequest->setBody(http_build_query($parametres));
}
            
if ($this->cua === self::CUA_PERMISOS) {
     $oidcToken = new OidcToken();
     $oidcToken->setServiceAccountEmail(self::SERVICE_ACCOUNT);
     $oidcToken->setAudience(self::URL_SERVEI_WORKER);
     $httpRequest->setOidcToken($oidcToken);
}
            
$tasca = new Task();
$tasca->setHttpRequest($httpRequest);
$tasca->setDispatchDeadline((new GoogleProtobufDuration())->setSeconds(1800));
            
$request = (new GoogleCloudTasksV2CreateTaskRequest())->setParent($parent)->setTask($tasca);
$client->createTask($request);

This is creating tasks with deadlines of 600 seconds, ignoring the 1800 set on the request:
Log for the task created

Acording to the docs, the maximum value is 1800 (30 minutes) for Cloud Task dispatching an HTTP request.

We are using PHP 8.3 with these libraries:

{
  "google/apiclient": "^2.18",
  "google/cloud-storage": "^1.36",
  "google/cloud-logging": "^1.31",
  "google/cloud-error-reporting": "^0.22.7",
  "google/cloud-tasks": "^1.15"
}

Any insight on how/why this happens?

We tried passing a string directly instead of the Durationobject to the method Task::setDispatchDeadline, but the result has always been the same.

Unable to install composer, “Unable to load dynamic library ‘wincache'” [duplicate]

I’m trying to install Composer on my machine and I’ve downloaded the installer from getcomposer.com, but when I run it I get the error “The PHP exe file you specified did not run correctly” with the following program output:

PHP Warning: Module “ldap” is already loaded

PHP Warning: Module “mysqli” is already loaded

PHP Warning: PHP Startup: Unable to load dynamic library ‘wincache’ (tried: C:Program Filesphp8.3.9extwincache (The specified module could not be found), C:Program Filesphp8.3.9extphp_wincache.dll (The specified module could not be found))

It appears based on the output that the problem is with my wincache dll file, but I’ve checked in php8.3.9ext and there is a file called php_wincache.dll. For some reason, the installer doesn’t seem to recognize it. Does anyone know how I can resolve this issue and run the installer?

How to display WooCommerce orders in a custom frontend dashboard with filters and pagination? [closed]

I’m trying to build a custom frontend dashboard (for shop managers) where they can view and filter WooCommerce orders.
Here’s what I need:

  • Display orders in a table (order number, date, status, total, customer, actions).

  • Add filters by date range and order status.

  • Add pagination (so not all orders load at once).

  • Make sure the query is optimized and doesn’t slow down the site when there are thousands of orders.

I’m currently using WC_Order_Query with paginate => true, which works, but I’m not sure if this is the best way to handle performance and scalability.

My questions are:

  • What is the most efficient way to query and display WooCommerce orders in the frontend with filters and pagination?

  • Should I use WC_Order_Query, WP_Query, or maybe a custom SQL query for better performance?

  • Any best practices to avoid slowing down the dashboard when there are many orders?

<?php
defined('ABSPATH') || exit;

if (! is_user_logged_in() || ! current_user_can('manage_woocommerce')) {
    echo '<p>Accesso negato.</p>';
    return;
}

$start_date   = isset($_GET['start_date'])   ? esc_attr($_GET['start_date'])   : '';
$end_date     = isset($_GET['end_date'])     ? esc_attr($_GET['end_date'])     : '';
$status       = isset($_GET['order_status']) ? sanitize_text_field($_GET['order_status']) : '';

$per_page     = 10;
$current_page = max(1, get_query_var('paged', isset($_GET['paged']) ? intval($_GET['paged']) : 1));

$query_args = [
    'paginate'     => true,
    'limit'        => $per_page,
    'paged'        => $current_page,
    'orderby'      => 'date',
    'order'        => 'DESC',
    'status'       => array_keys(wc_get_order_statuses()),
];

// Date filter
if ($start_date && ! $end_date) {
    $query_args['date_created'] = '>=' . $start_date;
} elseif (! $start_date && $end_date) {
    $query_args['date_created'] = '<=' . $end_date;
} elseif ($start_date && $end_date) {
    $query_args['date_created'] = $start_date . '...' . $end_date;
}

// Status filter
if (! empty($status)) {
    $query_args['status'] = $status;
}

// Run query
$orders_data = (new WC_Order_Query($query_args))->get_orders();
$orders      = $orders_data->orders;
$max_pages   = $orders_data->max_num_pages;
$has_orders  = ! empty($orders);
?>

<!-- FILTER FORM -->
<form action="#" method="get" class="woocommerce-order-filter-form form-data-filter">
    <input type="hidden" name="tab" value="orders" />
    
    From
    <input class="date-input" type="date" name="start_date" value="<?php echo esc_attr($start_date); ?>">
    To
    <input class="date-input" type="date" name="end_date"   value="<?php echo esc_attr($end_date); ?>">

    <select name="order_status" class="status-select">
        <option value=""><?php esc_html_e('All statuses', 'woocommerce'); ?></option>
        <?php foreach (wc_get_order_statuses() as $slug => $label): ?>
            <?php $pure_slug = str_replace('wc-', '', $slug); ?>
            <option value="<?php echo esc_attr($pure_slug); ?>" <?php selected($status, $pure_slug); ?>>
                <?php echo esc_html($label); ?>
            </option>
        <?php endforeach; ?>
    </select>

    <input class="date-submit" type="submit" value="<?php esc_attr_e('Filter', 'woocommerce'); ?>">
    <?php if ($start_date || $end_date || $status): ?>
        <a class="button reset" href="?tab=orders"><?php esc_html_e('Reset', 'woocommerce'); ?></a>
    <?php endif; ?>
</form>

<!-- ORDERS TABLE -->
<?php if ($has_orders): ?>
    <table class="gestore-tabella-ordini cpa-dasboard-table">
        <thead>
            <tr>
                <th>Order</th>
                <th>Date</th>
                <th>Status</th>
                <th>Total</th>
                <th>Customer</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($orders as $order): ?>
                <?php
                if (! is_a($order, 'WC_Order')) {
                    continue;
                }

                $status_code  = $order->get_status();
                $status_map   = [
                    'pending'        => ['label' => 'Pending',      'icon' => 'fa-clock'],
                    'processing'     => ['label' => 'Processing',   'icon' => 'fa-gear'],
                    'on-hold'        => ['label' => 'On hold',      'icon' => 'fa-spinner'],
                    'completed'      => ['label' => 'Completed',    'icon' => 'fa-circle-check'],
                    'cancelled'      => ['label' => 'Cancelled',    'icon' => 'fa-circle-xmark'],
                    'refunded'       => ['label' => 'Refunded',     'icon' => 'fa-arrow-rotate-left'],
                    'failed'         => ['label' => 'Failed',       'icon' => 'fa-triangle-exclamation'],
                    'checkout-draft' => ['label' => 'Draft',        'icon' => 'fa-spinner'],
                ];
                $status_data = $status_map[ $status_code ] ?? [
                    'label' => ucfirst($status_code),
                    'icon'  => 'fa-question-circle',
                ];
                ?>
                <tr class="woocommerce-orders-table__row status-<?php echo esc_attr($status_code); ?>">
                    <th scope="row">
                        <span class="order-number">#<?php echo esc_html($order->get_order_number()); ?></span>
                    </th>
                    <td>
                        <time datetime="<?php echo esc_attr($order->get_date_created()->date('c')); ?>">
                            <?php echo esc_html(wc_format_datetime($order->get_date_created())); ?>
                        </time>
                    </td>
                    <td>
                        <span class="status-text status-<?php echo esc_attr($status_code); ?>">
                            <i class="fa-solid <?php echo esc_attr($status_data['icon']); ?>"></i>
                            <?php echo esc_html($status_data['label']); ?>
                        </span>
                    </td>
                    <td>
                        <?php echo $order->get_formatted_order_total(); ?>
                    </td>
                    <td>
                        <?php echo esc_html($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); ?>
                    </td>
                    <td>
                        <a href="/dashboard/?dettaglio_ordine=<?php echo esc_attr($order->get_id()); ?>" class="cpa-btn-secondary">
                            <i class="fa-solid fa-magnifying-glass"></i>
                        </a>
                    </td>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>

    <!-- PAGINATION -->
    <?php if ($max_pages > 1): ?>
        <div class="woocommerce-pagination woocommerce-pagination--numeric woocommerce-Pagination">
            <?php
            $base_url = remove_query_arg('paged');
            ?>
            <?php if ($current_page > 1): ?>
                <a class="woocommerce-button woocommerce-button--previous button"
                   href="<?php echo esc_url(add_query_arg('paged', $current_page - 1, $base_url)); ?>">
                    &larr; Previous
                </a>
            <?php endif; ?>

            <?php for ($i = 1; $i <= $max_pages; $i++): ?>
                <?php if ($i === $current_page): ?>
                    <span class="page-number current"><?php echo $i; ?></span>
                <?php else: ?>
                    <a class="page-number" href="<?php echo esc_url(add_query_arg('paged', $i, $base_url)); ?>">
                        <?php echo $i; ?>
                    </a>
                <?php endif; ?>
            <?php endfor; ?>

            <?php if ($current_page < $max_pages): ?>
                <a class="woocommerce-button woocommerce-button--next button"
                   href="<?php echo esc_url(add_query_arg('paged', $current_page + 1, $base_url)); ?>">
                    Next &rarr;
                </a>
            <?php endif; ?>
        </div>
    <?php endif; ?>

<?php else: ?>
    <?php wc_print_notice('No orders found.', 'notice'); ?>
<?php endif; ?>

When i submit FormData using Json/Ajax it is not going through [closed]

Im trying to add profile photo to my users but when im trying to click submit button it is not going through.

Here is my Json


function getUserFormData(form) {
    return  {
        action: "addUser",
        user: {
            user_id: User : null,
            email: form['email'].value,
            username: form['username'].value,
            password: Util.hash(form['password'].value),
            password_confirmation: Util.hash(form['password_confirmation'].value),
            profile_image: form['profile_image'].value
        }
    };
}

AS.Http.submituser = function (form, data, success, error, complete) {
    AS.Util.removeErrorMessages();

    var $submitBtn = $(form).find("button[type=submit]");
    var $fileupload = $(data).prop('profile_image');
    var formData = new FormData();
    formData.append('file', $fileupload);

    if ($submitBtn) {
        AS.Util.loadingButton($submitBtn, $submitBtn.data('loading-text') || $_lang.working);
    }

    $.ajax({
        url: "/Ajax.php",
        cache: false,
        contentType: false,
        processData: false,
        type: "POST",
        dataType: "json",
        data: data,
        success: function (response) {
            form.reset();

            if (typeof success === "function") {
                success(response);
            }
        },
        error: error || function (errorResponse) {
            AS.Util.showFormErrors(form, errorResponse);
        },
        complete: complete || function () {
            if ($submitBtn) {
                AS.Util.removeLoadingButton($submitBtn);
            }
        }
    });
};

Here is the Back End

    public function add(array $data)
    {
        if ($errors = $this->registrator->validateUser($data, false)) {
            ASResponse::validationError($errors);
        }
        // Handle secure profile image upload
        $files = $data['profile_image'];
        $targetDirectory = "../assets/img/usersprofile/";
        $imageFileType = strtolower(pathinfo($files["profile_image"]["name"], PATHINFO_EXTENSION));

        // Generate a unique image filename: complete_name_uniqueID.extension
        $username = $data['username'];
        $safeName = preg_replace('/[^A-Za-z0-9]/', '_', $username); // Remove special chars
        $uniqueID = uniqid();
        $imageName = "{$safeName}_{$uniqueID}.{$imageFileType}";
        $targetFile = $targetDirectory . $imageName;

        // Validate image file
        $validMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
        $check = getimagesize($files["profile_image"]["tmp_name"]);
        if ($check === false || !in_array($check['mime'], $validMimeTypes)) {
            throw new Exception("Invalid image file format.");
        }

        // Check file size (max 2MB)
        if ($files["profile_image"]["size"] > 2000000) {
            throw new Exception("File size exceeds the 2MB limit.");
        }

        // Restrict executable file uploads
        if (preg_match('/.(php|html|htm|js|exe|sh)$/i', $files["profile_image"]["name"])) {
            throw new Exception("Invalid file type.");
        }

        // Ensure upload directory is safe
        if (!is_dir($targetDirectory) && !mkdir($targetDirectory, 0755, true)) {
            throw new Exception("Failed to create upload directory.");
        }

        // Move uploaded file
        if (!move_uploaded_file($files["profile_image"]["tmp_name"], $targetFile)) {
            throw new Exception("Error uploading the image.");
        }

        $this->db->insert('users', [
            'email' => $data['email'],
            'username' => $data['username'],
            'password' => $this->hashPassword($data['password']),
            'profile_image' => $imageName
        ]);



        Response::success(["message" => trans("user_added_successfully")]);
    }

I tried to append file but unfortunately still nothing happen. i cant see what is error because it is not showing.

Permission of folder it read/writable.

I dont know if the code is right, could you please help me!

How to save Google OAuth user login data to MySQL database [closed]

I am implementing Google OAuth authentication in my PHP application, but the user profile data is not being inserted into my MySQL database. The authentication process works correctly, and I can retrieve the user data from Google, but the insertion into the database fails silently.

// init configuration
$clientID = 'YOUR_CLIENT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
$redirectUri = 'http://localhost/shop/home.php';

$client = new Google_Client();
$client->setClientId($clientID);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirectUri);
$client->addScope("email");
$client->addScope("profile");

if (isset($_GET['code'])) {
    $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

    if (!isset($token['error'])) {
        $client->setAccessToken($token['access_token']);

        $google_oauth = new Google_Service_Oauth2($client);
        $google_account_info = $google_oauth->userinfo->get();

        $email    = $google_account_info->email;
        $fname    = $google_account_info->givenName;
        $lname    = $google_account_info->familyName;
        $password = password_hash($google_account_info->id, PASSWORD_BCRYPT);

        // check if user exists
        $stmt = $conn->prepare("SELECT id, fname, lname, email FROM users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            // user exists
            $user = $result->fetch_assoc();
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['name']    = $user['fname'] . " " . $user['lname'];
            $_SESSION['email']   = $user['email'];
        } else {
            // insert new user
            $stmt = $conn->prepare("INSERT INTO users (fname, lname, email, mobile, password, status_status_id, gender_id) 
                                    VALUES (?, ?, ?, ?, ?, ?, ?)");
            $mobile = "0712345678"; 
            $status = 4; 
            $gender = 1;
            $stmt->bind_param("ssssssi", $fname, $lname, $email, $mobile, $password, $status, $gender);

            if ($stmt->execute()) {
                $userId = $stmt->insert_id;
                $_SESSION['user_id'] = $userId;
                $_SESSION['name']    = $fname . " " . $lname;
                $_SESSION['email']   = $email;
            } else {
                die("Insert failed: " . $stmt->error);
            }
        }

        header("Location: home.php");
        exit;
    } else {
        die("Error fetching token: " . $token['error']);
    }
}

The OAuth flow completes successfully, and I can see that Google returns the user data correctly. However, when a new user tries to log in, the data is not inserted into the database. The script does not throw any errors, and it redirects to home.php, but the user record is not created.

PhpStorm adding script to my GET responses [closed]

I’m responding to a GET request with JSON data (Content-Type
application/json; charset=utf-8), but it keeps tacking on this random script to every response and I cannot get rid of it no matter what I do:

37 requests
720.83 kB / 707.49 kB transferred
Finish: 602 ms
DOMContentLoaded: 214 ms
load: 476 ms
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 503 of the JSON data

{"expected_data":"values"}<script>
(function() {
  var ws = new WebSocket('ws://' + window.location.host + 
             '/jb-server-page?reloadMode=RELOAD_ON_SAVE&'+
             'referrer=' + encodeURIComponent(window.location.pathname));
  ws.onmessage = function (msg) {
      if (msg.data === 'reload') {
          window.location.reload();
      }
      if (msg.data.startsWith('update-css ')) {
          var messageId = msg.data.substring(11);
          var links = document.getElementsByTagName('link');
          for (var i = 0; i < links.length; i++) {
              var link = links[i];
              if (link.rel !== 'stylesheet') continue;
              var clonedLink = link.cloneNode(true);
              var newHref = link.href.replace(/(&|?)jbUpdateLinksId=d+/, "$1jbUpdateLinksId=" + messageId);
              if (newHref !== link.href) {
                clonedLink.href = newHref;
              }
              else {
                var indexOfQuest = newHref.indexOf('?');
                if (indexOfQuest >= 0) {
                  // to support ?foo#hash 
                  clonedLink.href = newHref.substring(0, indexOfQuest + 1) + 'jbUpdateLinksId=' + messageId + '&' + 
                                    newHref.substring(indexOfQuest + 1);
                }
                else {
                  clonedLink.href += '?' + 'jbUpdateLinksId=' + messageId;
                }
              }
              link.replaceWith(clonedLink);
          }
      }
  };
})();
</script>

Does anyone know where this script is coming from and how I can disable it? I’ve also tried disabling the debugger in both my browser and in PhpStorm.

I’ve searched high and low and I know it has something to do with “live edit”, but I cannot find any options to enable/disable it no matter where I look.

Scoping Tailwind CSS Classes Per Section in Modular PHP Projects

I need to implement some kind of class scoping in Tailwind CSS. Each section of my site is in a different .php file (for example, hero.php, about.php, etc.). What I want is for Tailwind to generate separate CSS files for each section – for example, hero.css and about.css. The styles should be scoped using data-css=”hero” and data-css=”about”. So, in hero.php, I would use something like <section data-css=”hero” …>, and it should only apply styles from the hero section. Using tailwind v4 cli.

CSS: [data-css="Hero_test_hero_sekce"]
PHP: <section data-css="Hero_test_hero_sekce" class="relative h-screen bg-cover bg-center bg-no-repeat flex items-center">

Indexnow does not recognise urlList

I am trying to implement Indexnow to one of my sites but when I run it I get the response:

{“code”:”InvalidRequestParameters”,”message”:”Invalid request”,”details”:[{“target”:”request.urlList”,”message”:”The urlList field is required.”}]}

This is my (shortened) code:

$urls = array();
if (date('Y-m-d', filemtime('../index.php')) = date('Y-m-d',now())) {array_push($urls,'https://'.$_SERVER['SERVER_NAME'].'/');}
if (date('Y-m-d', filemtime('../credits.php')) = $date('Y-m-d',now())) {array_push($urls,'https://'.$_SERVER['SERVER_NAME'].'/credits');}

$post = array(
    'host' => $_SERVER['SERVER_NAME'],
    'key' => 'key',
    'keylocation' => 'https://'.$_SERVER['SERVER_NAME'].'/key.txt',
    'urlList' => $urls
);

unset($urls);

$cp = curl_init('https://api.indexnow.org/indexnow');
curl_setopt ($cp, CURLOPT_HTTPHEADER, Array("application/json; charset=utf-8"));
curl_setopt($cp, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cp, CURLOPT_POST, 1);
curl_setopt($cp, CURLOPT_POSTFIELDS, json_encode($post, JSON_UNESCAPED_UNICODE));

// execute!
$cp_response = curl_exec($cp);

When I do “echo json_encode($post);” I get:

{"host":"www.host.dk","key":"key","keylocation":"https://www.host.dk/key.txt","urlList":["https://www.host.dk/","https://www.host.dk/credits"]}

So what am I missing? Why is it not seeing the urlList array?

php mail script not sending mail [duplicate]

When I use the script below, no message gets sent. The failure message also doesn’t appear. I just get a blank screen. If I remove the $_POST, everything works. I double-checked the name of the form element coming over from the other page, so there is no typo there. I also noticed that the message fails if I add a variable for the mail header (but I do get the failure message in the else statemnt for that one…)

Thanks in advance!

<?php
    $to = "[email protected]";
    $subject = "Test Email from PHP";
    $message = "This is a test email sent using the PHP mail() function. From: " 
    $from = $_POST['subAdd'];
    $message = $message . $from

    if (mail($to, $subject, $message)){
      header("Location: http://practice.bkjdesignspa.com");
    }
    else{
      echo "Message failed";
    }

?>

global scopes for get , all and paginate function in laravel

I write a trait in laravel named prioritiable and I add a global scope to the query to sort the query result based on priority value

The problem is the scope add the order by SQL clause to all SELECT, DELETE , UPDATE , INSERT
but I want to just to have the scope on select

so I did this

trait Prioritiable
{
    protected static function bootPrioritiable(): void
    {
        static::retrieved(function ($model) {
            $model->addGlobalScope(OrderByPriorityScope::class);
        });
    }

}

The problem solved for first, find , firstOrFail , findOrFail but the scope does not work for get , all , paginate, since I think these three functions do not fire the retrieved event

the A_I says use $builder->getQuery()->type == ‘select’ in the scope apply function but the type does not exists and throws error

or do something like this

    public function apply(Builder $builder, Model $model)
    {
        $query = $builder->getQuery();

        // Apply only for SELECT queries that aren't aggregates
        if ($query->columns !== null && $query->aggregate === null) {
            $builder->orderBy('priority');
        }
    }

which not work fine

PHP (NextCloud) events/listeners best practices

To give a bit on context, I am building an app in nextcloud and I am going to shoot & listen to a lot for events. I have got 2 options to tackle this problem.

1. Creating a lot of events & listeners;

For every single action within a service, I can shoot out an event which will have a listener attached. This means that I will get a lot of events and listeners within the system. Example;

$dispatcher->dispatchTyped(new reorderEvent());
$dispatcher->dispatchTyped(new assignEvent());

2. Creating 1 event for a model with actions;

I can also create just 1 event that will pass through just an action string/enum. This will reduce the amount of event files within the application. Example;

class ActionEnum: string 
{
    case REORDER;
    case ASSIGN;
}

$dispatcher->dispatchTyped(new updatedEvent(ActionEnum::REORDER));
$dispatcher->dispatchTyped(new updatedEvent(ActionEnum::ASSIGN));

Now the multi-million dollar question is, which would be considered best-practice in the long run? Or is there another solution that is even better to use?

Why is my XCLASSes action for the EXT:sf_event_mgt EventController ignored?

I’m trying to add a button that allows users to subscribe to my event calender via a webcall:// link. I use type=9819 to trigger the function.

I can‘t get my icalAction to work, it just gets ignored and typo3 uses the listAction from the extension instead.

Im using typo3 13.4 and sitepackage. I would like to manage the output in a fluid template

My folder structure is:

/packages
└── studilife
    ├── Classes
    │    └── Controller
    │        └── EventController.php
    ├── Configuration
    │   └── Sets
    │       └── Studilife
    │           └── TyposScript
    │               └── setup.typoscript
    ├── Resources
    │   └── Private
    │       └── Extensions
    │           └── SfEventMgt
    │               └── Templates
    │                   └── Event
    │                       └── Ical.html
    └── ext_localconf.php

This is my code so far:

ext_localconf.php:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][DERHANSENSfEventMgtControllerEventController::class] = [
    'className' => StudentStudilifeControllerEventController::class,
];

TYPO3CMSExtbaseUtilityExtensionUtility::configurePlugin(
    'SfEventMgt',
    'Event',
    [
        DERHANSENSfEventMgtControllerEventController::class => 'list,detail,register,ical'
    ],
    []
);

setup.typoscript:

plugin.tx_sfeventmgt {
    view {
        templateRootPaths {
            100 = EXT:studilife/Resources/Private/Extensions/SfEventMgt/Templates/
        }
        partialRootPaths {
            100 = EXT:studilife/Resources/Private/Extensions/SfEventMgt/Partials/
        }
        layoutRootPaths {
            100 = EXT:studilife/Resources/Private/Extensions/SfEventMgt/Layouts/
        }
    }
    settings {
        calendar{
            showWeekNumber = 0
        }
    }
}

pageEventICalendar = PAGE
pageEventICalendar {
    typeNum = 9819
    settings.format = txt
    config {
        disableAllHeaderCode = 1
        xhtml_cleaning = none
        admPanel = 0
        metaCharset = utf-8
        locale_all = en_EN
        additionalHeaders.10.header = Content-Type:text/calendar;charset=utf-8
        disablePrefixComment = 1
        linkVars >

    }

    10 = USER
    10 {
        userFunc = TYPO3CMSExtbaseCoreBootstrap->run
        extensionName = SfEventMgt
        pluginName = Event
        vendorName = DERHANSEN
        controller = Event
        action = ical
    }
}

eventController.php:

<?php
namespace StudentStudilifeController;

class EventController extends DERHANSENSfEventMgtControllerEventController
{
    public function icalAction()
    {
        $events = $this->eventRepository->findAll();
        $this->view->assign('events', $events);

        $this->view->setFormat('txt');
        header('Content-Type: text/calendar; charset=utf-8');
        header('Content-Disposition: attachment; filename="events.ics"');
    }
}

Im trying to get my Action to be recognized by typo3. The typoscript works fine so far, but the eventController.php is just ignored. Its my first time trying to change the behaviour of an extension, so i probably miss something very basic. I tryed to use this official typo3 documentation: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Xclasses/Index.html.

Thanks for your help

Showing dynamic or different menus on wordpress not working in my theme

On my WordPress page, there’s a primary menu that shows up at the header of all pages, but I want to show a different set of menus for pages in the route /tech-products.

Based on my research on this site, adding the following to my function.php and then setting up the menu in Appearance → Menus → Manage Locations is expected to work, but it doesn’t work.

function register_custom_menus() {
    register_nav_menus(array(
        'primary' => 'Primary Menu',
        'tech_products_menu' => 'Tech Products Menu',
    ));
}
add_action('init', 'register_custom_menus');