Laravel stancl/tenancy: Tenant migrations not running (separate tenant DBs, migrations in database/migrations/tenant)

I am running tenant new migrations (orders/order_items) that live in database/migrations/tenant across multiple tenants. Each tenant has its own database (tenant_1, tenant_2, tenant_3, …) and there are some tables already. The central/system database is separate.

What happens when i run migrations using
php artisan tenants:migrate --force, tenant_1 migrates successfully.For tenant_2, tenant_3, etc., the command says “Nothing to migrate.
The new tables (orders, order_items) are not created in those tenant DBs. And new migrations are on migration/tenant folder

i have tried to checked config/tenancy.php includes the tenant migration path:

'migration_parameters' => [
        '--force' => true, // This needs to be true to run migrations in production.
        '--path' => [database_path('migrations/tenant')],
        '--realpath' => true,
    ],

when i run php artisan tenants:list it show perfectly real total of tenants

I am using laravel 12 and stancl/tenancy: ^3.8

how to simulate transactional behavior (rollback) for file system operations in php

Since PHP’s file system functions like rename(), copy() & … are not transactional, there’s no built-in rollback mechanism. I’m working on a PHP project where I need to perform multiple file system operations in sequence. The challenge is that if one operation fails, I want to rollback the previous ones to maintain consistency, similar to how database transactions work (especially when there are more than two operations involved, managing consistency becomes even more challenging. If one step fails, I need a way to undo all previous changes to avoid leaving the system in a partial or broken state). I’m looking for a reliable strategy to simulate transactional behavior for such operations.

Note : For simplicity, input validation, path sanitization, and security checks & … are omitted in this example.

<?php

$oldname = $_SESSION['oldname'];
$newname = $_POST['newname'];

$oldFile = './' . $oldname . '/' . $oldname . '.php';
$newFile = './' . $oldname . '/' . $newname . '.php';

$oldDir = './' . $oldname;
$newDir = './' . $newname;

if (file_exists($oldFile) && rename($oldFile, $newFile)) {
    if (file_exists($oldDir) && rename($oldDir, $newDir)) {
        //if (...) {

        try {
            $conn->beginTransaction();

            $update1 = $conn->prepare("UPDATE table1 SET name=? WHERE name=?");
            $update1->execute([$newname, $oldname]);

            $update2 = $conn->prepare("UPDATE table2 SET name=? WHERE name=?");
            $update2->execute([$newname, $oldname]);

            //...

            if ($update1->rowCount() > 0 && $update2->rowCount() > 0) {/* if ($update1->rowCount() > 0 && $update2->rowCount() > 0 && ...) { */

                $conn->commit();
                echo 'changed !';
            } else {

                $conn->rollBack();
                echo 'didnt change !';
            }
        } catch (PDOException $e) {

            $conn->rollBack();
            echo 'didnt change !';
        }
        //}
    } else {
        echo 'didnt change !';
    }
} else {
    echo 'didnt change !';
}
async function changename() {
    const newname = encodeURIComponent(document.getElementById('username').value);
    const formData = 'newname=' + newname;
    try {
        const response = await fetch('../script.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: formData
        });
        if (!response.ok) {
            throw new Error();
        }
        const responseText = await response.text();
        //...
    } catch (error) {
        msg('unfortunately, something went wrong !');
    }
}
document.getElementById("changename").addEventListener("click", changename);

Thanks in advance for any insights or suggestions !

Panther can’t connect to a port with fsockopen

I have a need for end to end testing, when i launch a test that imply to open a page, the same problem come back each time : fsockopen(): Unable to connect to 127.0.0.1:9080 (No connection could be made because the target computer actively refused it)
Or another same port.

I use wamp, and vhost, where i have a symphony app. I’ve tried to change navigator – chrome – and firefox, i have checked the versions if they were compatible, i’ve also made sure it wasn’t the chromedriver or geckodriver that had problems. And of course reinstalled multiple times.

Also, not just fsockopen, the terminal shows : Error output: ‘.’

I’m open to any idea, i’m really stuck.

enter image description here

-> Reinstalled
-> Change browser as chrome with panther is known to have several problems
-> Checked and made sure every version where compatible (chrome, with the chromedriver, firefox with geckodriver)

Apache reverse proxy for Metabase Docker container with Laravel app on same VM — /metabase shows Laravel 404 [closed]

I’m trying to run Metabase in Docker on a GCP VM that already hosts a Laravel application served by Apache. I want:

Laravel app accessible on / (e.g., http:///)

Metabase accessible on /metabase (e.g., http:///metabase)

Docker port 3000 not exposed publicly (only via Apache proxy)

What I’ve done

Docker container is running Metabase locally:

sudo docker run -d -p 3000:3000 
    -e MB_SITE_URL="http://127.0.0.1/metabase" 
    --name metabase metabase/metabase

Verified with:

sudo docker ps
curl http://127.0.0.1:3000

→ HTML output from Metabase appears.

Apache reverse proxy configuration (/etc/apache2/sites-available/metabase.conf):

<VirtualHost *:80>
    ServerAdmin [email protected]

    ProxyPreserveHost On
    ProxyRequests Off

    ProxyPass /metabase http://127.0.0.1:3000/
    ProxyPassReverse /metabase http://127.0.0.1:3000/

    ErrorLog ${APACHE_LOG_DIR}/metabase_error.log
    CustomLog ${APACHE_LOG_DIR}/metabase_access.log combined
</VirtualHost>

Enabled modules and site:

     sudo a2enmod proxy
    sudo a2enmod proxy_http
    sudo a2ensite metabase.conf
    sudo systemctl reload apache2

Laravel site config (000-default.conf) remains unchanged:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/public

    <Directory /var/www/html/public>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

What I see

    curl http://127.0.0.1/metabase → Metabase HTML works ✅

   Browser http://<VM-IP>/ → Laravel login works ✅

  Browser http://<VM-IP>/metabase → Laravel 404 page ❌

I do not want Metabase to be exposed directly on port 3000

Question

Why is Apache serving the Laravel 404 page instead of proxying /metabase to Docker, even though Docker is running and curl works locally?

How can I configure Apache so that:

Laravel app stays on /

Metabase is served securely on /metabase

Docker port 3000 remains internal

I am trying to move from PHP 7.4 to 8, but I got a fatal error message [closed]

Dear stackoverfolow community,

I have received this error code:

Fatal error: Declaration of DatabaseConnection::query($query, array $args = [], $options = []) must be compatible with PDO::query(string $query, ?int $fetchMode = null, mixed …$fetchModeArgs): PDOStatement|false in /usr/www/users/immobitt/drupal7/includes/database/database.inc on line 579

For very specific reasons, which I don’t want to specify here, I would like to stay with Drupal 7. To achieve a PHP upgrade, which also applies to the newer version 8.4, I would only need to correct the error I posted above.

My questions

  • can I publish the relevant file where the changes need to be made (database.inc) here, or send it to anybodody of you guys?

  • If the error (as can be seen) refers to line 579, does that mean that a change would only need to be made there?

  • To get rid of the error, could it be possible to replace “DatabaseConnection::query” with DatabaseConnection::runQuery ?

I apologize that I do not yet have the knowledge to explain it better – I have been trying to publish the code of the relevant file – but not possible –

I would greatly appreciate your support and help.

Best regards to the Stack Overflow community and thank you for your understanding.

Journal Type entry using one column per session user – PHP Mysql [closed]

I am not sure if this is a possible method, so I am looking for advice.

I would like to create a journal where a user adds an entry that has a javascript date stamp, followed by the entry into a MySQL table:

Date1:
Journal information1...
<br><hr><br>

As the user adds another entry (the same format as above), the information follows on from the last entry in the table (not creating a new row in the table)

I want the previous entry to be hidden, so it doesn’t look like a continuous list to the user:

**/HIDDEN/**
<br>Date1:<br>
Journal information1...
<br>**/HIDDEN/**
<hr>

<br>Date2:<br>
Journal information2...
<br><hr><br>

I want to do something like:

<form action="" method="post">
<textarea name="journal">
<span style="visibility: hidden;"><?=htmlspecialchars($journal)?>(previous entry)</span>
<span id="date"></span>
(space for new entry)
<hr>
</textarea>
</form>

<script>
var date = new Date();
var year = date.getFullYear();
document.getElementById('date').innerHTML = date;
</script>

Dragging the old entry into the input textarea, and allowing the user to add more.

I am sure there is a better way to process this, but I couldn’t find anything like it online.

Your time is appreciated!

Is it possible to use the “/” route for a controller in Laravel with Inertia?

What I want to set up in .routesweb.php is something like

Route::resource('/main', CallController::class);

So, if user goes to www.sitename.com/, the index of CallController should be executed and displayed. However, if I try to compile that with npx vite build, I am invariably met with an error of such type:

Expected identifier but found ":"
216 |   * @route '/{}'
217 |   */
218 |  export const show = (args: { : string | number } | [param: string | number ] | string | number, options?: RouteQueryOptions): RouteDefinition<'get'> => ({
    |                               ^
219 |      url: show.url(args, options),
220 |      method: 'get',

The error only seems to go away, if some other path other that / is being assigned to as the path for the CallController‘s index.

The only workaround that I have found is to set the resource route as /calls and redirect from it from `/’:

Route::get('/', function () {
        return redirect('/main');
    })->name('home');

But I wonder, whether it is the intended behaviour and if it is possible to use / as a route for a resource/controller?

Why are my Laravel validation errors not showing in the Blade view? [closed]

I made a form in Laravel and added validation rules in the store() method.
The validation works because when I submit invalid data, the page refreshes and the form doesn’t submit — but I don’t see any error messages on the page.

Here’s part of my form in Blade:

<form action="{{ route('register') }}" method="POST">
    @csrf
    <input type="text" name="name" placeholder="Name">
    <button type="submit">Register</button>
</form>

And the validation inside my request file:

public function rules()
{
    return [
        'name' => 'required|min:3',
    ];
}

I tried using @error('name') inside my form, but it still doesn’t display anything.
I expected to see the validation message like “The name field is required.” but the form just reloads.
How can I properly show Laravel validation errors in a Blade view?

Variables not populating from PHP Script to mail message [duplicate]

The script does run, and I get the email. None of the information in the variables appears in the message, though. I get the plain text (“Query from” in the subject and “From” in the body). I have pasted the PHP script and the HTML form below. I would love to use PHPMail, but I don’t know if it is in the hosting environment I use, and I cannot install it myself. Until I can find out, I am using the native mail() function. Thanks in advance.

PHP Code 
<?php $to = "[email protected]"; 
$subject = "Query from" . htmlspecialchars($_POST['customer']); 
$msgBody = htmlspecialchars($_POST['msgBody']) . " From: "; 
$from = htmlspecialchars($_POST['subAdd']); $message = $from . " " . $msgBody;

if (mail($to, $subject, $message)){
    header("Location: https://bkjdesignspa.com");
}
else{
     echo "<script>window.alert('There was a problem sending the message.')</script>";
}

?>

HTML form

<form id="contactInfo" method="post" action="contactForm.php">                 
    <label>Name</label><br>                 
    <input type="text" placeholder="Name" required><br>                 
    <label>Email</label><br>                 
    <input type="email" id="subAdd" placeholder="Email Address" required><br>                 
    <label>Details</label><br>                 
    <textarea id="msgBody" placeholder="Details of request" style="width: 10em; height: 5em;" required></textarea><br>                                <input type="submit" value="Submit">             
</form><br>

Get previous and next data from glob based on timestamp

I have the following code to sort the items based on a timestamp.

$arr = [];
foreach(glob('*.json') AS $item) {
    $data = json_decode(file_get_contents($item), true);
    $arr[] = [
        'taken' => $data['taken'],
        'file-name' => $data['file-name'],
        'account' => (empty($data['account']) ? null : $data['account'])
    ];
}

usort($arr, function($x, $y) { return $x['taken'] - $y['taken']; });

Here is the content of 4 of these JSON files I have in my folder:

{"hash":"1b668ef9398fe5fc9f68a3ad87d04a77","account":null,"file-name":"DSC00045","place":null,"taken":1663759434,"uploaded":1759397192},{"hash":"bccfb4221adc1e00b4fa34eef309d025","account":null,"file-name":"DSC00170","place":null,"taken":1663760473,"uploaded":1759397201},{"hash":"5aa05170b8e6c21b947db1a20b5a93ac","account":null,"file-name":"DSC00230","place":null,"taken":1663773888,"uploaded":1759397227},{"hash":"8de553beeda575d16377e62e77183507","account":null,"file-name":"DSC00318","place":null,"taken":1547596822,"uploaded":1759397265}

I want to get the previous and next item based on taken (which is the timestamp).

Currently I have made a mess and used the following to get the current item:

foreach($arr_test AS $test) {
    if($test['file-name'] == $get_image) {
        $current = $test;
    }
}

var_dump($current);

$get_item is the variable for (isset($_GET['img']) ? safetag($_GET['img']) : null) which contains the file name.

But now I am stuck. I have no clue what so ever how to get the previous and next item based on the timestamp.

My goal is to sort all items from the first foreach based on taken, and then get current, previous, and next file name based on when the photos were taken no matter how they are sorted in the folder. It’s for a photo gallery.

Scraping booking.com with PHP Curl

I’m trying to setup a simple php script (below) to check when a certain property becomes available on booking.com.
The site seems to work with some pretty simple query parameters – you can just go directly to eg https://www.booking.com/searchresults.en-gb.html?ss=New+York&checkin=2026-03-01&checkout=2026-03-05&group_adults=2 and it will process the search correctly, no need to be logged in, or click through from the previous search page etc.
But the following script just returns empty search results, with no search parameters filled in:

<?php
   
$ch = curl_init();
$timeout = 180;       
$url="https://www.booking.com/searchresults.en-gb.html?ss=New+York&checkin=2026-03-01&checkout=2026-03-05&group_adults=2";
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION , 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);   
$output = curl_exec($ch);
curl_close($ch);  
echo $output;
 
?>

Not sure if it’s down to booking.com implementing some kind of anti-bot protection behind the scenes which is actively blocking it, or if there’s just some simple thing I’m missing?

How to integrate v3 invisible recaptcha to Magento 2.4.6 search

I have integrated recaptcha in search form but the issue is when user directly hit the search url like catalogsearch/result/?q=ring, there also i have integrate recaptcha. Please suggest some method. I have integrated it but when i search for the first time, it refreshes and redirect to homepage. Rest in second time it is working
Code of my form.mini.phtml

    <?php
$helper = $this->helper('MagentoSearchHelperData');
$objectManager = MagentoFrameworkAppObjectManager::getInstance();
$scopeConfig   = $objectManager->get(MagentoFrameworkAppConfigScopeConfigInterface::class);
$siteKey       = $scopeConfig->getValue(
    'recaptcha_frontend/type_recaptcha_v3/public_key',
    MagentoStoreModelScopeInterface::SCOPE_STORE
);
?>

<i id="searchIcon" class="search-icon icon-search "></i>
<div id="screen" class="search-screen">
  <div class="container">

    <form class="form minisearch" id="search_mini_form2" action="<?php echo $helper->getResultUrl() ?>" method="get">
      <div class="field search">
        <div class="search-input">
          <input id="search2"
                 data-mage-init='{"quickSearch":{
                      "formSelector":"#search_mini_form2",
                      "url":"<?php echo $block->getUrl('search/ajax/suggest'); ?>",
                      "destinationSelector":"#search_autocomplete"}
                 }'
                 type="text"
                 name="<?php echo $helper->getQueryParamName() ?>"
                 value="<?php echo $helper->getEscapedQueryText() ?>"
                 placeholder="<?php echo __('Search'); ?>"
                 class="search-box input-text"
                 aria-labelledby="search_autocomplete"
                 maxlength="<?php echo $helper->getMaxQueryLength();?>"
                 role="combobox"
                 aria-haspopup="false"
                 aria-autocomplete="both"
                 autocomplete="off"/>
          <div id="search_autocomplete" class="search-autocomplete"></div>
        </div>

        <!-- hidden field for v3 token -->
        <input type="hidden" name="g-recaptcha-response" id="recaptchaResponseSearch" />

        <div class="search-button">
          <button type="submit"
                  class="action search"
                  value="submit"
                  style="display: none;">
              <span><p style="display: none;">Search</p></span>
          </button>
        </div>
      </div>   
    </form>

    <!-- reCAPTCHA v3 API -->
    <script src="https://www.google.com/recaptcha/api.js?render=<?php echo $siteKey ?>"></script>
    <script>
    require(['jquery'], function($) {
        $(document).ready(function() {
            var $form = $('#search_mini_form2');
            var $input = $('#recaptchaResponseSearch');

            if (!$form.length || !$input.length) return;

            // Hook into quickSearch before AJAX request
            $form.on('submit', function(e) {
                e.preventDefault();

                // Generate reCAPTCHA token
                grecaptcha.ready(function() {
                    grecaptcha.execute('<?php echo $siteKey ?>', {action: 'search'}).then(function(token) {
                        $input.val(token);

                        // Now manually trigger quickSearch AJAX
                        if ($form.data('mage-init')) {
                            $form.trigger('search'); // triggers quickSearch submit
                        } else {
                            // fallback to normal submit
                            $form.off('submit'); // prevent loop
                            $form.submit();
                        }
                    });
                });
            });
        });
    });
    </script>

    <span class="close-icon"><i id="closeIcon" class="icon-close"></i></span>
  </div>
</div>

//Code of plugin  is 
namespace CustomSearchCaptchaPlugin;

use MagentoFrameworkAppActionAction;
use MagentoFrameworkAppRequestInterface;
use MagentoFrameworkAppObjectManager;
use MagentoFrameworkControllerResultFactory;
use MagentoStoreModelScopeInterface;

class SearchDispatchPlugin
{
    public function aroundDispatch(Action $subject, Closure $proceed, RequestInterface $request)
    {
        $module     = $request->getModuleName();
        $controller = $request->getControllerName();
        $action     = $request->getActionName();

        // Only for catalogsearch/result/index
        if ($module === 'catalogsearch' && $controller === 'result' && $action === 'index') {
            $token = $request->getParam('g-recaptcha-response');

            // Load dependencies only when needed
            $objectManager  = ObjectManager::getInstance();
            $scopeConfig    = $objectManager->get(MagentoFrameworkAppConfigScopeConfigInterface::class);
            $messageManager = $objectManager->get(MagentoFrameworkMessageManagerInterface::class);
            $resultFactory  = $objectManager->get(ResultFactory::class);

            if (!$token) {
                $siteKey = $scopeConfig->getValue(
                    'recaptcha_frontend/type_recaptcha_v3/public_key',
                    ScopeInterface::SCOPE_STORE
                );

                echo '<html><head><script src="https://www.google.com/recaptcha/api.js?render=' . $siteKey . '"></script>
                <script>
                grecaptcha.ready(function() {
                    grecaptcha.execute("' . $siteKey . '", {action: "search"}).then(function(token) {
                        let url = window.location.href;
                        if(url.indexOf("g-recaptcha-response") === -1) {
                            if(url.indexOf("?") > -1) {
                                url += "&g-recaptcha-response=" + token;
                            } else {
                                url += "?g-recaptcha-response=" + token;
                            }
                            window.location.href = url;
                        }
                    });
                });
                </script></head><body>Please wait... validating search...</body></html>';
                exit;
            }

            // If token exists, verify
            if (!$this->verifyRecaptcha($token, $scopeConfig)) {
                $messageManager->addErrorMessage(__('CAPTCHA verification failed. Please try again.'));
                $resultRedirect = $resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setPath('/');
                return $resultRedirect;
            }
        }

        return $proceed($request);
    }

    protected function verifyRecaptcha($token, $scopeConfig)
    {
        $secret = $scopeConfig->getValue(
            'recaptcha_frontend/type_recaptcha_v3/private_key',
            MagentoStoreModelScopeInterface::SCOPE_STORE
        );

        $verifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
        $response  = file_get_contents($verifyUrl . '?secret=' . $secret . '&response=' . $token);
        $result    = json_decode($response, true);

        return isset($result['success'], $result['score'], $result['action']) &&
               $result['success'] === true &&
               $result['score'] >= 0.5 &&
               $result['action'] === 'search';
    }
}

“Docker Compose Laravel setup: Nginx shows 404, phpMyAdmin cannot connect to db”

Laravel + Docker Compose on macOS: Nginx (web, ports 8081:80, volumes ./src:/var/www/html, default.conf root /var/www/html/public, fastcgi_pass app:9000) returns 404 on http://localhost:8081, while phpMyAdmin (8080:80) cannot reach MySQL 8 service db (3307:3306) even with PMA_HOST=db (getaddrinfo / mysqli_real_connect errors). How can I diagnose the network/volume/config issue and fix both 404 and DB login?

phpMyAdmin cannot connect to MySQL in a Docker Compose Laravel stack: all containers (app, web, db, phpmyadmin) are Up; Laravel connects using DB_HOST=db; MySQL is exposed as 3307:3306; phpMyAdmin has PMA_HOST=db; yet login fails with getaddrinfo ENOTFOUND db / php_network_getaddresses. Why does service name resolution or port mapping fail, and what exact configuration is required for phpMyAdmin → MySQL 8 in this setup?

Stuck with Nginx 404 and phpMyAdmin DB connection error in Laravel + Docker Compose: route:list shows / and /author/add, Nginx config sets root /var/www/html/public and try_files … /index.php, but visiting http://localhost:8081 or /author/add returns 404; phpMyAdmin at http://localhost:8080 cannot connect to db (MySQL 8). Compose uses ./src:/var/www/html and 8081:80 / 3307:3306. What am I missing?

Docker Compose Laravel environment on macOS: Nginx (8081:80) serves 404 despite correct default.conf (root /var/www/html/public, try_files, fastcgi_pass app:9000), and phpMyAdmin (8080:80) cannot log in to MySQL service db (3307:3306) with PMA_HOST=db set—DNS resolves intermittently, mysqli_real_connect fails. What are the definitive steps to verify container networking, volumes, and phpMyAdmin/MySQL 8 auth so both issues are resolved?

PHP critical condition – jtl_paypal_commerce, JTL Shop [closed]

I have an online store based on JTL Shop where this error keeps being sent all the time:

“Info: CRITICAL: PHP critical condition found!
Possbile plugin name: jtl_paypal_commerce
2025-10-01 09:20:22.223860 [NOTICE] [986761] [T0] [80.187.122.9:22877-H3:89E3F183CCE72FEF-12#APVH www.domain.de:443] [STDERR] PHP Fatal error: Uncaught TypeError: JTLLanguageLanguageHelper::mappedGetCountryCodeByCountryName(): Argument #1 ($iso) must be of type string, null given, called in /home/bndifoms/domains/domain/public_html/includes/src/Language/LanguageHelper.php on line 180 and defined in /home/bndifoms/domains/domain/public_html/includes/src/Language/LanguageHelper.php:1105”

Has anyone ever had a similar case before? Or perhaps does anyone know a solution / could help?

Thank you in advance.