Entries filed under PHP

Default Filter in Laravel Nova

Posted on 20. Februar 2023 Comments

There is currently no way to use a Filter for a Resource in the default view. However, for the desired outcome, it’s possible to use a combination of the Nova indexQuery method and Laravels global scopes.

  1. Create a scope with the desired default filter: php artisan make:scope DefaultFilterScope
  2. Use this scope in the indexQuery method of the Nova Resource like so:
    public static function indexQuery(NovaRequest $request, $query) { return $query->withGlobalScope(DefaultFilterScope::class, new DefaultFilterScope); }
  3. In the other Filters for this Resource, add $query = $query->withoutGlobalScope(DefaultFilterScope::class); in the first line of the apply method, to remove the Global Scope added in the indexQuery method, and just use whatever the Filter does.


Deploy with envoyer and artisan

Posted on 20. Mai 2020 Comments

I just revived JustParks Envoyer Deploy package and updated it for Laravel 5.5+ (handle() and fire() – both work now), 6 and 7. I haven’t written it, so all the credit goes to Dayle Rees/JustPark.

Updated envoyer:deploy package on packagist

As you can tell from the README, Install like so:

composer require repat/envoyer-deploy --dev

Then publish the config file by executing this and selecting the number that says JustPark\Deploy\ServiceProviders\EnvoyerServiceProvider.

php artisan vendor:publish

In the envoyer.php config file, fill in the unique ID that comes after the /deploy in the link you can find in the Deployment Hooks tab in envoyer, e.g. https://envoyer.io/deploy/4aLDdfsfsd4s6fSzeKGNfakekey75R45wOwTQULEDJNrj

You can now deploy with

php artisan envoyer:deploy

Sourcecode for repat/envoyer-deploy on GitHub

Laravel QueueWorker: database not configured

Posted on 4. November 2019 Comments

It doesn’t matter which queue system you’re using: Redis, a relational database such as MySQL or a cloud solution like AWS SQS ; you can always store failed jobs in a normal database table. This configuration is done in config/queue.php in the last array:

'failed' => [
    'driver' => 'database',
    'database' => 'default', // NOTE: connection, not database!
    'table' => 'jobs_failed',

The key is to put in the connection name, not the database name for ‚database‘. If you don’t you will get the error message „Database default not configured“ every time a job fails instead.

Check out my Laravel Job Eloquent Models.

Laravel Dusk: The currently authenticated user is not who was expected.

Posted on 31. Oktober 2019 Comments

If you’re having trouble using $browser->loginAs($user) it might be because the SESSION_DRIVER is set to array. So even this simple code will fail:

$this->browse(function (Browser $browser) {

Error: The currently authenticated user is not who was expected.
Failed asserting that two arrays are identical.


Write a .env.dusk.local (or where ever you’re starting the tests from) and use a persistent driver like SESSION_DRIVER=database or SESSION_DRIVER=file

Crawling with Web Storage in PHP

Posted on 28. September 2019 Comments

Some pages have an extra screen before the real site appears, e.g. for age verification (like porn, for now anyways, or drug sites) or country/currency selection (like travel and big company sites). As far as I researched this, sometimes the selection is stored in a cookie, sometimes in Web Storage.

Crawling with Cookies is no problem with Guzzle.

But for example, at https://cannabis.wiki the age verification is stored in the Local Storage as you can see in the Chrome DevTools:


Using spatie/crawler we can inject a Browsershot (puppeteer) instance, that sets the localStorage key ageConfirmed through custom JavaScript:

$js = "localStorage.setItem('ageConfirmed', '1');";
$browsershot->setOption('addScriptTag', json_encode(['content' => $js]));

However, the code is only injected after the side is already loaded. Therefore we have to use JavaScript to reload the page:

$js = "localStorage.setItem('ageConfirmed', '1');location.reload()";
$browsershot->setOption('addScriptTag', json_encode(['content' => $js]));

You can test this on the console e.g. by using ->save($pathToFile); and have a look at the screenshot to see if it worked.

Laravel: Serialization of ‚Closure‘ is not allowed with Jobs and Queues

Posted on 26. Februar 2018 Comments

When dispatching Jobs onto a queue it’s possible to get the following error:

Serialization of ‚Closure‘ is not allowed

This basically means that you are either passing a class that contains anonymous functions („closures“ in PHP) or that in the Job itself there is an anonymous function. This could also be a library you are using. PHP is unable to serialize closures per se. When Jobs get dispatched onto the queue, everything has to be serialized before. If you absolutely must use them this way, look into the Super Closure package by jeremeamia. However, just rewriting the code a little might be easier:



Instead of passing a whole object to the Job like so:

$objOfClassWithClosures = ...;
$job = new Job($objOfClassWithClosures);

Pass the Fully Qualified Class Name (that’s what ClassName::class returns) to the job and instantiate the object on the other side, possibly even using Laravels Container:

$job = new Job(ClassWithClosures::class);

Inside the job you can then use the constructor to make a new instance of that class:

public function __construct(string $fqcn) {
$objOfClassWithClosures = app()->make($fqcn);


PHP + Laravel development Packages for atom.io

Posted on 30. Januar 2018 Comments

PHP CS Fixer

brew install php-cs-fixer

apm install php-cs-fixer


php path: /usr/local/bin/php

php-cs-fixer path: /usr/local/bin/php-cs-fixer

PHP CS Fixer Rules: @PSR2,blank_line_after_opening_tag,whitespace_after_comma_in_array,blank_line_after_namespace

PHP CS Fixer Arguments: --using-cache=no, --no-interaction, --stop-on-violation

[x] Show Notifications


Can also be used on commandline for folders, e.g.
$ php-cs-fixer fix app/ --rules=@PSR2,blank_line_after_opening_tag,whitespace_after_comma_in_array,blank_line_after_namespace


php-integrator-refactoring (php-integrator-base)

apm install php-integrator-base

apm install php-integrator-refactoring

Linting (also see linter(-php))

Sort use statements


linter and linter-php

apm install linter

apm install linter-php

In case linting with php-integrator-base does not work.


language-blade and language-vue

apm install language-blade

apm install language-vue



apm install minimap

Short overview over the code on the right side



apm install highlight-selected



apm install platform-ide-terminal

Instead of switching windows, terminal right in atom




apm install symbols-tree-view

Structured overview on the right side over classes, constants, attributes, methods etc


hyperclick and hyperclick-php

apm install hyperclick

apm install hyperclick-php

Cmd+Click on classes, functions etc to go to origin.

Not needed if you installed atom-ide-ui



apm install teletype

Work on the same file with coworkers, encrypted via WebRTC


More dependencies might be installed with installing some of these packages

PHP Commandline Notification

Posted on 3. Januar 2018 Comments

When you run long (PHP) jobs it’s easy to forget about the terminal. That’s why I’ve created a small PHP package that will make a little sound. Because PHP itself doesn’t have this functionality anymore it’s possible to just echo the ASCII sign for BEL. Simply put this at the end of your PHP job:

use repat\CommandlineBell;
// flashes screen if possible, otherwise just bell()
// makes a beep sound

Under the hood it’s really just:
echo "0x07";

A good (non-PHP) alternative I found is brb by Viktor Fröberg, just run commands like this

php artisan migrate --seed ; brb

Of course it’s always possible to just run a TTS app on the commandline via exec() like this:

exec("say terminal task done");

Or you could do it similar to brb:

php artisan migrate --seed ; say seeding done

Source on GitHub

Quick and dirty redirect script for the fitting shipping provider

Posted on 2. März 2017 Comments

Another way to use the PHP library shipping-service-provider-check apart from fixing the shipping providers in the ERP Plentymarkets is a simple quick and dirty PHP script that redirects to the tracking page of a fitting shipping provider. You can find the whole sourcecode on GitHub.


If you don’t use some sort of MVC this is a quick way to do it. If you do, I suspect you’ll know how to alter this example to fit your system. Feel free to write me an e-mail or comment if you need help

  1. Log onto your server and create a folder
  2. Copy or git pull the files, including .htaccess
  3. Get Composer
  4. composer require repat/shipping-service-provider-check

Explanation of the code

The $trackingId variable is received via HTTP GET. This means the URL would be http://url.tld/trackingscriptfolder/script.php?tracking_id=123456 (or without the script.php in case of the .htaccess), where 123456 is the TrackingID. The rest is more or less just for debugging. The scripts returns a HTTP Code 422 and ends if there is no input given.

$trackingId = $_GET["tracking_id"];
if (empty($trackingId)) {
  $unprocessableEntity = 422;
  echo "wrong input";

Next the URLs will be defined. The keys have to match the shipping providers so make sure the shipping providers are added at the library as well. The TrackingID will be added at the end of the URL, so make sure they have the right format.

$shippingProviderURLs = [
  "dhl" => 'https://nolp.dhl.de/nextt-online-public/set_identcodes.do?idc=',

Then follows the documented way of checking for the providers. It could technically be that at the same time a TrackingID is valid for more than one provider. To keep things simple, we’ll just use the first one (array_search instead of array_keys). In case there is none found, array_search returns false and the script continues. In case there is one found, the header() function is called to redirect the user to the correct provider page.

$checkedProvider = array_search(true, $result);
$urlOfCheckedProvider = $shippingProviderURLs[$checkedProvider];

if ($checkedProvider !== false) {
  header('location: ' . $urlOfCheckedProvider . $trackingId);

Now it’s up to you what you will do with the ones you can’t redirect. I decided to write a little skeleton.html file and include that with a simple message that the user could try the shipping providers where a check is not possible (no API, no website scraping, no regex). They are listed earlier:

$shippingProviderURLsNoCheck = [
  "DPD" => 'https://tracking.dpd.de/parcelstatus?query=',

Fix shipping providers for FBA orders in Plentymarkets

Posted on 27. Februar 2017 Comments

The popular ERP Plentymarkes let’s you send your orders via the Fulfillment by Amazon program to your customers. Amazon is just used as a logistics partner, the order doesn’t have to come via Amazon. It could e.g. be a Rakuten or eBay order. The problem that Plentymarkets didn’t address at all and is discussed in the private forums, is that Amazon chooses whatever shipping company they seem fit.

Every order has a standard shipping provider and with it comes a URL for tracking the package. Most of the vendors would implement an event procedure („Ereignisaktion“) that sends an email to the customer containing the order and the TrackingID as soon as it’s shipped. The TrackingIDs are directly imported from Amazon. Unfortunately Plentymarkets does not change the shipping provider in case it’s not the default one (which is often the case). So the customer gets wrong information.

In one of last last blogposts I introduced a PHP package to check which shipping provider a TrackingID belongs to by either scraping their website or using a regular expression and filtering for common patterns. In this blog post I want to explain how to use it to fix those orders. You will need a webserver with PHP and MySQL and a little knowledge of programming and Linux.

You can find some simplified code examples on GitHub soon.

  1. Take your FBA orders out of the event procedures that sends the email to the customers, filter e.g. via WarehouseID
  2. Instead, use an event procedure to mark those orders with a flag, e.g. a star (ID 2)
  3. Create a DynamicExport of the type OrderComplete. Filter for your Sent Status (usually 7) and WarehouseID of FBA orders. Include these fields:
    1. OrderID
    2. OrderPackageNo
    3. OrderParcelServiceID
    4. OrderParcelServicePresetID
    5. OrderLastUpdateTimestamp
  4. Implement the SOAP Call GetDynamicExport (will be replaced by REST via Plugin mid-2017)
  5. Write a Cronjob that calls the GetDynamicExport script with the FormatID of the DynamicExport from #2
  6. Create a database table called ‚pm_shipping_providers_check‚ with the fields from #2
  7. Write a script that imports the CSV you downloaded with the GetDynamicExport call into your MySQL database
  8. Create another DynamicExport, this time of the type Order. Include these fields:
    1. OrderID (Synchronisation)
    2. ParcelServiceID (Import)
    3. ParcelServicePresetID (Import)
    4. PackageNo (Import)
  9. Create a table with these fields called ‚pm_shipping_providers_correction
  10. Create a script, that uses the shipping-service-provider-check library to check the every PackageNo in ‚pm_shipping_providers_check‘ and – if the provider is different from the default one – writes it into ‚pm_shipping_providers_correction‘
  11. Implement the SOAP Call SetDynamicImport (see #3)
  12. Write a script that exports the table ‚pm_shipping_providers_correction‘ into a (semicolon seperated) CSV.
  13. Create a cronjob that uploads the file regularly
  14. Create an event procedure on the event PackageNo that sends out emails, but only for the previously flagged orders