Entries filed under English

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.

Connect SequelPro with DigitalOcean Managed MySQL 8.0.X

Posted on 19. September 2019 Comments

ALTER USER 'doadmin' IDENTIFIED WITH mysql_native_password BY 'secret_password';

Change ’secret_password‘ to the password given to you by DigitalOcean.

The reason behind this is that SequelPro and other MySQL Clients only work with the old (5.X) way of MySQL authentication vs. the new (8.X) caching_sha2_password. It has nothing to do with the MySQL version itself as Sequel Pro seems to work just as well with version 8.X. You can find more information in the MySQL documentation.

Traveling from Asunción to Clorinda and back

Posted on 23. Juli 2019 Comments

There is very little (English) information on the internet about how to travel from the Paraguayan capital Asunción to the little town Clorinda, just across the border. Since I don’t have a travel blog but this ranks fairly well, I thought I’d put it up. The only thing I could find, apart from TripAdvisor and LonelyPlanet posts from 10y ago, is this article in Spanish from ultimahora.com.

There are (at least) 2 border crossings and I recently did both. I imagine they work they same the other way around.

Puerto Falcón/José Falcón

  1. Go to the main bus station, Terminal the Omnibus Asunción, but don’t go inside. There are a few food stands outside on the Avenida República Argentina where buses regularly stop, going north. Just stand there for a while and wait until a bus comes that says „Puerto Falcón“ on the side. If you’re unsure, just say those 2 words to the driver and he will most likely nod. The trip is 6000 PYG, which at the time of writing is ~1 USD. This bus had air conditioning. It seems to depart at Mercado but I’m not sure about that.
  2. The bus takes you up the road past the airport and then takes a turn west across the Rio Paraguay on the bridge Puente Remanso. Driving through the city, especially in traffic, is a bit geographical nonsense, as you can see on the map. But it does get you there.
  3. Everybody will have to get out at the border station in Puerto Falcón. You then cross the river over the bridge into Argentina already, no need to do anything on the Paraguayan side.
  4. On the Argentinian side of the bridge, go to the very right. You will find 2 immigration offices there where you get your exit stamp from Paraguay and your entry stamp from Argentina. It took less than 2 minutes.
  5. Go a little further to the next street crossing, past the taxis. To the left there will be a dirt road that goes into town (in case you want to walk) but every now and then a pretty run down bus comes by. It’s 5000 PYG (~0.84 USD) to go to the center of Clorinda and takes about 10-15 minutes. It also goes past the western part of town, Juan Domingo Peron. The taxis waiting there seem to be expensive, to make sure not agree on a price before and not get ripped off.

Buses to the border depart from outside the central bus station
Dirt road to Clorinda Center, if you want to walk ~2km
Pretty run down bus that goes from the border to Clorinda Central for 5000 PYG

Nanawa / Puerto Elsa

  1. Go to the Cruce Fronterizo in Clorinda. You will either walk down the riverside and see a pretty colorful bridge (s. picture) or come from a small market hall, where you can see the immigration office at the end.
  2. Go to immigration and get an exit stamp from Argentina and an entry stamp from Paraguay! It’s possible to cross into Paraguay without it, but you need that stamp, especially if you got a stamp in Puerto Falcón. Otherwise you will have problems leaving Paraguay again via any other border station, including the airport.
  3. Cross the colorful bridge Pasarela de la Amistad Clorinda – Nanawa through the markets.
  4. Turn left and walk up the riverside past the Casino. Then turn right to the Terminal de Omnibus Puerto Elsa. This is not the Terminal de Omnibus Clorinda (that would be in Argentina – this is Paraguay already on the other side of the river). It’s not on Google Maps but OpenStreetMap (e.g. Maps.me) will have it. In fact, it doesn’t look like a terminal at all. Just a roof some some dude making hamburgers and some chickens running around. But there will most likely be a bus waiting. They seem to be run in the collectivo way – so they only go when they’re full, not with a specific schedule. And people also sometimes referred to these quite big buses as collectivo. Not exactly what you might know as a collectivo from Central America.
  5. The bus line is 101 but there are apparently different versions that end up in different places, like 101A and 101B. Mine was 101A and left me at the famous Mercado 4 and did not go to the central but station. Again, the bus was 6000 PYG (~1USD). In the evenings/night it’s apparently not the safest place so make sure you can either take an Uber or take enough cash for a taxi to get home. Also, it had no air conditioning and is a lot more like the chicken buses in LatAm, drives slow and stops at every little house on the road. It’s good fun though and the locals are super friendly!
Make sure to get your passport stamps before crossing the bridge – even though there are no controls.
Bridge between Clorinda, AR and Nanawa, PY
Línea 101A back to Asunción Mercado 4

Ferry Puerto Pilcomayo – COPANATRA Servicio de balsas

There is one report about a ferry and timetables on Facebook but I asked around and the ferry doesn’t seem to run on Saturdays, probably not the whole weekend.

A few notes on Clorinda

This little town with some odd 40k inhabitants is pretty dead. There’s apparently one hotel, one ATM (though Paraguayn Guaranís/PYG are accepted everywhere, even on the bus!), a few shops selling mostly things like dog food or mate in bulk, a few mum and pop supermarkets. I didn’t see an open café or restaurant, but it might’ve been the time of day. There’s nothing for sightseeing and if you want to travel to e.g. Buenos Aires I’d suggest taking to long distance Bus directly from Asuncións Bus Terminal. It will take the same route anyways but is way less hassle. On the Nanawa side, there’s an interesting market, but selling mostly cheap stuff from China and some local produce – and of course, Mate and accessories. It’s ok for an afternoon or to get the passport stamp to check off the country – although I highly encourage everybody to travel in Patagonia extensively and visit Buenos Aires – this is not the way to see Argentina 😉

Travel Setup

Posted on 22. Juni 2018 Comments

For a while now I’ve been bouncing around from country to country and while occasionally, e.g. in Iceland, I don’t have everything I need, it’s usually possible (and in case of Iceland – expensive) to just buy things wherever you are. So I only travel with a Osprey 40L backpack. I’ve been wanting to write a packing list for a while. In it is:



  • MacBookPro 13“ in Crumpler case
  • Macbook USB-C charger + European plug + American plug
  • 15.6“ External monitor + USB-C cable (power+data)
  • SD/µSD Card Reader
  • USB charger with American plug
  • Powerbank
  • Small Bose speaker
  • External harddrive + USB cable
  • Adapter for UK/Ireland
  • Feature phone for my German SIM card (double SIM phone would be better)
  • 2 USB-C to USB adapter
  • USB to USB-C chord (charging phone with powerbank)
  • CCTV disguised as power adapter
  • Nexus 5X
  • Koss Porta Pro
  • Cheap ear phones since they break anyway
  • iPad + charger cable



  • 3-4 Merino T-Shirts
  • 1 Merino Long Sleeve
  • 1 Merino Sweatshirt
  • 1 Primaloft jacket
  • 1 Rain jacket
  • 1 Belt
  • A whole bunch of underwear + socks


Scuba Diving Equipment

  • Cressi Mask
  • Mares Computer
  • Cheap Actioncam on a bungee cord
  • Logbook + Pen
  • PADI C-Card
  • Small waterproof bag



  • Drivers license + International
  • 1 Credit card from each company (Visa, MasterCard, Amex, Diners Club)
  • Passport
  • Vaccination Documents (to prove e.g. yellow fever vaccination)
  • Medical information document


Bathroom stuff

  • Toothbrush + toothpaste
  • Small bottle with shower gel
  • Nail cutter
  • Ibuprofen + Tylenol + something against diarrhoea
  • Thermometer to check for fever



  • 100 USD in cash for emergencies
  • Cheap antibacterial gel
  • Keychain

Apart from a few guitars, some outdoor equipment (tent, sleeping bag, stove etc), 2 bicycles, a bunch of books and few warm clothes I store on my parents attic and my scuba diving equipment on Gran Canaria that’s also all I own.

A Digital Nomads Guide for Caye Caulker, Belize

Posted on 27. März 2018 Comments

Caye Caulker is a small limestone coral island off the coast of Belize in the Caribbean Sea measuring about 5 miles (8.0 km) (north to south) by less than 1 mile (1.6 km) (east to west).

— https://en.wikipedia.org/wiki/Caye_Caulker

NomadList doesn’t really give it a good rating but in my opinion that’s not quite fair. What attracted me was that it’s smaller than San Pedro with a laid back hippie vibe and good scuba diving spots.

How to get there

  1. Fly, mostly from Belize City
  2. WaterTaxi from Chetumal, MX (with immigration in San Pedro for ~1h), daily at either 3 or 3.30pm + the usual Mexican delay, ~50 USD
  3. WaterTaxi from Belize City/Airport

How to get around

When you arrive (on the eastern side) you can quite literally see the water on the western side of the island. My point is: Caye Caulker is super small! You can easily walk everywhere, rent a bike or, if need be, a golf cart. Not even the police has cars but drive golf carts and motorbikes. I saw about 3 real cars in total and a few construction trucks, but not in the center.

Where to stay

For 30-50€/night you will get a decent apartment/hotel room on AirBnB/booking.com with WiFi and AC.

For 17€ (35 BZD) you will get a bunk bed in a 2 bed „room“ (called „sleep box“) in La Cubana that resembles one of the box hotels found in Japan or Abu Dhabi Airport. But if you spent the majority of the time outside anyway, what more do you need. Otherwise, for the same money, you mostly get big rooms with 8-10+ people and possibly no AC. Here, at least the AC runs from 8pm to 8am. If that (and warm showers) doesn’t interest you, Yuma Hostel directly at the pier seems relaxed (not a party hostel) and has 2 lovely dogs. Further north is the famous Drifted Coconut Hostel.

CoWorking Spaces

Nope! There are no CoWorking spaces or not even DN Hotspot Cafés (that I saw) on Caye Caulker. You have to work wherever you find a nice spot. I can recommend Ice and Beans on the ocean side for your cliché working-on-the-beach-instagram-photo but more importantly: really good coffee! Other than that try the restaurant underneath La Cubana as they have WiFi and power plugs.

Ice and Beans Cafe Caye Caulker

Tropical Paradise Hotel at the (literal) end of the road (how fitting, the cemetery is next door) also has power plugs and decent WiFi, not to mention a good barkeeper/selection of alcohol and drinks on the menu for after-hours.

Across the road from La Cubana is the internet café Caye Board which offers WiFi at 30BZD/4h. I know it seems old school but the place has air conditioning, is relatively calm compared to cafés/restaurants:


You might have problems with your laptop and the high humidity (80%+). My MacBook Pro Keyboard stopped working for a whole morning. Try to blow it out with a Scuba tank (since I couldn’t find anybody with a pressurised air can) to make sure theres no sand/dust in it. And then try working from an air conditioned room because AC does not only make it colder but also dry. If the computer still turns on, try to install software that turns on the internal fan to sort of dry it out. Also read 5 Ways to Protect Your Laptop in the Tropics by Too Many Adapters.


The Belizian Dollar (BZD) is directly tied to the US Dollar with 2:1, meaning 2 BZD = 1 USD. You can use USD as a method of payment and will sometimes even get change back in USD. While certainly not as cheap as the neighboring countries it’s not an expensive country per se. Caye Caulker is small though and everything comes by plane or ship so expect a surcharge. It’s quite touristy so that adds another few dollars to everything you buy.


There are 6(?) dive shops on the island and a few tour operators that re-sell those dives:

Only 3 (or 4?) of those go to the famous Blue Hole which is a few hours on a bumpy speed boat away. Only BDS offers tech/cave diving. They all have some sort of bad reputation and reviews on the web, reaching from reckless boat driving where people got injured to cowboy attitudes by Divemasters, faulty equipment, no oxygen on board despite the obvious risk of DCS with the Blue Hole being ~120m/400ft deep, to even harassment of women and an instructor dying in the Blue Hole. Surely the safest option is to bring your own equipment, some experience and a good buddy. There have been dive centers that had to close down only to reopen a little later with the same staff (Belize  ¯\_(ツ)_/¯ ) That said, there are plenty of people happily diving with those companies and nothing bad happens. Safest bet is not to pay for multiple days in advance as most of them don’t seem to give you your money back (German) if you don’t end up going (weather, illness etc). Alternatively, snorkeling can be just as pretty 🙂

Please refuse to dive with faulty equipment, no matter what the owner/instructor/divemaster says! On return to the island (all dives are boat dives), report them to PADI or SDI/TDI and if necessary to the police. If you have a medical emergency or signs of decompression sickness go immediately go the doctor and call DAN/your insurance. The next hyperbaric chamber is on San Pedro. You can do very little against unfair business policies or unfriendly staff but don’t let them endanger your life or the lives of others on the boat!


For ~10BZD in Calle de Sol (the one going west from the pier) on the left/south side 2 very friendly ladies will wash your clothes. I guess it depends on the amount but I don’t own many things and washed pretty much everything I had minus shorts + T-Shirt I was wearing.


Most restaurants and cafés have WiFi of various speeds and reliability. Get mobile internet as backup since sometimes the internet is just gone for a few minutes and the latency for VoIP calls is better on mobile.

Mobile Internet

BTL is virtually the only provider for GSM based phones (CDMA as used in US/NZ/AUS supported by Smart!). The BTL shop is a little difficult to find since the official address on the website is „backstreet“. Which isn’t exactly wrong but even Google Maps can’t find it. Also the GPS coordinates found on infomarket.bz are wrong, however you will find a said laundry on the opposite site of that road. Your safest bet is to walk towards the big cell towers and ask around. Or take a screenshot of Google Maps:

These are the correct GPS coordinates: 

17°44’35.7″N 88°01’32.0″W

Google Maps shows this at the the corner of Avenida Mangle and Calle de Sol (again, the street straight from the pier all the way down). It’s a white and purple building. OpenStreetMap (e.g. with maps.me) shows this as Belize Telecom Limited:

BTL office for SIM Cards on Caye Caulker (c) OpenStreetMap

To register you need ~15minutes, an ID and ~20 BZD for the SIM card + whatever you want to charge. For 1GB, expect ~30BZD although they seem to have more or less permanent monthly specials which double the amount of data. For 30 BZD I got 4.8GB (March 2018). Although they advertise 4G/LTE I could never get more then HSDPA/3G. Fun fact: on the wall in the BTL building there is a poster with the goal of reaching 25MBit/s Download in 2020. South Korean homing pidgeons might have been faster in the 90s but that’s ok for an island who’s motto is „Go Slow“.

Nice to know

  • The first thing I heard, even before „Taxi?“, was „Marijuana?“. You can indeed smell it on every other street corner although it is not legal at all, no matter what the locals say. A big sign on the police station also confirms that. Many seemingly relaxed and hippie vibe hostels do not tolerate drugs at all and the laws are pretty strict.
  • Belize is an ex-colony of the UK and – as the only country in Central America – the main language is English. The accent is similar to those in the British (ex-) territories in the Caribbean and easy to understand. Most people understand Spanish too and the locals speak Creole, a mixture of languages.
  • If you’re easily sunburned use plenty of sunscreen as with the white sand, you can apparently get a sunburn just from the reflection while standing in the shade. Even if that’d be a myth, the sun can be pretty strong and due to the wind you might not notice the burn fast enough.


Any additions? Contact me! 🙂

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

One Click Shadowsocks with no technical knowledge needed

Posted on 23. November 2017 Comments

Shadowsocks is a proxy that has been designed and used to circumvent censorship in China. So if it’s possible to get traffic across the Great Firewall of China it pretty much can be used anywhere, e.g. Egypt where VPNs are blocked since mid 2017.

Digital Ocean offers virtual servers for cheap with an easy to understand pricing model. Basically you pay either $5, $10, $20, $40, $80 or $160 per month, for more have a look at pricing at digitalocean.com. These server are general purpose servers, you can do everything with them, which also means, they don’t have anything installed and you need to do everything yourself.

oneclickshadowsocks.de is a service to install shadowsocks on DigitalOcean servers without having to actually login via SSH and entering lots of technical commands in the commandline. It uses the DigitalOcean API to create a Droplet (=server) with shadowsocks already set up and running. All you have to do is to enter the IP address you get via e-mail in your shadowsocks client and the password given to you on the website.

The code is open source and the website itself is hosted on GitHub Pages, which means, you can see the sourcecode of the page itself, running at that very moment. This way other people can verify they nothing shady is going on.

Delete empty rows in CSV file with sed

Posted on 23. August 2017 Comments

This is for when you have empty lines (so lot’s of ,,,,,,) in your file.


sed -i '' -e '/^,*$/d' filename.csv
find ./ -type f -exec sed -i '' -e '/^,*$/d' {} \;


sed -i '/^,*$/d' filename.csv
find ./ -type f -exec sed -i '/^,*$/d' {} \;


^ marks the beginning of a line
,* marks a possible infinite amount of commas
$ marks the end of a line

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=',