<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: adithyasrinivasan</title>
    <description>The latest articles on Forem by adithyasrinivasan (@adithyasrinivasan).</description>
    <link>https://forem.com/adithyasrinivasan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F568247%2Fed814d1f-11a2-4cf7-a5c3-81d450a927f5.png</url>
      <title>Forem: adithyasrinivasan</title>
      <link>https://forem.com/adithyasrinivasan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adithyasrinivasan"/>
    <language>en</language>
    <item>
      <title>Data Providers in PHPUnit</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Wed, 30 Mar 2022 12:53:47 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/data-providers-in-phpunit-1e80</link>
      <guid>https://forem.com/adithyasrinivasan/data-providers-in-phpunit-1e80</guid>
      <description>&lt;p&gt;When I built a &lt;a href="https://www.arbeitnow.com/tools/salary-calculator/germany"&gt;Salary Calculator for Germany&lt;/a&gt; using Laravel, I started covering the code with Unit Tests using PHPUnit. This particularly came in handy when I had to cover more edge cases as I was able to trust the calculation. One of the features that I didn't know until that point was &lt;a href="https://phpunit.readthedocs.io/en/9.5/writing-tests-for-phpunit.html#data-providers"&gt;Data Providers in PHPUnit&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Data Provider?
&lt;/h3&gt;

&lt;p&gt;When I write a test for a method, or a class, I write multiple assertions with the values for the same code. Data Providers are useful here when all that changes is the values passed to the method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DataProviders are a framework for easily controlling how data can be provided from a source&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take an example of how you would write a test &lt;strong&gt;without&lt;/strong&gt; data providers. Assume you have a method &lt;code&gt;add($a, $b)&lt;/code&gt; in a class &lt;code&gt;Operations&lt;/code&gt; that returns a value, summing up the numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public function test_add()
    {
        $actual = (new Operations)-&amp;gt;add(1, 2);
        $this-&amp;gt;assertEquals(3, $actual);
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you want to add multiple assertions, you would be tempted to add another assertion like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public function test_add()
    {
        $actual = (new Operations)-&amp;gt;add(1, 2);
        $this-&amp;gt;assertEquals(3, $actual);

        $actual = (new Operations)-&amp;gt;add(3, 4);
        $this-&amp;gt;assertEquals(7, $actual);
    }

    // Or a test per method
    public function test_add_first()
    {
        $actual = (new Operations)-&amp;gt;add(1, 2);
        $this-&amp;gt;assertEquals(3, $actual);
    }

    public function test_add_second()
    {
        $actual = (new Operations)-&amp;gt;add(3, 4);
        $this-&amp;gt;assertEquals(7, $actual);
    }



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These add overhead if the signature of the method changes, or when you want to cover more cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use a Data Provider in PHPUnit
&lt;/h3&gt;

&lt;p&gt;A Data Provider can simplify this, allowing you to pass multiple sets of values for the same test. From the official documentation:&lt;/p&gt;

&lt;p&gt;A data provider method&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;must be &lt;code&gt;public&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;and either return an array of arrays or an object that implements the &lt;code&gt;Iterator&lt;/code&gt; interface and yields an array for each iteration step.
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's convert the existing test case using a Data Provider. We will use a &lt;code&gt;dataProvider&lt;/code&gt; annotation following the name of the data provider.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
* @dataProvider addProvider
*/
public function test_add($a, $b, $expected)
{
    $actual = (new Operations)-&amp;gt;add($a, $b);
        $this-&amp;gt;assertEquals($expected, $actual);
}

public function addProvider()
{
    return array(
            array(1, 2, 3),
            array(4, 5, 7),
    );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, PHPUnit would pass the take the array, loop through the items (array again) and pass the arguments based on the &lt;strong&gt;position&lt;/strong&gt; of the method parameters.&lt;/p&gt;

&lt;p&gt;For the first item, it will take &lt;code&gt;array(1, 2, 3)&lt;/code&gt;, call &lt;code&gt;test_add(1, 2, 3)&lt;/code&gt;  and validate the assertions. Then the next item and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inline Data Providers in PHPUnit
&lt;/h3&gt;

&lt;p&gt;In the test cases above with a Data Provider, we can simplify it even further by inlining the data provider. The annotation to use is &lt;code&gt;testWith&lt;/code&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
* @testWith array(
            array(1, 2, 3),
            array(4, 5, 7),
    );
*/
public function test_add($a, $b, $expected)
{
    $actual = (new Operations)-&amp;gt;add($a, $b);
        $this-&amp;gt;assertEquals($expected, $actual);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>XML Sitemap is rendering as plain text</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 23 Jan 2022 10:02:10 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/xml-sitemap-is-rendering-as-plain-text-1c11</link>
      <guid>https://forem.com/adithyasrinivasan/xml-sitemap-is-rendering-as-plain-text-1c11</guid>
      <description>&lt;p&gt;After adding &lt;code&gt;&amp;lt;xhtml:link&amp;gt;&lt;/code&gt; to my sitemap file where I included &lt;code&gt;&amp;lt;xhtml:link rel="alternate" hreflang="supported_language-code"&amp;gt;&lt;/code&gt; my XML sitemap file started rendering as a plain text file.&lt;/p&gt;

&lt;p&gt;In the console window of Chrome, I saw an error as well which indicated the structure was off.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Caught TypeError: Cannot read properties of null (reading 'childNodes')at XMLDocument.ready (content.js:218)ready @ content.js:218
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had to adjust my &lt;code&gt;&amp;lt;urlset&amp;gt;&lt;/code&gt; from this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this, thanks to this Stackoverflow answer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://www.w3.org/TR/xhtml11/xhtml11_schema.html http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd"
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/TR/xhtml11/xhtml11_schema.html"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Strangely enough that while the XML was rendering properly, Google Search Console was displaying an issue for the sitemap&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Sitemap or Sitemap index file does not properly declare the namespace!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The schema below fixed the Google issue (that's all we care about in 2021, right?) while the rendering issue still persists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>indexing</category>
    </item>
    <item>
      <title>Automating MySQL backups to S3 using Laravel</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 05 Dec 2021 13:59:58 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/automating-mysql-backups-to-s3-using-laravel-3hnp</link>
      <guid>https://forem.com/adithyasrinivasan/automating-mysql-backups-to-s3-using-laravel-3hnp</guid>
      <description>&lt;p&gt;Having already &lt;a href="https://adithya.dev/s3-snapshots-for-elasticsearch-via-kibana/"&gt;setup automatic S3 snapshots for Kibana,&lt;/a&gt; the next item on the list is to automate MySQL backups. There are a couple of services like Snapshooter that can do this but I prefer doing it on my own.&lt;/p&gt;

&lt;p&gt;To automate &lt;strong&gt;MySQL backups to AWS S3&lt;/strong&gt; with Laravel, I'm using &lt;a href="https://github.com/spatie/laravel-backup"&gt;Laravel Backup&lt;/a&gt; package by Spatie.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install the package using  &lt;code&gt;composer require spatie/laravel-backup&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see a similar error message like this, your PHP version is probably not supported by the package / dependencies. You might want to use &lt;code&gt;composer require spatie/laravel-backup ^6&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argument 2 passed to Symfony\Component\Translation\Translator::addResource() must be an instance of Symfony\Component\Translation\mixed, array given, called in /var/www/html/vendor/nesbot/carbon/src/Carbon/AbstractTranslator.php on line 165
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To publish the configuration file, run &lt;code&gt;php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"&lt;/code&gt; - this will create a file under config called &lt;code&gt;backup.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Go to your AWS Console, create a new IAM User (you can see the steps linked on the Kibana guide) and add   &lt;strong&gt;AmazonS3FullAccess&lt;/strong&gt; to the permissions attached to the user.&lt;/li&gt;
&lt;li&gt;Grab the &lt;strong&gt;AWS_ACCESS_KEY_ID&lt;/strong&gt; and &lt;strong&gt;AWS_SECRET_ACCESS_KEY&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a S3 Bucket from AWS console (the bucket name goes under &lt;strong&gt;AWS_BUCKET&lt;/strong&gt; and your default region under &lt;strong&gt;AWS_DEFAULT_REGION)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;On the &lt;code&gt;config\backup.php&lt;/code&gt; file, under &lt;code&gt;destination&lt;/code&gt; key, change the value of &lt;code&gt;disks&lt;/code&gt; array to include &lt;code&gt;s3&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'disks' =&amp;gt; [
    's3',
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ensure that the default database is set to &lt;code&gt;mysql&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'databases' =&amp;gt; [
    'mysql',
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now if you run the command on your command line &lt;code&gt;php artisan backup:run --only-db --only-to-disk=s3&lt;/code&gt; the process should kick off and you should see similar messages.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Starting backup...
Dumping database database_name...
Determining files to backup...
Zipping 1 files and directories...
Created zip containing 1 files and directories. Size is 900 MB
Copying zip to disk named s3...
Successfully copied zip to disk named s3.
Backup completed!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once this is done, you can setup to run it using the scheduler on a frequency that you prefer. Go to your &lt;code&gt;Console\Kernel.php&lt;/code&gt; and add an entry
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected function schedule(Schedule $schedule)
{        
    $schedule-&amp;gt;command("backup:run --only-db --only-to-disk=s3")-&amp;gt;weeklyOn(6, '7:00');

    //Other commands
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error messages
&lt;/h3&gt;

&lt;p&gt;The problem was incorrect permissions assigned to the IAM User&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Copying zip failed because: There was an error trying to write to disk named s3.

Copying zip failed because: Error executing "ListObjects" on....
AWS HTTP error: cURL error 6: Could not resolve host:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>laravel</category>
    </item>
    <item>
      <title>AWS SignatureDoesNotMatch error</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Fri, 26 Nov 2021 15:08:34 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/aws-signaturedoesnotmatch-error-3o6g</link>
      <guid>https://forem.com/adithyasrinivasan/aws-signaturedoesnotmatch-error-3o6g</guid>
      <description>&lt;p&gt;I was setting up AWS from scratch again on Windows 10. I went into IAM -&amp;gt; Users -&amp;gt; Add User and obtained the &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;. Then I set up both of them under environmental variables.&lt;/p&gt;

&lt;p&gt;I opened up a command prompt and ran &lt;code&gt;aws sts get-caller-identity&lt;/code&gt; and got this error message.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;An error occurred (SignatureDoesNotMatch) when calling the GetCallerIdentity operation: The request signature we calculated does not match the signature you provided&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After a bit of Googling and making sure that &lt;a href="https://github.com/aws/aws-cli/issues/602"&gt;my system time was set correctly&lt;/a&gt;, I found out that sometimes AWS CLI has an issue if the &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; has a + (plus symbol) on the starting part of the value. All I did was to delete the existing &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;, regenerate it and it worked.&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>Remote Laravel Jobs</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Fri, 26 Nov 2021 09:48:57 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/remote-laravel-jobs-1hle</link>
      <guid>https://forem.com/adithyasrinivasan/remote-laravel-jobs-1hle</guid>
      <description>&lt;p&gt;&lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt; has been my go-to framework for building almost anything in the past few years, including Arbeitnow. Laravel &amp;amp; PHP make it such a breeze for anyone to build platforms, APIs to power the modern web. When I'm on the job hunt, I don't look for just "Laravel Jobs" as I consider myself a framework agnostic engineer.&lt;/p&gt;

&lt;p&gt;I do see a lot of people looking for &lt;a href="https://www.arbeitnow.com/laravel-jobs"&gt;Laravel jobs&lt;/a&gt; and companies hiring people with expertise in Laravel, although some times it comes with a PHP / Laravel / Symfony, etc., requirement. As is common in tech, most of these are remote jobs - with remote-first or hybrid options. While remote working is allowed, it is often restricted to &lt;strong&gt;remote in EU&lt;/strong&gt;. Some of them offer &lt;strong&gt;visa sponsorship&lt;/strong&gt; and relocation support as well, so check it out.  &lt;/p&gt;

&lt;p&gt;I have tried to include salary ranges for laravel developers as well, but please make sure that this may change at any time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remote Laravel Jobs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ABOUT YOU&lt;/strong&gt; is one of the fastest growing eCommerce companies in Europe Hamburg’s first unicorn with a value more than USD 1 billion. As a fashion technology corporation, along with our strong team, our ambition is to digitalize the classic shopping stroll by creating an inspiring personalized shopping experience on the smartphone.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are currently looking for skilled &amp;amp; passionate Fullstack Developers (m/f/d) across Medior, Senior and Lead levels to become part of one of our Tech teams, either working onsite in Hamburg, remotely in the EU or in our Tech Hub in Zagreb, Croatia (planned to open in Spring 2022).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/about-you-se-co-kg"&gt;About You Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaleFast&lt;/strong&gt; is a leading full-service eCommerce solution provider and a rapidly growing company. We offer an all-in-one eCommerce solution for fast-growing brands. We provide to our clients the tools, operations and expertise needed to expand globally in no time.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;100% remote work&lt;/strong&gt; on offer until the end of the pandemic, reverting to 2 days a week working from home post-pandemic&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/scalefast"&gt;Scalefast Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bookingkit&lt;/strong&gt; is Europe's leading booking and reservation management software for providers of tours and activities. We have challenged ourselves to digitise and revolutionise the market directly.
Our Tech Stack - PHP, Vue.js, MySQL, Redis, AWS, Cypress.io, Docker
&lt;strong&gt;Remote option:&lt;/strong&gt;
Work from wherever you are, while enjoying quarterly team events with all bookingkids in Berlin. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/bookingkit-gmbh"&gt;BookingKit Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Laravel Jobs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CaseKing&lt;/strong&gt; is an international e-Commerce company with over 900 employees at 12 locations worldwide. We are one of the most successful companies for hardware and gaming equipment in Europe and the industry leader in Germany.
These jobs are mostly located in Berlin, Germany.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/caseking-gmbh"&gt;Caseking Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At &lt;strong&gt;felmo&lt;/strong&gt; we believe that the best veterinary care for your pet should not require more effort than ordering pizza or a cab. We work every day to elevate and deliver high-quality in-home veterinary care to pet-parents and their pets.
felmo ist eine mobile Tierarztpraxis für Hunde und Katzen. 🐶🐱 Wir haben keine stationäre Praxis. Unsere Tierärzte besuchen die Kunden Zuhause. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/felmo"&gt;Felmo Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Urban Sports Club&lt;/strong&gt; is the largest and most flexible flat-rate sports offer with over &lt;strong&gt;50&lt;/strong&gt; types of sports and over &lt;strong&gt;10000&lt;/strong&gt; partner venues across Europe.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently, they are hybrid remote and allow working up to 2 months anywhere in EU. Headquarters is in Berlin, Germany.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/urban-sports-club"&gt;Urban Sports Club Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die &lt;strong&gt;Dosing GmbH&lt;/strong&gt; ist spezialisiert auf digitale Lösungen zur Arzneimittel-Therapiesicherheit.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is located in Heidelberg, Germany.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/dosing-gmbh"&gt;Dosing Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Brainspin GmbH&lt;/strong&gt; ist ein kleiner, aber erfolgreicher, spezialisierter Medienpartner für Einzelhändler, die ihr Geschäft durchschnelle, schön gebaute, ästhetisch ansprechende Webshops und E - Commerce-Sites von Nutzern für Nutzer online bringen möchten.
&lt;strong&gt;4 Tage (€55.000 bis € 65.000 PA) - E - Commerce, Berlin&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/brainspin"&gt;Brainspin Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;überdosis - 54,000 - 72,000 (EUR)&lt;/strong&gt;
We are a small, family-like team of creatives, designing and developing websites and apps for very different clients, for us and for the whole world as open source. We are looking for another PHP/Laravel developer with years of experience. Maybe that’s you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://arbeitnow.com/companies/uberdosis"&gt;überdosis Laravel Jobs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Company blurbs have been borrowed either from Google search results or their own websites. Please always check the company's direct job description for up to date information.&lt;/small&gt;&amp;lt;!--kg-card-end: html--&amp;gt;&lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
    <item>
      <title>Job Board API</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sat, 20 Nov 2021 09:36:20 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/job-board-api-4n22</link>
      <guid>https://forem.com/adithyasrinivasan/job-board-api-4n22</guid>
      <description>&lt;h3&gt;
  
  
  A public free Job Board API with jobs from Applicant Tracking Systems
&lt;/h3&gt;

&lt;p&gt;I have just opened up an API for my job board and you can see more information on the link below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Job Board API
&lt;/h2&gt;

&lt;p&gt;A public free Job Board API with jobs from Applicant Tracking Systems - &lt;a href="https://arbeitnow.com/blog/job-board-api/"&gt;https://arbeitnow.com/blog/job-board-api/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This could serve as a good starting point for a side project, just like how I did last year for Arbeitnow. If you're using Laravel, you're already familiar with the structure of the API. It's in JSON and supports pagination. To navigate between pages, you can follow the next / prev URLs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$http = Http::get('https://arbeitnow.com/api/job-board-api');
if ($http-&amp;gt;ok()){
 // process the data
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Decode GZIP response in Laravel</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 31 Oct 2021 14:37:34 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/decode-gzip-response-in-laravel-3p1l</link>
      <guid>https://forem.com/adithyasrinivasan/decode-gzip-response-in-laravel-3p1l</guid>
      <description>&lt;p&gt;If you try to decode a GZIP response without decoding, you will have seen this error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XMLReader::read(): /var/www/html/:1: parser error : Document is empty {"exception":"[object] (ErrorException(code: 0): XMLReader::read(): /var/www/html/:1: parser error : Document is empty at
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To decode a XML ZIP response in Guzzle, you can do this as recommended by the &lt;a href="https://docs.guzzlephp.org/en/stable/request-options.html#decode-content"&gt;documentation&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Request gzipped data, but do not decode it while downloading
$client-&amp;gt;request('GET', 'foo.xml.gz', [
    'headers' =&amp;gt; ['Accept-Encoding' =&amp;gt; 'gzip'],
    'decode_content' =&amp;gt; false
]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When set to a string, the bytes of a response are decoded and the string value provided to the decode_content option is passed as the Accept-Encoding header of the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Pass "gzip" as the Accept-Encoding header.
$client-&amp;gt;request('GET', 'foo.xml.gz', ['decode_content' =&amp;gt; 'gzip']);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Laravel provides useful header methods via its HTTP client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$response = Http::withOptions([
            'decode_content' =&amp;gt; 'gzip'
        ])-&amp;gt;get('foo.xml.gz');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or using headers, this can be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   $response = Http::accept('gzip')
                -&amp;gt;get('foo.xml.gz');

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>laravel</category>
    </item>
    <item>
      <title>Laravel raw SQL update query</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Mon, 18 Oct 2021 09:29:18 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/laravel-raw-sql-update-query-e80</link>
      <guid>https://forem.com/adithyasrinivasan/laravel-raw-sql-update-query-e80</guid>
      <description>&lt;p&gt;A really small mistake - I wanted to run a MySQL update statement on laravel (no bindings, no parameters, no models) so I wrote this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB::update(`UPDATE table SET something = 1 WHERE id = 1`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I ran this, I got this error&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ValueError: PDO::prepare(): Argument #1 ($query) cannot be empty&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Was a bit surprised to see this. Upon reading the documentation, you're supposed to run the query this way, for queries not returning any values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB::statement('UPDATE table SET something = 1 WHERE id = 1');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, I had used backticks `` for the original longer SQL statement so that seemed to have caused on issue.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Execute quickly with Laravel Tinker</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 17 Oct 2021 20:56:13 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/execute-quickly-with-laravel-tinker-1oop</link>
      <guid>https://forem.com/adithyasrinivasan/execute-quickly-with-laravel-tinker-1oop</guid>
      <description>&lt;p&gt;Came across this on Twitter today on how to execute quickly with &lt;a href="https://laravel.com/docs/8.x/artisan#tinker"&gt;Laravel Tinker&lt;/a&gt;. Seemed like a handy script!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Laravel productivity tip! Add this little function to your bash profile to quickly execute anything with the Tinker command and get the results instantly. &lt;a href="https://t.co/qIB9pQCTWt"&gt;pic.twitter.com/qIB9pQCTWt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— Philo Hermans (&lt;a class="mentioned-user" href="https://dev.to/philo01"&gt;@philo01&lt;/a&gt;
) &lt;a href="https://twitter.com/Philo01/status/1449386062959284224?ref_src=twsrc%5Etfw"&gt;October 16, 2021&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the gist of it that you should add to your bash profile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function tinker()
{
    if [-z "$1"]
        then
            php artisan tinker
        else
            php artisan tinker --execute="dd($1);"
    fi
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then on your terminal, you can execute it with the shortcut, instead of &lt;code&gt;php artisan tinker&lt;/code&gt; and directly as &lt;code&gt;tinker 'User::first()'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The author of the tweet also provided this as an explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you enter “tinker” it will execute the bash function. If no arguments are given, it will simply run “php artisan tinker”. If you provide any argument, this argument is forwarded as the “execute” parameter for the tinker command. The “dd” fn will prettify the output.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>S3 Snapshots for Elasticsearch via Kibana</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 29 Aug 2021 10:51:11 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/s3-snapshots-for-elasticsearch-via-kibana-5c2</link>
      <guid>https://forem.com/adithyasrinivasan/s3-snapshots-for-elasticsearch-via-kibana-5c2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2FCapture.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2FCapture.PNG" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm terrified of racking up big bills with AWS so I don't work a lot with it, aside from &lt;a href="https://aws.amazon.com/ses/" rel="noopener noreferrer"&gt;Amazon Simple Email Service&lt;/a&gt; (SES). For my ElasticSearch 7.14 cluster that I run alongside with Kibana, I wanted to setup &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-restore.html" rel="noopener noreferrer"&gt;Snapshot and Restore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My understanding was that with Snapshots, you obtain a copy of your cluster data at that point and you can restore it when you would like to. I already had an AWS account setup before starting with this. For this, you needed to setup a storage repository and then configure via Kibana.&lt;/p&gt;

&lt;p&gt;This is how I went about it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a S3 Bucket (this is the storage repository we will use with Elasticsearch)&lt;/li&gt;
&lt;li&gt;Create an AWS policy to allow the IAM User to access the S3 Bucket&lt;/li&gt;
&lt;li&gt;Create an IAM User and attach the policy we created&lt;/li&gt;
&lt;li&gt;Install the S3 Repository Plugin&lt;/li&gt;
&lt;li&gt;Register the repository with Kibana&lt;/li&gt;
&lt;li&gt;Setup an automatic policy with Kibana / Elasticsearch so it backs up data via cron&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Create a S3 Bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open AWS Console  -&amp;gt; &lt;a href="https://s3.console.aws.amazon.com/s3/" rel="noopener noreferrer"&gt;S3&lt;/a&gt; -&amp;gt; Create Bucket&lt;/li&gt;
&lt;li&gt;Enter a bucket name: &lt;strong&gt;elasticsearch-s3-bucket-snapshot&lt;/strong&gt; , other defaults are good - make sure you select " &lt;strong&gt;Block all public access&lt;/strong&gt;" and then go ahead with creating the bucket (or saving)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-1.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Enter a bucket name: &lt;strong&gt;elasticsearch-s3-bucket-snapshot&lt;/strong&gt;, other defaults are good - make sure you select "&lt;strong&gt;Block all public access&lt;/strong&gt;" &lt;/p&gt;

&lt;h3&gt;
  
  
  Create an AWS policy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open AWS Console -&amp;gt; &lt;a href="https://console.aws.amazon.com/iam" rel="noopener noreferrer"&gt;IAM&lt;/a&gt; -&amp;gt; Policies &lt;/li&gt;
&lt;li&gt;Click on "Create Policy"&lt;/li&gt;
&lt;li&gt;Switch to JSON editor and paste the following policy (that Elasticsearch &lt;a href="https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-repository.html#repository-s3-permissions" rel="noopener noreferrer"&gt;recommends for S3 permissions&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Statement": [
    {
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads",
        "s3:ListBucketVersions"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com"
      ]
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com/*"
      ]
    }
  ],
  "Version": "2012-10-17"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-2.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on "Next: Tags", tags can be default so click next again&lt;/li&gt;
&lt;li&gt;Enter a policy name &lt;strong&gt;elasticsearch-s3-policy-snapshot&lt;/strong&gt; and hit " &lt;strong&gt;Create policy&lt;/strong&gt;"
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-3.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Enter a policy name &lt;strong&gt;elasticsearch-s3-policy-snapshot&lt;/strong&gt; and hit "&lt;strong&gt;Create policy&lt;/strong&gt;"&lt;/p&gt;

&lt;h3&gt;
  
  
  Create an IAM User
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open AWS Console -&amp;gt; &lt;a href="https://console.aws.amazon.com/iam" rel="noopener noreferrer"&gt;IAM&lt;/a&gt;-&amp;gt; Access Management -&amp;gt; Users&lt;/li&gt;
&lt;li&gt;Click on "Add Users"&lt;/li&gt;
&lt;li&gt;Enter an user name elasticsearch-s3-user (customizable), check &lt;strong&gt;Programmatic access&lt;/strong&gt; and click &lt;strong&gt;Next: Permissions&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-4.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Enter an user name elasticsearch-s3-user (customizable), check &lt;strong&gt;Programmatic access &lt;/strong&gt;and click Next: Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch to " &lt;strong&gt;Attach existing policies directly&lt;/strong&gt;" , search and select " &lt;strong&gt;elasticsearch-s3-policy-snapshot"&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-5.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click " &lt;strong&gt;Next: Tags&lt;/strong&gt;", defaults are fine. Review the details and click Create User.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-6.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Review screen for Elasticsearch IAM user&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This will generate a "Access Key ID" and "Secret access key" - both of which we will need soon to setup repository in Kibana, so keep them handy. There's a CSV option to download.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-7.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Credentials for IAM User&lt;/p&gt;

&lt;h3&gt;
  
  
  Install the S3 Repository Plugin
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On your machine or server, go to where the Elasticsearch bin folder is. Mine was at /usr/share/elasticsearch&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;sudo bin/elasticsearch-plugin install repository-s3&lt;/code&gt;, answer with y or Y when asked about permissions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restart your cluster!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;We will &lt;a href="https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-client.html" rel="noopener noreferrer"&gt;configure the client settins for the plugin&lt;/a&gt;. Using &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.14/elasticsearch-keystore.html" rel="noopener noreferrer"&gt;elasticsearch-keystore&lt;/a&gt;, set the credentials for your IAM User
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/elasticsearch-keystore add s3.client.default.access_key
# enter your "Access Key ID", hit enter
bin/elasticsearch-keystore add s3.client.default.access_key
# enter your "Secret Access Key", hit enter

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Register the repository with Kibana
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to your Kibana dashboard -&amp;gt; Management -&amp;gt; Stack Management -&amp;gt; Snapshot &amp;amp; Restore -&amp;gt; Repositories -&amp;gt;  " &lt;strong&gt;Register a repository&lt;/strong&gt;"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-8.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Snapshot &amp;amp; Restore on Kibana&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name it as &lt;strong&gt;elasticsearch-repository-snapshot&lt;/strong&gt; , select AWS S3 as repository type, click Next. If you don't see AWS S3, make sure you restarted your cluster!
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-9.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Repository name &amp;amp; Type&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client name is &lt;strong&gt;default&lt;/strong&gt; (this is part of your keystore secrets s3.client. &lt;strong&gt;default&lt;/strong&gt;.access_key) and your S3 Bucket Name. Review other defaults and hit Register.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-11.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Repository client name &amp;amp; S3 Bucket name&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once this is done, it pops up a details screen for the repository. Click on &lt;strong&gt;Verify repository&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-12.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Verify Repository to make sure everything is good&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup an automatic policy with Kibana
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On the same screen, switch to &lt;strong&gt;Policies&lt;/strong&gt; -&amp;gt; Create Policy
&amp;lt;!--kg-card-begin: markdown--&amp;gt;&lt;/li&gt;
&lt;li&gt;Enter these details

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;elasticsearch-weekly-snapshot&lt;/strong&gt; as the name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; as the snapshot name, appends the date at the end&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;elasticsearch-repository-snapshot&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set frequency to every week&lt;/li&gt;
&lt;li&gt;Click Next
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-13.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Details for Policy - Cron&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click Next, and on review screen, hit Create Policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-14.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Review Policy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can run the policy and when it's done, you will see the snapshot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-15.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;Run now for the policy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should see something like this once snapshot is complete
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fadithya.dev%2Fcontent%2Fimages%2F2021%2F08%2Fimage-16.png" alt="S3 Snapshots for Elasticsearch via Kibana"&gt;&lt;/a&gt;snapshot is complete&lt;/p&gt;

</description>
      <category>indexing</category>
      <category>elasticsearch</category>
    </item>
    <item>
      <title>Use localized datetime from Carbon in Laravel</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Sun, 22 Aug 2021 20:20:55 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/use-localized-datetime-from-carbon-in-laravel-3jgk</link>
      <guid>https://forem.com/adithyasrinivasan/use-localized-datetime-from-carbon-in-laravel-3jgk</guid>
      <description>&lt;p&gt;I've been using this great package &lt;a href="https://github.com/mcamara/laravel-localization"&gt;laravel-localization&lt;/a&gt; for translations. I noticed a minor issue with how datetime is resolved for locales in Laravel. The default &lt;code&gt;format($dateTimeFormat)&lt;/code&gt; wasn't kicking it and a look at documentation reveals that if you use Carbon\Carbon 2, there are more helper methods to make this easier. Using &lt;code&gt;isoFormat($dateTimeFormat)&lt;/code&gt; takes locale into consideration.&lt;/p&gt;

&lt;p&gt;You also may know &lt;code&gt;formatLocalized()&lt;/code&gt; method from Carbon 1. This method still works the same in Carbon 2 but you should better use &lt;code&gt;isoFormat()&lt;/code&gt; instead. It does mean that you might have change all your existing method calls to a new format but it's a much cleaner, neater solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-&amp;gt;isoFormat(string $format): string&lt;/code&gt; use ISO format rather than PHP-specific format and use inner translations rather than language packages you need to install on every machine where you deploy your application. &lt;code&gt;isoFormat&lt;/code&gt; method is compatible with &lt;a href="https://momentjs.com/"&gt;momentjs format method&lt;/a&gt;, it means you can use same format strings as you may have used in moment from front-end or node.js. Here are some examples:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Official documentation here: &lt;a href="https://carbon.nesbot.com/docs/#api-localization"&gt;https://carbon.nesbot.com/docs/#api-localization&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Adding Scopes to Laravel Scout Queries</title>
      <dc:creator>adithyasrinivasan</dc:creator>
      <pubDate>Fri, 16 Jul 2021 19:09:12 +0000</pubDate>
      <link>https://forem.com/adithyasrinivasan/adding-scopes-to-laravel-scout-queries-4h0</link>
      <guid>https://forem.com/adithyasrinivasan/adding-scopes-to-laravel-scout-queries-4h0</guid>
      <description>&lt;p&gt;I included a new section for &lt;a href="https://arbeitnow.com/four-day-week-jobs"&gt;four day work week jobs&lt;/a&gt; and when building the logic for that, I wanted to make use of scopes that are present in the eloquent model. I use &lt;a href="https://laravel.com/docs/master/scout"&gt;Laravel Scout&lt;/a&gt; to offload some of the work.&lt;/p&gt;

&lt;p&gt;Scope &lt;code&gt;scopeIsPublished&lt;/code&gt; has an easy boolean check against the database like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

//model definition

 public function scopeIsPublished($query)
 {
   return $query-&amp;gt;where('is_published', true);
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Scout, I wanted to include this when a user searches for a job. So naturally, this was what I ended up with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

//logic
$query = Jobs::search('search text')
            -&amp;gt;onlyPublished()
            -&amp;gt;otherConditions();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was surprised when the results were unfiltered so I looked a little into the support for scopes in Laravel Scout. On the model instance, ScoutBuilder exposes a handy callback for &lt;code&gt;query&lt;/code&gt; so you can use it like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

//logic
$query = Jobs::search('search text')
            -&amp;gt;query(function ($query){
                return $query-&amp;gt;onlyPublished();
            })
            -&amp;gt;otherConditions();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helped get the expected results and should work with all providers Algolia, Elasticsearch, Meilisearch, etc.&lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
  </channel>
</rss>
