I can’t properly fetch the firstname and lastname from users table and title from the books table [closed]

PROBLEM HERE

The borrower’s name and title aren’t displaying as expected in my CodeIgniter 4 app. Despite trying various solutions, the issue persists. Could someone help troubleshoot and resolve it? Your assistance would be greatly appreciated.

public function getPendingTransactions($user_id = null)
{
    // Start the query builder
    $builder = $this->db->table('transactions')
        ->select([
            'transactions.transaction_id',
            'transactions.user_id',
            'transactions.book_id',
            'transactions.borrow_date',
            'transactions.due_date',
            'transactions.status',
            'users.firstname',
            'users.lastname',
            'books.title'
        ])
        ->join('users', 'users.user_id = transactions.user_id', 'left')  // Left join for users
        ->join('books', 'books.book_id = transactions.book_id', 'left')  // Left join for books
        ->where('transactions.status', 'pending');  // Filter by pending status

    // Add user filter if provided
    if ($user_id !== null) {
        $builder->where('transactions.user_id', $user_id);
    }

    // Debug: Log the compiled SQL query
    log_message('debug', 'SQL Query: ' . $builder->getCompiledSelect());

    // Fetch the transactions
    $transactions = $builder->get()->getResultArray();

    // Log the query result for debugging
    log_message('debug', 'Pending Transactions Query Result: ' . print_r($transactions, true));

    // Handle NULL values by setting defaults
    foreach ($transactions as &$transaction) {
        // Default to 'Unknown' for firstname, 'N/A' for title, and empty string for lastname
        $transaction['firstname'] = !empty($transaction['firstname']) ? $transaction['firstname'] : 'Unknown';
        $transaction['lastname'] = !empty($transaction['lastname']) ? $transaction['lastname'] : '';
        $transaction['title'] = !empty($transaction['title']) ? $transaction['title'] : 'N/A';
    }

    return $transactions;
}




public function showPendingTransactions($user_id = null)
{
    $pendingTransactions = $this->getPendingTransactions($user_id);

    if (empty($pendingTransactions)) {
        log_message('debug', 'No pending transactions found.');
    } else {
        log_message('debug', 'Pending Transactions: ' . print_r($pendingTransactions, true));
    }

    return view('admin/approve_reject_transactions', ['pendingTransactions' => $pendingTransactions]);
}



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Approve or Reject Transactions</title>
    <!-- Bootstrap CSS -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
    <!-- SweetAlert CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f7fc;
            margin: 0;
            padding: 0;
        }

        .container {
            width: 80%;
            margin: 20px auto;
            background-color: #fff;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }

        h2 {
            text-align: center;
            color: #333;
            margin-bottom: 20px;
        }

        .alert {
            padding: 15px;
            margin-bottom: 20px;
            background-color: #4CAF50;
            color: white;
            border-radius: 5px;
        }

        .table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }

        .table th, .table td {
            padding: 12px;
            text-align: left;
            border: 1px solid #ddd;
        }

        .table th {
            background-color: #007BFF;
            color: white;
        }

        .table tr:nth-child(even) {
            background-color: #f2f2f2;
        }

        .btn {
            padding: 8px 16px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 14px;
            cursor: pointer;
            border-radius: 4px;
        }

        .btn-success {
            background-color: #28a745;
            color: white;
            border: none;
        }

        .btn-danger {
            background-color: #dc3545;
            color: white;
            border: none;
        }

        .btn:hover {
            opacity: 0.8;
        }

        form input[type="date"] {
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }

        form button {
            margin-left: 10px;
        }

        .actions {
            display: flex;
            justify-content: space-around;
            align-items: center;
        }

        .actions form {
            margin-right: 10px;
        }
    </style>
</head>

<body>
    <!-- Include the Navbar -->
    <?= $this->include('layout/navbar'); ?>

    <div class="container mt-5">
        <h2>Pending Borrowed Books</h2>

        <?php if (session()->getFlashdata('message')): ?>
            <div class="alert"><?= session()->getFlashdata('message') ?></div>
        <?php endif; ?>

        


        <table class="table">
            <thead>
                <tr>
                    <th>Transaction ID</th>
                    <th>Borrower Name</th>
                    <th>Book Title</th>
                    <th>Borrowed Date</th>
                    <th>Due Date</th>
                    <th>Status</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
    <?php if (!empty($pendingTransactions)): ?>
        <?php foreach ($pendingTransactions as $transaction): ?>
            <tr>
                <td><?= ($transaction['transaction_id']) ?></td>
                            <td>
                <?= esc($transaction['firstname'] ?? 'Unknown') ?> 
                <?= esc($transaction['lastname'] ?? '') ?>
            </td>
            <td><?= esc($transaction['title'] ?? 'No Title') ?></td>
                <td><?= esc($transaction['borrow_date']) ?></td>
                <td>
                    <input type="date" value="<?= esc($transaction['due_date']) ?>" disabled>
                </td>
                <td><?= esc($transaction['status']) ?></td>
                <td class="actions">
                    <form action="<?= site_url('admin/approveTransaction/' . $transaction['transaction_id']) ?>" method="POST">
                        <input type="date" name="due_date" value="<?= esc($transaction['due_date']) ?>" required>
                        <button type="submit" class="btn btn-success">Approve</button>
                    </form>
                    <a href="<?= site_url('admin/rejectTransaction/' . $transaction['transaction_id']) ?>" class="btn btn-danger">Reject</a>
                </td>
            </tr>
        <?php endforeach; ?>
    <?php else: ?>
        <tr>
            <td colspan="7">No pending transactions.</td>
        </tr>
    <?php endif; ?>
</tbody>



        </table>
    </div>

    <!-- jQuery, Bootstrap JS, SweetAlert JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>

    <script>
        // Add SweetAlert for better user experience on approve/reject actions
        $('.btn-danger').on('click', function (e) {
            e.preventDefault();
            const href = $(this).attr('href');

            Swal.fire({
                title: 'Are you sure?',
                text: "Do you want to reject this transaction?",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#dc3545',
                cancelButtonColor: '#6c757d',
                confirmButtonText: 'Yes, reject it!'
            }).then((result) => {
                if (result.isConfirmed) {
                    window.location.href = href;
                }
            });
        });
    </script>
</body>

</html>

Symfony with Webpack and Stimulus loading all controllers on every page

I have an issue with the setup mentioned in the title. Project is using Symfony 7.1 with Webpack encore and stimulus. I have a combination of custom.js files for individual pages and stimulus controllers. Unfortunately, all stimulus controllers are bundled into app.js and loaded on every page. Even with the /* stimulusFetch: 'lazy' */ comment.

This is a horrible thing because I have quite a few custom controllers and they are meant for individual pages, not the whole site. This increases the bundle size for no reason and some controllers are not meant for public but registered/logged in users.

How can I change this behavior and only load the controller where I need it? The current bootstrap.js is as default from Symfony:

import { startStimulusApp } from "@symfony/stimulus-bridge";

// Registers Stimulus controllers from controllers.json and in the controllers/
export const app = startStimulusApp(
  require.context(
    "@symfony/stimulus-bridge/lazy-controller-loader!./controllers",
    true,
    /.[jt]sx?$/
  )
);

I tried loading bootstrap.js from another file than app.js but then none of the controllers load. I also tried not registering any controllers like so:

import { startStimulusApp } from "@symfony/stimulus-bridge";
const app = startStimulusApp();
export default app;

And then manually calling app.register('', ); in individual .js files, however it won’t load.

Please advise, much appreciated.

DataTables 2.0 in WordPress Plugin Admin Area

I would like to implement DataTables2 in my WordPress plugin. I started from test table to check if it works:

<?php
/*
Plugin Name: WooSKU Updater
Description: A plugin to manage SKUs, quantities, and prices using DataTables.
Version: 1.0
Author: Your Name
*/

function woosku_updater_enqueue_scripts() {
    // Enqueue jQuery first
    wp_enqueue_script('jquery', 'https://code.jquery.com/jquery-3.7.1.js', array(), null, true);

    // Enqueue DataTables after jQuery
    wp_enqueue_style('datatables-css', 'https://cdn.datatables.net/2.1.8/css/dataTables.dataTables.css');
    wp_enqueue_script('datatables-js', 'https://cdn.datatables.net/2.1.8/js/dataTables.js', array('jquery'), null, true);

    // Initialize DataTables
    wp_add_inline_script('datatables-js', '
        jQuery(document).ready(function($) {
            $("#woosku-table").DataTable();
        });
    ');
}
add_action('wp_enqueue_scripts', 'woosku_updater_enqueue_scripts');


// Add the WooSKU Updater admin menu
function woosku_updater_menu() {
    add_menu_page(
        'WooSKU Updater',      // Page title
        'SKU Updater',         // Menu title
        'manage_options',      // Required capability
        'woosku-updater',      // Menu slug
        'woosku_updater_page', // Function to display the admin page content
        'dashicons-update',    // Icon
        100                    // Position
    );
}
add_action('admin_menu', 'woosku_updater_menu');

// Callback function for the admin page content
function woosku_updater_page() {
    ?>
    <div class="wrap">
        <h1>WooSKU Updater</h1>
        <p>Manage your SKUs, quantities, and prices.</p>
        <table id="woosku-table" class="display" style="width:100%">
            <thead>
                <tr>
                    <th>SKU</th>
                    <th>QTY</th>
                    <th>PRICE</th>
                </tr>
            </thead>
            <tbody>

                <tr><td>SKU001</td><td>10</td><td>£15.00</td></tr>
                <tr><td>SKU002</td><td>5</td><td>£25.50</td></tr>
                <tr><td>SKU003</td><td>8</td><td>£12.75</td></tr>
                <tr><td>SKU004</td><td>20</td><td>£8.99</td></tr>
                <tr><td>SKU005</td><td>15</td><td>£10.50</td></tr>

            </tbody>
        </table>
    </div>
    <?php
}

It creates example table, but it doesn’t load all Datatables files. The error I have is

load-scripts.php?c=1&load%5Bchunk_0%5D=wp-hooks,jquery-core,jquery-migrate,utils&ver=6.7:4

   POST https://example.com.com/wp-admin/admin-ajax.php net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK)

And the code connected to this error:

<script type='text/javascript'>
                (function($) {

                    //(Re)starts the background worker thread
                    function blcDoWork() {
                        $.post("https://example.com.com/wp-admin/admin-ajax.php", {
                            'action': 'blc_work',
                            '_ajax_nonce': 'a5213e0ea6'
                        });
                    }

                    //Call it the first time
                    blcDoWork();

                    //Then call it periodically every X seconds
                    setInterval(blcDoWork, 421000);

                }
                )(jQuery);
            </script>

Any thoughts? Thank you.

How to Reverse the Billing and Shipping Functionality in “Ship to a different address?” in WooCommerce Checkout?

I want to modify the WooCommerce checkout process and reverse the behavior of the “Ship to a different address?” checkbox. Here’s how it currently works in the classic checkout:

When the checkbox is checked:
The shipping form becomes visible, allowing the customer to fill in shipping details.
When the checkbox is unchecked:
The shipping form is hidden, and the customer’s shipping address is automatically set to match the billing address.

**What I want to achieve is the exact opposite:
**
Change the text of the checkbox to “Different billing address?”.
When the checkbox is checked:
The billing form should become visible, allowing the customer to fill in billing details.
When the checkbox is unchecked:
The billing form should be hidden, and the customer’s billing address should automatically be set to match the shipping address.


If reversing this functionality is too complicated, do you think it would be better to create a new checkbox field on the checkout page to handle these conditions, or should I continue down the path of modifying the existing functionality?

Notes:
In the new block-based checkout, this functionality already works as intended.
However, I need to achieve this specifically in the classic checkout.
Any advice or alternative solutions would be greatly appreciated!

I inspected the core checkout.min.js file and found the relevant function:

javascript
Kodu kopyala
update_checkout_action: function (t)
// Core WooCommerce functionality
}
I believe I can achieve this by modifying this function, but I’m wondering if there’s a better or more standard way to implement this change. Surely, with WooCommerce being around for so long, there must be a cleaner solution.

how can I create Task and Event for a lead using Vtiger API

I use Vtiger Api to create a new lead. Now I need to create new Task or new Event for my lead.

who can help me? and has an example

this is my code:

{
    "operation":"create",
    "format":"json",
    "sessionName":"221747465d9f2d70a76e9",
    "elementType":"Leads",
    "element": {
        "firstname":"test",
        "lastname":"test", //mandatory
        "email":"[email protected]", 
        "phone":"123456789", 
        "country":"Oman", 
        "website":"https://test.com/", 
        //list of mandatory fields is unique to your crm
        "assigned_user_id":"19x97" // this is parameter from authorisation response    
    }  
}

I don’t have any idea…

How to fix unusual problem in php, mysql? [duplicate]

I use a simple code for login to my website. After entering the username and password, I get this error:

ERROR:

408 Request Timeout in PHP MYSQL
Server timeout waiting for the HTTP request from the client.

Apache Server at otagh… Port 80

Note:
this error occurs only for one username&password
Other users login the site without problems

the output of database is correct for this username and password, and an error occurs only for this query in PHP.

the PHP script is executed correctly for all users, but a timeout error occurs only for the same

this is my php code:
$user = 'sys_user';
$pass = '1234';
if ($user && $pass) {     
    $sql = "SELECT * FROM users where user='$user'&& pass='$pass'";     
    $result = $mysqli->query($sql);     
    if ($result->num_rows > 0) {

How to solve Dompdf mb_internal_encoding

I am trying to generate a pdf using dompdf which works well on local server (XAMPP) But when i go live (CPANEL) i get this error **Fatal

error: Uncaught Error: Call to undefined function Dompdfmb_internal_encoding() in /home/calbrema/public_html/dompdf/vendor/dompdf/dompdf/src/Dompdf.php on line 295
( ! ) Error: Call to undefined function Dompdfmb_internal_encoding() in /home/calbrema/public_html/dompdf/vendor/dompdf/dompdf/src/Dompdf.php on line 295**. Here is whats on line 295

$this->mbstringEncoding = mb_internal_encoding();
        mb_internal_encoding('UTF-8'); 

I am using Php 8.3 on shared Cpanel hosting. I checked under php extensions and mbstring is ticked.

How do i solve this please help

I tried adding this extension=php_mbstring.dll in php.ini as stated in one of the forums here which doesn’t seem to working at all.

How to insert multiple selects into separate rows

Having read several posts on this subject, I have managed to insert data from a multiple select form.
However, the data goes into one row. I need each value to go into separate rows.
Here is the relevant field in the form

<p>
    <label>Assign Users::</label>
    <select id="client" name="client[]"  multiple="multiple">
        <option  class="multiple" value="selected">Assign User to Project</option>
        <?php 
            foreach($clients as $client){ 
        ?>
        <option value="<?php echo $client ->user_id;?>"><?php echo $client ->user_name; ?></option>
        <?php 
        }
        ?>
    </select>
</p>

And here is the Insert code

$ref=$_POST['project_ref'] ;
$user_id=implode(',', $_POST['user']);
$wpdb->insert( 'vo_wp_assigned_projects', array('client'=>$user_id,'project'=> $ref));

This inserts into one row, which is no use as I need to be able to access each individual entry.
I have tried foreach loops from other posts in this group with no success.
I hope I have provided sufficient information.

Alphanumeric String Comparison In PHP [duplicate]

I am unable to understand how does PHP compare an alphanumeric string.

php > var_dump("222" < "30");
bool(false)

php > var_dump("222a" < "30");
bool(true)

The first comparison makes sense, but what’s happening in the second one ? how is it comparing last two digits from 222a with 30 ?

Thank You.

php equivalent of bytes (str,’latin-1′) in python

the context is :

signed_str = hmac.new(bytes(secret_key, 'latin-1'),
                  msg=bytes(prepared_str, 'latin-1'),
                  digestmod=hashlib.sha256).hexdigest().lower()

I manage to get this segment of code work nicely but the php I tried is not even close

<php

$signed_str = strtolower( base64_encode (hash_hmac('sha256',$prepared_str , $secretKey) ) )  ;

Generally, i understand the whole thing but not the exact details to convert it to php.
And when we are at it, it would be perfect if hexdigest has a php equivalent.

public function getProfiles($account_id)

OK I have a system that generates subscriptions from customers related to

  1. Service,.
  2. Account (email) belonging to that service.
  3. Profile related to the account.
    All this is associated to a client, but to be able to see it at the time of the subscription all this keeps relation to the authenticated user.

The problem I have it when obtaining the profiles.

In my Accounts table I have a field called sale_type that can have only 2 options:
‘complete’ and ‘profile’

I have functions to get the accounts associated to a service_id, so I can get the profiles associated to an account_id.

When an account has sale_type = ‘complete’; its associated profiles are linked through the account_id which in turn has a user_id (account holder) in the accounts table.

But when an account has sale_type = ‘profile”; its profiles are associated to the user through a field called user_id in the profiles table.

In this way; if an account is sale_type = ‘complete and you want to make a subscription, you will get all the profiles associated to that account, while if an account is sale_type = ‘profile’ you will get only the profiles belonging to that account in which the user_id (from the profiles table) is the authenticated user.

profiles table

In the following image I can select the Service, I can select a mail (mabeliñ[email protected]) with the condition sale_type = ‘complete’, and then I can see the profiles it has.

subscription view

But when I choose an account with the condition sale_type = ‘profile’, it does not show me the profiles that the account has on behalf of the authenticated user.

subscripton view

I have the function below that shows me the profiles in the accounts sale_type= ‘complete’ but does not show the profiles in the accounts sale_type= ‘profile’.

public function getProfiles($account_id){
        $data = [];

        // Obtener la cuenta con el id de cuenta dado
        $account = Account::find($account_id);

        // Comprobar si la cuenta existe
        if ($account) {
            $attr = [
                'table' => 'profiles',
                'columns' => [
                    'id',
                    'name',
                    'pin',
                    'user_id' // Agregar user_id para obtener este campo también
                ],
                'compare' => 'account_id',
                'compare_value' => $account_id
            ];
            $response = Helper::getDataSelect($attr);

            // Verificar el sale_type de la cuenta
            if ($account->sale_type == 'complete') {
                // Si sale_type es 'complete', mostrar todos los perfiles
                $data = $response;
            } else if ($account->sale_type == 'profile') {
                // Si sale_type es 'profile', mostrar solo los perfiles para el usuario actual
                if (count($response) > 0){
                    foreach ($response as $res){
                        $profile = Profile::find($res->id);

                        if ($profile && $profile->subscriptions->count() == 0) {
                            if ($profile->user_id == Auth::user()->id) {
                                array_push($data, $res);
                            } 
                        }
                    }
                }
            }
        }

        return response()->json(['data' => $data]);
    }

I have tried changing the function to this:

public function getProfiles($account_id){
    $data = [];
    $attr = [
        'table'=>'profiles',
        'columns'=>[
            'id',
            'name',
            'pin'
        ],
        'compare'=>'account_id',
        'compare_value'=>$account_id
    ];
    $response = Helper::getDataSelect($attr);
    if(count($response) > 0){
        foreach($response as $res){
            $profile = Profile::find($res->id);
            if($profile->subscriptions->count() == 0){

                if($profile->user_id == Auth::user()->id){
                    array_push($data, $res);
                }
            }
        }
    }

    return response()->json(['data'=>$data]);
}

This way it lets me see the profiles of the account sale_type= ‘profile’ but it does not let me see the profiles of the accounts sale_type=’complete’ 🙁

I can see the profiles that belong to me

and for the ‘full’ account I don’t see the profiles

I need help, to allow me to show the profiles depending on the sale_type, because currently if I use one method I can see the sale_type=’complete’ and the others not. and if I change the function I can see the accounts sale_type=’profile’ and the others not 🙁

esta es mi funcion en el Helper:

public static function getDataSelect($attr, $validateUser=false){
            if($attr){
                if($validateUser){
                    $data = DB::table($attr['table'])->select($attr['columns'])->where($attr['compare'],$attr['compare_value'])->where('user_id',Auth::user()->id)->get();
                }else{
                    $data = DB::table($attr['table'])->select($attr['columns'])->where($attr['compare'],$attr['compare_value'])->get();
                }

                return $data;
            }else{
                return null;
            }

        }

When I run exec command in php script , it is not giving any output but return value is 0

When I run an exec command in my php script, it is not giving any output but return value is 0

Background : I am trying to implement AS2 communication functionality using AS2Secure PHP code. When I am trying to send message to partner after signing and encrypting. But at the time of encrypting , it is not encrypting , we are sending only signed message.

Here is the exec command function:

openssl smime  -encrypt -in "C:\Users\Maggy\AppData\Local\Temp\as2A5B3.tmp" -out "C:\Users\Maggy\AppData\Local\Temp\as2B18B.tmp" -des3 "D:\as2secure_code_build-0.9.0\partners\maggy\clientcertificate.pem"

I ran the the same command in the command line and it is successfully giving output.

Here is the PHP code:

    public static function exec($command, $return_output = false){
        $output = array();
        $return_var = 0;
        try{

    AS2Log::info(false, 'This is AS2Adapter File and IN EXEC FUNCTION CALLED'.$command);
    // AS2Log::info(false, 'INPUT DATA as FOLLOWS'.file_get_contents($input));
            exec($command , $output, $return_var);
    //          proc_open($command , $output, $return_var);
    //            passthru ("$command , 2>&1");
    AS2Log::info(false, 'This is AS2Adapter File and IN EXEC FUNCTION EXECUTED and Result will             
    be ~~~~~~~~~~~~~~~~~~~~~');


    AS2Log::info(false, 'This is AS2Adapter File and IN EXEC FUNCTION COMPLETED                         
    SUCCESSFULLY'.$output[0]);

    $line = (isset($output[0])?$output[0]:'Unexpected error in command line : ' . $command);
            if ($return_var) throw new Exception($line, (int)$return_var);
        }
        catch(Exception $e){
            throw $e;
        }
        
    AS2Log::info(false, 'This is RETURN OUTPUT LOOKS LIKE : '.file_get_contents($output));

    AS2Log::info(false, 'This is RETURN VAR LOOKS LIKE : '.file_get_contents($return_var));

    if ($return_output){
        return $output;
    AS2Log::info(false, 'This is AS2Adapter File and FINAL OUTPUT LOOKS LIKE : '.$output);

    }
    else
        return $return_var;
    }

Can you please help me resolve this issue?

I have tried shell_exec and it is giving the same result.

I have tried the passthru command but it didn’t give any result.

I am trying to do the signed and encrypted the message but it is only signing the message, not encrypting.

Prevent a specific plugin custom field to update when I update a post – WordPress

I am using a specific plugin to count my post views.

It store in a postmeta custom field named “hits” the value and this value is updated in real time.

I just noticed that when, as an admin, I edit a post, the “hits” value does not increase while I am editing the post.

When I think about it seems logic because if “hits” value is 15 when I enter in a post edition, it will still be 15 when I finish my post edition because all postmeta are updated when I update a post. SO, even if 10 more people have visit my post my post counter still display a value of 15 when it should display 25.

So now I am trying very hard with my low PHP skill to prevent this field to be updated while I update my posts.

I tried different method but none of them worked :

  1. I tried to prevent this metadate to be updated before saving my post with the following code :
function exclude_hits_from_update($null, $object_id, $meta_key, $meta_value) {
        if ('hits' === $meta_key) {
            return true; 
        }
            return $null;
    }
    add_filter('pre_update_post_meta', 'exclude_hits_from_update', 10, 4);
  1. I also tried this code in order to try to get the value of the metadate just before updating the post but it did not work either (it seems that this just create more custom field named “hits”) :
function prevent_hits_field_update( $post_id, $post, $update ) {

    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
        return;
    }
    if ( isset($_POST['hits']) ) {
        $current_hits = get_post_meta($post_id, 'hits', true);
        update_post_meta($post_id, 'hits', $current_hits);
    }
}
add_action('save_post', 'prevent_hits_field_update', 10, 3);
  1. I also tried to modify directly the save_post function in the plugin itself (by commenting the line “update_post_meta” but I know it is not enough :
public function adminSave( $post_id )
    {
        // skip for autosave
        if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
        {
            return;
        }

        // update hits count
        if( isset($_POST['post_type']) && in_array( $_POST['post_type'], array( 'post', 'page' ) ) )
        {    
            $hits = ( isset($_POST['hits']) && !empty($_POST['hits']) ? intval( preg_replace( '/[^0-9]/', '', $_POST['hits'] ) ) : 0 );
            
            if( $hits > 0 )
            {
                $hits_exists = get_post_meta( $post_id, 'hits', true );
                
                if( $hits_exists===false )
                {
                    add_post_meta( $post_id, 'hits', $hits, true );
                }
                else
                {
                    /*update_post_meta( $post_id, 'hits', $hits );*/ /* HERE */
                }
            }
        }
    
        // clear Popular Posts Widget
        $ahc_ppw = new AJAX_Hits_Counter_Popular_Posts_Widget();
        $ahc_ppw->clearCache();
        
        return true;
    }

Can anyone help me with this ? Unfortunately I can not change the plugin yet because it is linked to several blocks on my website and he use some efficient cache methods.

Thanks in advance for any help !
Jonathan

Custom sorting of reviews in Elementor

I am trying to set up custom filtering of the reviews widget in Elementor. Basically what ‘d like to do is add a new ACF field for product model, and then have my loop carousel template populate with the relevant reviews (e.g. reviews with that product tag) on pages dynamically. How would I go about doing this?

I’ve added a new field but can’t figure out how to get around manually adding/inserting all of these reviews depending on the page.

here’s the code i’ve tried so dar:

add_action('elementor/query/custom_review_filter', function($query) {
    if (is_page() && get_field('product_model')) {
        $product_model = get_field('product_model');
        $query->set('meta_key', 'product_model');
        $query->set('meta_value', $product_model);
    }
});

How to get only keys from a nested array in php?

{
    "numberOfResults": 1,
"items": [
    {
        "asin": "B089SMNFZJ",
        "attributes": {
            "model_name": [
                {
                    "language_tag": "en_US",
                    "value": "Arko",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "age_range_description": [
                {
                    "language_tag": "en_US",
                    "value": "Adult",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "bullet_point": [
                {
                    "language_tag": "en_US",
                    "value": "After washing with hand soap, use Arko Nem Cream give dry hands the soothing care they deserve",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Intensive Cream",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Fast absorbing",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Delivers lng lasting moisture",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "scent": [
                {
                    "language_tag": "en_US",
                    "value": "Classic",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "material_type_free": [
                {
                    "language_tag": "en_US",
                    "value": "Alcohol Free",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_dimensions": [
                {
                    "width": {
                        "unit": "centimeters",
                        "value": 10.0
                    },
                    "length": {
                        "unit": "centimeters",
                        "value": 15.0
                    },
                    "height": {
                        "unit": "centimeters",
                        "value": 10.0
                    },
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "product_description": [
                {
                    "language_tag": "en_US",
                    "value": "<br>Arko Nem<br><br>Shine like your skin!<br>Protects and vivifies your skin.<br><br>Arko Nem Classic Oily Cream<br>&nbsp;<br>This efficient moisturizer that contains the clean and nostalgic scent of classic Arko creams, is a guaranteed solution to the dryness that your skin experience in the cold of winter, wind of spring and the glowing days of the summer. Despite it has an oil-based formula, Arko Nem Classic easily absorbs and provides a comfortable use.&nbsp;<br>It has been dermatologically tested and can be used safely on children's skin.&nbsp;<br>During the day, weather changes and various other external factors cause your body the lose its natural moisture balance.&nbsp;<br><br>It moisturizes without leaving a greasy feeling on your skin and allows it to reach the natural moisture balance.<br>Its effect lasts 24 hours and meets your skin’s moisture needs all day.&nbsp;<br>300ml, 100ml, 20cc<br>With 3 sizes of 20cc, 100ml and 300ml, you can easily put Arko cream in your bag, take it to your travels and share it with your loved ones at home.<br><br>RECCOMENDATIONS FOR USE<br><br>Massage to your hands and face and apply all areas that need moisture until the cream is absorbed.&nbsp;<br>Massage and let your skin absorb the cream until it disappears.<br>Arko Nem Classic moisturizing cream is with you everywhere!&nbsp;<br>It provides your skin's natural moisture balance and does not leave a greasy feeling.&nbsp;<br><br>DISCOVER THE ARKO NEM SERIES!<br><br>SOFT TOUCH<br>GLYCERIN<br>CLASSIC<br>PEARL ESSENCES<br>OLIVE OIL&nbsp;<br><br>250ml&amp;60ml Features, benefits, areas of usage<br><br>For normal and combination skins<br>With its formula that absorbs quickly and does not leave a greasy feeling, it gives moisture to your skin.<br><br>For severe dry skins<br>It traps moisture in your hands and provides an ideal moisture balance for severe dry hands.<br><br>For dry skins",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "brand": [
                {
                    "language_tag": "en_US",
                    "value": "Arko",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "unspsc_code": [
                {
                    "value": "53130000",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_display_weight": [
                {
                    "unit": "grams",
                    "value": 200.0,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "externally_assigned_product_identifier": [
                {
                    "value": "091952669056",
                    "type": "upc",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "value": "0091952669056",
                    "type": "ean",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_form": [
                {
                    "language_tag": "en_US",
                    "value": "Cream",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_type_keyword": [
                {
                    "value": "facial-moisturizers",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "number_of_items": [
                {
                    "value": 5,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_package_dimensions": [
                {
                    "length": {
                        "unit": "centimeters",
                        "value": 3.302
                    },
                    "width": {
                        "unit": "centimeters",
                        "value": 10.16
                    },
                    "height": {
                        "unit": "centimeters",
                        "value": 11.938
                    },
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "recommended_uses_for_product": [
                {
                    "language_tag": "en_US",
                    "value": "Soothing",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "size": [
                {
                    "language_tag": "en_US",
                    "value": "Pack of 5",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "part_number": [
                {
                    "value": "504785",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "target_gender": [
                {
                    "value": "unisex",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "variation_theme": [
                {
                    "name": "SIZE_NAME/SCENT_NAME",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "contains_liquid_contents": [
                {
                    "value": true,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_package_weight": [
                {
                    "unit": "kilograms",
                    "value": 0.136,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_volume": [
                {
                    "unit": "milliliters",
                    "value": 300.0,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "skin_type": [
                {
                    "language_tag": "en_US",
                    "value": "Oily,Dry",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "manufacturer": [
                {
                    "language_tag": "en_US",
                    "value": "Evyap",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "target_use_body_part": [
                {
                    "value": "hands",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "model_number": [
                {
                    "value": "504785",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "supplier_declared_dg_hz_regulation": [
                {
                    "value": "not_applicable",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "material_feature": [
                {
                    "language_tag": "en_US",
                    "value": "Natural",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "item_name": [
                {
                    "language_tag": "en_US",
                    "value": "Arko Classic Oily Cream 20cc (5 Pack)",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "list_price": [
                {
                    "currency": "USD",
                    "value": 0.0,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "batteries_required": [
                {
                    "value": false,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "product_site_launch_date": [
                {
                    "value": "2020-06-16T07:23:07.142Z",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "target_audience_keyword": [
                {
                    "language_tag": "en_US",
                    "value": "Unisex Adult",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Men",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Adults",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "People",
                    "marketplace_id": "ATVPDKIKX0DER"
                },
                {
                    "language_tag": "en_US",
                    "value": "Teens",
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ],
            "unit_count": [
                {
                    "type": {
                        "language_tag": "en_US",
                        "value": "Count"
                    },
                    "value": 6.0,
                    "marketplace_id": "ATVPDKIKX0DER"
                }
            ]
        },
        "dimensions": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "item": {
                    "height": {
                        "unit": "inches",
                        "value": 3.93700787
                    },
                    "length": {
                        "unit": "inches",
                        "value": 5.905511805
                    },
                    "width": {
                        "unit": "inches",
                        "value": 3.93700787
                    }
                },
                "package": {
                    "height": {
                        "unit": "inches",
                        "value": 1.299999998674
                    },
                    "length": {
                        "unit": "inches",
                        "value": 4.699999995206
                    },
                    "weight": {
                        "unit": "pounds",
                        "value": 0.29982867632
                    },
                    "width": {
                        "unit": "inches",
                        "value": 3.99999999592
                    }
                }
            }
        ],
        "identifiers": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "identifiers": [
                    {
                        "identifierType": "EAN",
                        "identifier": "0091952669056"
                    },
                    {
                        "identifierType": "UPC",
                        "identifier": "091952669056"
                    }
                ]
            }
        ],
        "images": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "images": [
                    {
                        "variant": "MAIN",
                        "link": "https://m.media-amazon.com/images/I/71OWUn6w2HL.jpg",
                        "height": 1500,
                        "width": 1500
                    },
                    {
                        "variant": "MAIN",
                        "link": "https://m.media-amazon.com/images/I/51vBolkWZkL.jpg",
                        "height": 500,
                        "width": 500
                    },
                    {
                        "variant": "MAIN",
                        "link": "https://m.media-amazon.com/images/I/51vBolkWZkL._SL75_.jpg",
                        "height": 75,
                        "width": 75
                    },
                    {
                        "variant": "PT01",
                        "link": "https://m.media-amazon.com/images/I/31G-MWnA8sL.jpg",
                        "height": 432,
                        "width": 391
                    },
                    {
                        "variant": "PT01",
                        "link": "https://m.media-amazon.com/images/I/31G-MWnA8sL._SL75_.jpg",
                        "height": 75,
                        "width": 68
                    },
                    {
                        "variant": "PT02",
                        "link": "https://m.media-amazon.com/images/I/41fE9c5y2ML.jpg",
                        "height": 479,
                        "width": 494
                    },
                    {
                        "variant": "PT02",
                        "link": "https://m.media-amazon.com/images/I/41fE9c5y2ML._SL75_.jpg",
                        "height": 73,
                        "width": 75
                    },
                    {
                        "variant": "PT03",
                        "link": "https://m.media-amazon.com/images/I/31o+SLhcIpL.jpg",
                        "height": 286,
                        "width": 302
                    },
                    {
                        "variant": "PT03",
                        "link": "https://m.media-amazon.com/images/I/31o+SLhcIpL._SL75_.jpg",
                        "height": 71,
                        "width": 75
                    },
                    {
                        "variant": "PT04",
                        "link": "https://m.media-amazon.com/images/I/31VNiSOl3SL.jpg",
                        "height": 292,
                        "width": 311
                    },
                    {
                        "variant": "PT04",
                        "link": "https://m.media-amazon.com/images/I/31VNiSOl3SL._SL75_.jpg",
                        "height": 70,
                        "width": 75
                    }
                ]
            }
        ],
        "relationships": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "relationships": []
            }
        ],
        "salesRanks": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "classificationRanks": [
                    {
                        "classificationId": "16479981011",
                        "title": "Face Moisturizers",
                        "link": "https://www.amazon.com/gp/bestsellers/beauty/16479981011",
                        "rank": 4613
                    }
                ],
                "displayGroupRanks": [
                    {
                        "websiteDisplayGroup": "beauty_display_on_website",
                        "title": "Beauty & Personal Care",
                        "link": "https://www.amazon.com/gp/bestsellers/beauty",
                        "rank": 227725
                    }
                ]
            }
        ],
        "summaries": [
            {
                "marketplaceId": "ATVPDKIKX0DER",
                "adultProduct": false,
                "autographed": false,
                "brand": "Arko",
                "browseClassification": {
                    "displayName": "Face Moisturizers",
                    "classificationId": "16479981011"
                },
                "itemClassification": "BASE_PRODUCT",
                "itemName": "Arko Classic Oily Cream 20cc (5 Pack)",
                "manufacturer": "Evyap",
                "memorabilia": false,
                "modelNumber": "504785",
                "partNumber": "504785",
                "size": "Pack of 5",
                "tradeInEligible": false,
                "websiteDisplayGroup": "beauty_display_on_website",
                "websiteDisplayGroupName": "Beauty"
            }
        ]
    }
]
}

I get JSON data for ASINs from Amazon using the SP API, as above.

This data is;

$data = json_decode($DATA_SEC_TXT_1, true);

The sample output is as follows.

Array
(
[0] => Array
    (
        [asin] => B089SMNFZJ
        [attributes] => Array
            (
                [model_name] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Arko
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [age_range_description] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Adult
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [bullet_point] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => After washing with hand soap, use Arko Nem Cream give dry hands the soothing care they deserve
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                        [1] => Array
                            (
                                [language_tag] => en_US
                                [value] => Intensive Cream
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                        [2] => Array
                            (
                                [language_tag] => en_US
                                [value] => Fast absorbing
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                        [3] => Array
                            (
                                [language_tag] => en_US
                                [value] => Delivers lng lasting moisture
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [scent] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Classic
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [material_type_free] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Alcohol Free
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [item_dimensions] => Array
                    (
                        [0] => Array
                            (
                                [width] => Array
                                    (
                                        [unit] => centimeters
                                        [value] => 10
                                    )

                                [length] => Array
                                    (
                                        [unit] => centimeters
                                        [value] => 15
                                    )

                                [height] => Array
                                    (
                                        [unit] => centimeters
                                        [value] => 10
                                    )

                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [product_description] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Arko Nem
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [brand] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Arko
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [unspsc_code] => Array
                    (
                        [0] => Array
                            (
                                [value] => 53130000
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )
                [supplier_declared_dg_hz_regulation] => Array
                    (
                        [0] => Array
                            (
                                [value] => not_applicable
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [material_feature] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Natural
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [item_name] => Array
                    (
                        [0] => Array
                            (
                                [language_tag] => en_US
                                [value] => Arko Classic Oily Cream 20cc (5 Pack)
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                [list_price] => Array
                    (
                        [0] => Array
                            (
                                [currency] => USD
                                [value] => 0
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )

                                    [product_site_launch_date] => Array
                    (
                        [0] => Array
                            (
                                [value] => 2020-06-16T07:23:07.142Z
                                [marketplace_id] => ATVPDKIKX0DER
                            )

                    )
        [summaries] => Array
            (
                [0] => Array
                    (
                        [marketplaceId] => ATVPDKIKX0DER
                        [adultProduct] => 
                        [autographed] => 
                        [brand] => Arko
                        [browseClassification] => Array
                            (
                                [displayName] => Face Moisturizers
                                [classificationId] => 16479981011
                            )

                        [itemClassification] => BASE_PRODUCT
                        [itemName] => Arko Classic Oily Cream 20cc (5 Pack)
                        [manufacturer] => Evyap
                        [memorabilia] => 
                        [modelNumber] => 504785
                        [partNumber] => 504785
                        [size] => Pack of 5
                        [tradeInEligible] => 
                        [websiteDisplayGroup] => beauty_display_on_website
                        [websiteDisplayGroupName] => Beauty
                    )

            )

    )

)

I can easily process this php data with the code;

print_r ($data["items"]);

What I want to do is to get the keys of nested arrays in PHP codes.

The output I want to get should be like this.

What I want to do is to get the keys of nested arrays in PHP codes.

So every;

[0] => Array

I want to go over the previous keys.

The output I want to get is;

[asin] => B089SMNFZJ
[attributes] => Array
(
[0] => model_name
[1] => age_range_description
[0] => bullet_point
...
...

How can I do this?