How i can fix hackers exploit prestashop 1.6 module

A hacker can exploit my module made by a freelancer, i’m trying to fix the module…

I’m trying to fix the module with the code without escaping sql injection the code like that:

If i use pSQL function or bqSQL function, their is not escaping value for sql injection.

Their is the code of insecure statement

$sql = 'SELECT * FROM `'._DB_PREFIX_.'module_name` where active = 1 and id_customer = '.bqSQL($id_customer). ' and id_shop = '.$id_shop;

$rows = Db::getInstance()->executeS($sql);

if(!empty($rows)){

    $row1 = array();
        $sql1 = 'SELECT * FROM `'._DB_PREFIX_.'module_name` where active = 1 and number = "'.bqSQL($rows[0]['number']).'"';
    $row1 = Db::getInstance()->executeS($sql1);
}

If i insert this text into my module input accessible by client:
jud3v”;INSERT INTO sqlmapoutput (data) VALUES (‘jud3v_digital’);#
The field jud3v_digital will be created on my DB.

Hacker query:
enter image description here

Their is the sql statement made by hacker:

        477145 Query    SELECT * FROM `ps_magcatreserve_numbers` where number = "941020";INSERT INTO ps_cart_rule ( active, code, description, date_from, date_to, date_add, date_upd, reduction_percent, reduction_currency, reduction_tax, reduction_product, quantity, quantity_per_user, minimum_amount, minimum_amount_currency, minimum_amount_tax, minimum_amount_shipping, free_shipping, highlight, partial_use, priority, shop_restriction, carrier_restriction, cart_rule_restriction, country_restriction, group_restriction, product_restriction, id_customer ) VALUES ( 1, 0x50524f4d4f3939, 0x50726f6d6f74696f6e206465202d3939252073616e73207265737472696374696f6e, NOW(), DATE_ADD(NOW(), INTERVAL 1 YEAR), NOW(), NOW(), 99.00, 1, 1, 0, 1000000, 1000000, 0.00, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 )#" and id_customer =
        477145 Query    SELECT * FROM `ps_magcatreserve` where active = 1 and number = "941020";INSERT INTO ps_cart_rule ( active, code, description, date_from, date_to, date_add, date_upd, reduction_percent, reduction_currency, reduction_tax, reduction_product, quantity, quantity_per_user, minimum_amount, minimum_amount_currency, minimum_amount_tax, minimum_amount_shipping, free_shipping, highlight, partial_use, priority, shop_restriction, carrier_restriction, cart_rule_restriction, country_restriction, group_restriction, product_restriction, id_customer ) VALUES ( 1, 0x50524f4d4f3939, 0x50726f6d6f74696f6e206465202d3939252073616e73207265737472696374696f6e, NOW(), DATE_ADD(NOW(), INTERVAL 1 YEAR), NOW(), NOW(), 99.00, 1, 1, 0, 1000000, 1000000, 0.00, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 )#"

Hacker can update customer matching email address, reset password, access admin panel, delete my whole website (thing done last night with + 170 multi shop), made free order, drop database;

i have now for this time:

  • restrict mysql credentials grants (removed DROP grant)
  • remove destructive php function

I’m trying to fix the code, but with my test i cannot made a anti sql injection statement, how i can perform this ?

I’m using php 7.1 with presta 1.6.1.24, i have tested too with mysqli prepare statement that do nothing

How to improve page load speed when rendering dynamic tables from database in PHP + jQuery AJAX?

I am currently using this code

<script type="text/javascript">
    function LoadChallanTable() {
        var companyID = $('#cbCompanyName').val();
        if (companyID !== '' && companyID !== null) {
            $.ajax({
                type: 'POST',
                url: 'LoadChallanTable.php',
                data: {companyID: companyID},
                success: function (data)
                {
                    if (data !== '') {
                        var allProductList = jQuery.parseJSON(data);

                        var tableQuery = '<table id="tblChallanProduct" class="tableHead"><tr><td class="tableCell" style="display:none;">Product ID</td><td class="tableCell">Product Name</td><td class="tableCell">Purchase Quantity</td><td class="tableCell">Free Quantity</td><td class="tableCell">Purchase Amount</td><td class="tableCell">Register DP</td><td class="tableCell">Purchase DP</td><td class="tableCell"></td></tr>';
                        for (var i = 0; i < allProductList.length; i++) {
                            if (i % 2 === 0) {
                                tableQuery = tableQuery + '<tr class="tableRow"><td style="display:none;"><input id="prodID' + (i + 1) + '" name="prodID' + (i + 1) + '" value="' + allProductList[i]['productID'] + '"></td><td class="tableCell">' + allProductList[i]['productName'] + '</td><td class="tableCell"><input type="text" class="tableCell" id="purQty' + (i + 1) + '" name="purQty' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="freQty' + (i + 1) + '" name="freQty' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="purAmt' + (i + 1) + '" name="purAmt' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell" id="pRegDP' + (i + 1) + '" name="pRegDP' + (i + 1) + '">' + parseFloat(allProductList[i]['dP']).toFixed(3) + ' Tk</td><td class="tableCell"><input type="text" readonly="true" class="inputPTable" id="pPurDP' + (i + 1) + '" name="pPurDP' + (i + 1) + '" style="text-align:Right;" size="6" value="0.000 Tk"></td><td class="tableCell" id="errMsg' + (i + 1) + '"></td></tr>';
                            } else {
                                tableQuery = tableQuery + '<tr class="tableRowOdd"><td style="display:none;"><input id="prodID' + (i + 1) + '" name="prodID' + (i + 1) + '" value="' + allProductList[i]['productID'] + '"></td><td class="tableCell">' + allProductList[i]['productName'] + '</td><td class="tableCell"><input type="text" class="tableCell" id="purQty' + (i + 1) + '" name="purQty' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="freQty' + (i + 1) + '" name="freQty' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="purAmt' + (i + 1) + '" name="purAmt' + (i + 1) + '" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell" id="pRegDP' + (i + 1) + '" name="pRegDP' + (i + 1) + '">' + parseFloat(allProductList[i]['dP']).toFixed(3) + ' Tk</td><td class="tableCell"><input type="text" readonly="true" class="inputPTableOdd" id="pPurDP' + (i + 1) + '" name="pPurDP' + (i + 1) + '" style="text-align:Right;" size="5" value="0.000 Tk"></td><td class="tableCell" id="errMsg' + (i + 1) + '"></td></tr>';
                            }
                        }

                        $('#tblChallanProduct').html(tableQuery + '</table>');
                    } else {
                        $('#tblChallanProduct').html(data);
                        alert('No record found.');
                    }
                },
                error: function () {
                    alert('Error occurred.');
                }
            });
        }
    }
</script>

where LoadChallanTable.php is

$allProductList = $productManager->LoadProduct($companyID);

if (count($allProductList) > 0) {
    echo json_encode($allProductList);
} else {
    echo '';
}

where LoadChallanTable.php creates a list of invoices and sends it as json_encoded and I am making an ajax call to my UI, taking the data from that json, creating a table using javascript and assigning it to the html of the tblChallanProduct table. Which improved much page load speed.

Instead of previous one was

<script type="text/javascript">
    function LoadChallanTable() {
        var companyID = $('#cbCompanyName').val();
        if (companyID !== '' && companyID !== null) {
            $.ajax({
                type: 'POST',
                url: 'LoadChallanTable.php',
                data: {companyID: companyID},
                success: function (data)
                {
                    $('#tblChallanProduct').html(data);
                    if (data === '') {
                        alert('No record found.');
                    }
                },
                error: function () {
                    alert('Error occurred.');
                }
            });
        }
    }
</script>

where LoadChallanTable.php is

$allProductList = $productManager->LoadProduct($companyID);

if (count($allProductList) > 0) {
    $tableQuery = "<table id="tblChallanProduct" class="tableHead"><tr><td class="tableCell" style="display:none;">Product ID</td><td class="tableCell">Product Name</td><td class="tableCell">Purchase Quantity</td><td class="tableCell">Free Quantity</td><td class="tableCell">Purchase Amount</td><td class="tableCell">Register DP</td><td class="tableCell">Purchase DP</td><td class="tableCell"></td></tr>";
    for ($i = 0; $i < count($allProductList); $i++) {
        if ($i % 2 == 0) {
            $tableQuery = $tableQuery . "<tr class="tableRow"><td style="display:none;"><input id="prodID" . ($i + 1) . "" name="prodID" . ($i + 1) . "" value="" . $allProductList[$i]->productID . ""></td><td class="tableCell">" . $allProductList[$i]->productName . "</td><td class="tableCell"><input type="text" class="tableCell" id="purQty" . ($i + 1) . "" name="purQty" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="freQty" . ($i + 1) . "" name="freQty" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="purAmt" . ($i + 1) . "" name="purAmt" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell" id="pRegDP" . ($i + 1) . "" name="pRegDP" . ($i + 1) . "">" . number_format((float) $allProductList[$i]->dP, 3, ".", "") . " Tk</td><td class="tableCell"><input type="text" readonly="true" class="inputPTable" id="pPurDP" . ($i + 1) . "" name="pPurDP" . ($i + 1) . "" style="text-align:Right;" size="5" value="0.000 Tk"></td><td class="tableCell" id="errMsg" . ($i + 1) . ""></td></tr>";
        } else {
            $tableQuery = $tableQuery . "<tr class="tableRowOdd"><td style="display:none;"><input id="prodID" . ($i + 1) . "" name="prodID" . ($i + 1) . "" value="" . $allProductList[$i]->productID . ""></td><td class="tableCell">" . $allProductList[$i]->productName . "</td><td class="tableCell"><input type="text" class="tableCell" id="purQty" . ($i + 1) . "" name="purQty" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="freQty" . ($i + 1) . "" name="freQty" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell"><input type="text" class="tableCell" id="purAmt" . ($i + 1) . "" name="purAmt" . ($i + 1) . "" value="0" style="text-align:Right;" onkeyup="KeyUpEvent(this, event)" onfocus="OnFocusFunction(this)"></td><td class="tableCell" id="pRegDP" . ($i + 1) . "" name="pRegDP" . ($i + 1) . "">" . number_format((float) $allProductList[$i]->dP, 3, ".", "") . " Tk</td><td class="tableCell"><input type="text" readonly="true" class="inputPTableOdd" id="pPurDP" . ($i + 1) . "" name="pPurDP" . ($i + 1) . "" style="text-align:Right;" size="5" value="0.000 Tk"></td><td class="tableCell" id="errMsg" . ($i + 1) . ""></td></tr>";
        }
    }
    echo $tableQuery . "</table>";
} else {
    echo '';
}

where LoadChallanTable.php creates a list of invoices and sends it as a string and I am making an ajax call to read the string and assigning it directly to the html of the tblChallanProduct table.
If you have any other methods that can improve page load speed further, please let me know. I will appreciate it.

How to move dump() from the screen to the dev toolbar? [closed]

I’m trying to display the output of dump() in the dev toolbar. This was working in Dockware 6.6, however this doesn’t seem to work anymore in Dockware 6.7.

Currently all output of dump() is shown directly on the screen. I have no idea if this was intentional or simply some tiny little detail is not set correctly on my system.

I’m pretty sure I haven’t messed with any settings regarding this as I have set-up a second instance inside a completely different environment and I’m experiencing the same issue.

In the profiler debug is empty: “no content was dumped“. I’m not sure if it’s relevant, but I’m trying to dump in my plugin’s subscriber on an event.

the red marked menu entry is missing in 6.7

Parse error: syntax error, unexpected string content “”, expecting “-” or identifier or variable or number

I have a website, to test the login functionality, I made a testing.php file. Here is the code:

<?php
if (!isset($_POST["password"])) {
    $form = "<html><head><title>testing</title></head><body><form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post"><input type="password" name="password"></form></body></html>";
    echo($form);
} else {
    if ($_POST["password"] === "TestersAndDevs0nly") {
        session_start();
        $_SESSION["logged"] = true;
    }
}
?>

but when I execute it i get this error:
Parse error: syntax error, unexpected string content “”, expecting “-” or identifier or variable or number

I tried putting in it a variable, but it returned the error still.

Where is first view file in Symfony?

I am new in Symfony and I start to create basic MVC project. When I create project and run it I see welcome page. In laravel this file is in views/welcome.blade.php. In symfony where is this file.

Use placeholders and $wpdb->prepare(); found $sql

I create my custom plugin and test in plugin check plugin but it give me error like
Use placeholders and $wpdb->prepare(); found $sql

// Execute

$sql = "SELECT {$found_rows} p.ID AS course_id, X.*,IF(X.status = %s AND uim.meta_value IS NOT NULL, uim.meta_value, X.status) AS status FROM ( SELECT ui.* FROM `{$stepup_lms_user_items}` ui  LEFT JOIN `{$stepup_lms_user_items}` uix    ON ui.item_id = uix.item_id AND ui.user_id = uix.user_id    AND ui.user_item_id < uix.user_item_id  WHERE uix.user_item_id IS NULL) X {$join}   {$where}    {$limit}";

        // Only the dynamic value goes through prepare
        $rows = $db->wpdb->get_results(
                $wpdb->prepare( $sql, 'finished' )
        );

Also I write query inside $wpdb->prepare(); then it give another error like

Use placeholders and $wpdb->prepare(); found interpolated variable {$found_rows} at "SELECT {$found_rows} p.ID AS course_id, X.*,IF(X.status = %s AND uim.meta_value IS NOT NULL, uim.meta_value, X.status) AS status FROM (tSELECT ui.*tFROM {$stepup_lms_user_items} uitLEFT JOIN {$stepup_lms_user_items} uixtON ui.item_id = uix.item_idtAND ui.user_id = uix.user_idtAND ui.user_item_id < uix.user_item_idtWHERE uix.user_item_id IS NULL) X {$join}t{$where}t{$limit}"

But It is not solve.

Please help me

Thanks in advance.

I try bellow links

I refer wordpress document https://make.wordpress.org/core/2022/10/31/postponed-to-wp-6-2-escaping-table-and-field-names-with-wpdbprepare/

also view other resource https://github.com/WordPress/WordPress-Coding-Standards/issues/2442

I want to resolve my ERROR and warning in Plugin Check plugin.

How to get array_splice from upper to lower?

When I run the following code, I’m receiving this output:

PHP
PHP What
PHP What is
PHP What is PHP

However I want to receive the following output:

PHP What is PHP
PHP What is
PHP What
PHP

What thing needs to change to extract values from Upper to Lower

<?php
// Horje.Com
$stringSentence = 'PHP What is PHP';
$stringSentence = preg_replace('/s+/', ' ', $stringSentence);
$buffer = '';
$count = 1;
$length = strlen($stringSentence);
for ($i = 0; $i < $length; $i++) {
    if ($stringSentence[$i] !== ' ') {
       $buffer .= $stringSentence[$i];
    } else {
        //echo ' '.$count++.' '.$buffer.'&lt;/br&gt;';
        $pieces = explode(" ", $stringSentence);
        $first_part = implode(" ", array_splice($pieces, 0, $count++));
        echo ''.$first_part.'</br>';
        $buffer = '';
    }
}

$pieces = explode(" ", $stringSentence);
$first_part = implode(" ", array_splice($pieces, 0, $count++));

echo ''.$first_part.'';

I keep getting “Failed to open stream: Permission denied” and changing permissions on the folder does not work

I am switching from Windows to Linux (Fedora), and I keep getting this error in my Laravel project that I did not have on Windows:

enter image description here

It’s apparently related to permissions, but running these commands doesn’t fix the issue:

sudo chmod -R 777 /var/www
sudo chmod -R 777 storage/
sudo chown -R apache:apache /var/www/
sudo chmod -R 777 /var/www/html/cursos/victor-robles/master-fullstack/api-rest-laravel/storage/framework/views/

I have checked if permissions have been set properly with ls -la and this is what I get:

api-rest-laravel folder:

drwxr-xr-x. 1 apache apache    402 Sep 18 10:51 .
drwxrwxrwx. 1 apache apache     56 Sep 18 02:02 ..
drwxr-xr-x. 1 apache apache     52 Aug 18 22:33 app
-rwxrwxrwx. 1 apache apache    425 Apr 15 08:24 artisan
drwxr-xr-x. 1 apache apache     50 Aug 18 22:33 bootstrap
-rwxrwxrwx. 1 apache apache   2462 Aug 18 23:27 composer.json
-rwxrwxrwx. 1 apache apache 299734 May  1 13:24 composer.lock
drwxr-xr-x. 1 apache apache    204 Aug 18 22:33 config
drwxr-xr-x. 1 apache apache    102 Aug 18 22:33 database
drwxr-xr-x. 1 apache apache     24 Aug 18 22:33 docs
-rwxrwxrwx. 1 apache apache    258 Apr 15 08:24 .editorconfig
-rwxrwxrwx. 1 apache apache   1139 Sep 18 02:20 .env
-rwxrwxrwx. 1 apache apache   1084 Apr 15 08:24 .env.example
-rwxrwxrwx. 1 apache apache    186 Apr 15 08:24 .gitattributes
-rwxrwxrwx. 1 apache apache    286 Apr 15 08:24 .gitignore
-rwxrwxrwx. 1 apache apache    354 Apr 15 08:24 package.json
-rwxrwxrwx. 1 apache apache   1173 Apr 15 08:24 phpunit.xml
drwxr-xr-x. 1 apache apache     78 Aug 18 22:33 public
-rwxrwxrwx. 1 apache apache   3932 Apr 15 08:24 README.md
drwxr-xr-x. 1 apache apache     20 Aug 18 22:33 resources
drwxr-xr-x. 1 apache apache     36 Aug 18 22:33 routes
drwxr-xr-x. 1 apache apache     32 Aug 18 22:33 storage
drwxr-xr-x. 1 apache apache     46 Aug 18 22:33 tests
drwxr-xr-x. 1 apache apache    596 Aug 18 22:34 vendor
-rwxrwxrwx. 1 apache apache    331 Apr 15 08:24 vite.config.js

api-rest-laravel/storage

drwxr-xr-x. 1 apache apache  32 Aug 18 22:33 .
drwxr-xr-x. 1 apache apache 402 Sep 18 10:51 ..
drwxr-xr-x. 1 apache apache  68 Aug 18 22:33 app
drwxr-xr-x. 1 apache apache  70 Aug 18 22:33 framework
drwxr-xr-x. 1 apache apache  42 Aug 18 22:33 logs

api-rest-laravel/storage/framework

drwxr-xr-x. 1 apache apache   70 Aug 18 22:33 .
drwxr-xr-x. 1 apache apache   32 Aug 18 22:33 ..
drwxr-xr-x. 1 apache apache   28 Aug 18 22:33 cache
-rwxrwxrwx. 1 apache apache  119 Apr 15 08:24 .gitignore
drwxr-xr-x. 1 apache apache   20 Aug 18 22:33 sessions
drwxr-xr-x. 1 apache apache   20 Aug 18 22:33 testing
drwxrwxrwx. 1 apache apache 4052 Sep 18 02:24 views

I have also tried restarting apache with sudo systemctl restart httpd several times but nothing works.

Please, any ideas?

prevent PHP from using ellipses (…) in the paths of INCLUDE statements in error messages

I have a .php page that generates a Fatal error:

...
#2 [path1]/header.php(22): include('/Library/WebSer...') 
#3 [path2]/index.php(4): include('/Library/WebSer...')
...

(where I’ve substituted [path#] for the path to files in the traceback) and in both, the file being included is truncated and presented as "/Library/WebSer..." with ellipses instead of the full path and most importantly, without the file_name.

Based on PHP – Stop displaying full path in errors, I take it that once upon a time PHP did not do this, i.e., when reporting an error, it gave the full path, including the file_name, but maybe I’m misunderstanding this 11 year old question and answer.

I’ve looked through all of the php.ini directives at https://www.php.net/manual/en/ini.list.php, and don’t see one that addresses what I want, i.e., I want the full path, including file_name, displayed instead of a truncated path with ellipses at the end like “include(‘/Library/WebSer…’)”.

Is there way to force display of the full path in the “include()”?

Thank you.

Datediff subtract time between two times (non working hours)

I am using datediff to work out how many hours and minutes it takes to go from one department (timestamped) to another department (timestamped).

If a department starts the task but doesn’t complete it that working day, but finishes the following day, the data is ‘incorrect’ as it has added non-working hours (overnight) to it.

This is being displayed through the DataTables plugin.

Please, can I get advice on creating a SQL Statement that ignores or subtracts the non-working hours?

Or maybe there is a better way around this?

Current PHP Code:

<table id="example" class="SizeTable" border="1" width="100%">
<thead>
<tr>
<th style="font-size: 1rem">PON</th>
<th style="font-size: 1rem">Total Doors</th> 
<th style="font-size: 1rem">Fold<br>Complete</th> 
<th style="font-size: 1rem">Folding Time<br>H:M</th> 
<th style="font-size: 1rem">Weld<br>Complete</th>
<th style="font-size: 1rem">Welding Time<br>H:M</th> 
<th style="font-size: 1rem">Painted<br>Complete</th>
<th style="font-size: 1rem">Painting Time<br>H:M</th> 
<th style="font-size: 1rem">Assembly<br>Complete</th>  
<th style="font-size: 1rem">Ordered<br>Date</th>
<th style="font-size: 1rem">Lead<br>Time</th>
<th style="font-size: 1rem">Due<br>Date</th> 
</tr>
</thead>
<tbody>
<?php
    include('connection.php');
    $select_query = mysqli_query($connection,"SELECT PON, dateOn, dueDate, foldedStart, weldedStart, paintedStart, assemblyStart, DATEDIFF(dueDate,dateOn) AS days, (
    requiredDoors +
    requiredDoors2 +
    requiredDoors3 +
    requiredDoors4 +
    requiredDoors5 +
    requiredDoors6 +
    requiredDoors7 +
    requiredDoors8 +
    requiredDoors9 +
    requiredDoors10 +
    requiredDoors11 +
    requiredDoors12 +
    requiredDoors13 +
    requiredDoors14 +
    requiredDoors15 +
    requiredDoors16 +
    requiredDoors17 +
    requiredDoors18 +
    requiredDoors19 +
    requiredDoors20 
    ) AS total FROM WIP2 WHERE status = '12'
    OR DATEPART(WEEKDAY,foldedStart) NOT IN (7, 1)
    AND assemblyStart NOT LIKE '%red%' 
    AND assemblyStart NOT LIKE '%InProgress%' 
    AND paintedStart NOT LIKE '%red%' 
    AND paintedStart NOT LIKE '%InProgress%' 
    AND weldedStart NOT LIKE '%red%' 
    AND weldedStart NOT LIKE '%InProgress%' 
    AND foldedStart NOT LIKE '%red%' 
    AND foldedStart NOT LIKE '%InProgress%' 
    ORDER BY dueDate desc");
    while($data = mysqli_fetch_array($select_query)){
?>
<?php
  $fold = date_create($data["foldedStart"]);
  $weld = date_create($data["weldedStart"]);
  $paint = date_create($data["paintedStart"]);
  $assembly = date_create($data["assemblyStart"]);  
  $interval1 = date_diff($fold, $weld);
  $interval2 = date_diff($weld, $paint);
  $interval3 = date_diff($paint, $assembly);
?>
<tr>
<td><?php echo $data['PON']; ?></td>
<td><?php echo $data['total']; ?></td>  
  
<td><?php echo $data['foldedStart']; ?></td>
<td><?php echo $interval1->format('%H:%I'); ?></td>
<td><?php echo $data['weldedStart']; ?></td>
<td><?php echo $interval2->format('%H:%I'); ?></td>
<td><?php echo $data['paintedStart']; ?></td>
<td><?php echo $interval3->format('%H:%I'); ?></td>
<td><?php echo $data['assemblyStart']; ?></td>
<td><?php echo $data['dateOn']; ?></td>
<td><?php echo $data['days']; ?></td>
<td><?php echo $data['dueDate']; ?></td>
</tr>   
<?php } ?>
</tbody>
</table>

Screenshot

MariaDB / PDO / PHP 1020 error (“Record has changed since last read in table”)

How do I correctly deal with 1020 errors within a transaction in MariaDB?

I recently encounter 1020 “Record has changed since last read in table” errors on code that run without this error for 20 years. It is hard to believe that the “record has changed since last read in table” because the failing SQL query is only for records used by one user (visitor):

DELETE FROM vbshoppingcart where visitor_id = :visitor_id AND businessunitID = :businessunitID

Anyway, when this error occurs I try to catch it and run the query again, because it actually should be a temporary failure:

$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
$this->dbh->beginTransaction();

// other queries within the same transaction will precede the query in question

$retry_attempts = 3;
$retry_wait_microseconds = 100000; // 100ms

while ($retry_attempts > 0) {
  $this->stmt = $this->dbh->prepare($this->query);
  $this->bindparams();
        
  try {

    $returnvalue = $this->stmt->execute();
    $this->clearBindvalues();

    return $returnvalue;
            
  } catch (PDOException $e) {
    $error_code = $e->getCode();
    $error_message = $e->getMessage();

    if ($error_code === 'HY000' && strpos($error_message, '1020') !== false) {
      // Retry in case of 1020
      error_log("Retry because of error 1020 – remaining: $retry_attempts.");

      usleep($retry_wait_microseconds);
      $retry_attempts--;
      continue;
    }

    // If no possibility that the query can be successfully executed clear the bind values in order to have the object ready for additional DB queries

    $this->clearBindvalues();
        
  }
            
  throw new Exception('PDO error occurred. Could not perform desired database interaction.');
        
}

// other queries within the same transaction will follow the query in question

try {

  // At the end the transaction will be committed:
  $result = $this->dbh->commit();

} catch (PDOException $e) {

  error_log("Commit failed: " . $e->getMessage());
  $this->dbh->rollBack();

  throw new Exception("Transaction commit failed: " . $e->getMessage());
}

I run this in a transaction (as shown in the code) with other queries before and after the query that sometimes causes trouble. If a 1020 error is thrown, always the first retry will already be executed successfully and the script goes on. At the end, the transaction will appear to be successfully committed (according to the logs), but in reality the entries will not be written to MariaDB.

How to prevent exposing real data in AJAX response (SSR vs CSR) and instead return opaque tokens?

I’m comparing two ways of rendering HTML structures with data from PHP + MySQL.

Option 1: SSR (Server-Side Rendering)

PHP builds the HTML and returns it directly:

PHP:


else if(isset($_POST["retrieveData"])){

  $sql = "SELECT * FROM sampleTable";

  $result = $conn->query($sql);

  $data = '';

  while($row = $result->fetch_assoc()){

    $data .= '<div class="Sample">';

    $data .= '<p class="ticket-id">'.$row["ticket"].'</p>';

    $data .= '<p class="email">'.$row["email"].'</p>';

    $data .= '</div>';

  }

  echo $data;

}

JS:

$.ajax({

  method: "POST",

  url: "PostData.php",

  data: { retrieveData: true },

  success: function(response){

    $('.container').append(response);

  }

});

Option 2: CSR (Client-Side Rendering)

PHP only returns JSON, and JS builds the HTML:

PHP:

else if(isset($_POST["retrieveData"])){

  $sql = "SELECT * FROM sampleTable";

  $result = $conn->query($sql);

  $rows = [];

  while($row = $result->fetch_assoc()){

    $rows[] = [

      "ticket" => $row["ticket"],

      "email"  => $row["email"]

    ];

  }

  echo json_encode($rows);

}

JS:

$.ajax({

  method: "POST",

  url: "PostData.php",

  data: { retrieveData: true },

  success: function(response){

    let a = JSON.parse(response);

    for(let i=0;i<a.length;i++){

      let b=a[i];

      let html=`

      <div class="Sample">

        <p class="ticket-id">${b.ticket}</p>

        <p class="email">${b.email}</p>

      </div>`;

      $('.container').append(html);

    }

  }

});

The problem

Both options expose the real data in the AJAX response. For example, if a user opens DevTools and adds console.log(response) inside my JS file:

Option 1 (SSR) response will log raw HTML with IDs and emails.

Option 2 (CSR) response will log JSON with the same IDs and emails.

So sensitive values (like ticket IDs or emails) are directly visible in the client.

What I want

Instead of returning the actual data directly in the AJAX response, I’d like to return only opaque/random alphanumeric tokens (e.g. 3f9aX2kP…).

Later, when the client needs to use those tokens, the server should be able to resolve them back to the real data.

My questions:

  1. Is it possible for a user to modify my JavaScript in Chrome DevTools and see raw AJAX responses? (I assume yes, but want confirmation.)

  2. What’s the standard way to return tokens instead of real data in AJAX responses, while still making the real data retrievable later?

Should I generate random strings and map them server-side (DB/session)?

Or use signed tokens (like HMAC/JWT) so the server can verify them without storing mappings?

How do I prevent replay or tampering?

Resolve PHP Notice Function _load_textdomain_just_in_time

I have an old abandoned plugin that I still use and so I cant have the developer to update it. I am receiving 1000s of PHP notices a day in my debug log with the _load_textdomain_just_in_time error.

This is the notice:

PHP Notice: Function _load_textdomain_just_in_time was called
incorrectly. Translation loading for the visitor-maps domain was
triggered too early. This is usually an indicator for some code in the
plugin or theme running too early. Translations should be loaded at
the init action or later. Please see Debugging in WordPress for more
information. (This message was added in version 6.7.0.)

In my attempts to try and correct the code – I have researched fixes where it shows the ‘wrong’ code and then the ‘correct code’ but the examples I have seen – none are worded the exact same as what I have, and so I am unsure and hesitant – for example see this link: Notice: Function _load_textdomain_just_in_time was called incorrectly

I believe I have found the code lines in the plugin that is causing the error in my abandoned plugin:

----
function visitor_maps_init() {

 if (function_exists('load_plugin_textdomain')) {
      load_plugin_textdomain('visitor-maps', false, 'visitor-maps/languages' );
 }
 ----

Could anyone advise how I could adjust the above code so that it resolves the php notice?

How to handle queued jobs failing silently when using Redis with Laravel 10 Horizon?

I’m working on a Laravel 10 project that uses Redis as the queue driver with Horizon. I’ve noticed that sometimes my queued jobs don’t execute, and nothing shows up in the failed_jobs table either.

  • Horizon dashboard shows the job was processed.

  • No exceptions are being logged.

  • The job logic isn’t running whatsoever (no db updates, no logs).

Things I tried:

  • Forcing queued jobs with php artisan queue:retry

  • Checking supervisor logs (no problems to speak of)

  • Check Redis running fine