<?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>DEV Community: Graffino</title>
    <description>The latest articles on DEV Community by Graffino (@graffino).</description>
    <link>https://dev.to/graffino</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%2Forganization%2Fprofile_image%2F963%2F0dcd1ba4-2f76-4430-b423-c38f0d6604f6.png</url>
      <title>DEV Community: Graffino</title>
      <link>https://dev.to/graffino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/graffino"/>
    <language>en</language>
    <item>
      <title>Enhancing Laravel Commands: Parameterized Inputs and Custom Output Formats [4/4]</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Fri, 26 May 2023 13:02:17 +0000</pubDate>
      <link>https://dev.to/graffino/enhancing-laravel-commands-parameterized-inputs-and-custom-output-formats-4ebl</link>
      <guid>https://dev.to/graffino/enhancing-laravel-commands-parameterized-inputs-and-custom-output-formats-4ebl</guid>
      <description>&lt;p&gt;So far, so good. It gives us some insights into the current state of our gating system, but not much more. Since we've come this far, we might as well take one step further and incorporate two crucial aspects of commands: the ability to pass parameters. Once we have this functionality in place, the console kernel becomes equally powerful as the web kernel, granting access to all infrastructure and data layers, just as you would normally have.&lt;/p&gt;

&lt;p&gt;What we do is pass a username to the command and then examine each gate for the retrieved user. We mark, in an additional column, whether the user can pass it or not, indicating a green "pass" or a red "restricted".&lt;/p&gt;

&lt;p&gt;Try to and identify the new code additions. I’ll give you a hint: start with the command signature. Feel free to comment if you have any questions. And, most importantly, have fun!&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

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Auth\Access\Gate;
use App\Models\User;

class CheckGates extends Command
{
    protected $signature = 'gate:check {username}';
    protected $description = 'Check access of user for all defined gates in Laravel';

    protected $gate;

    public function __construct(Gate $gate)
    {
        parent::__construct();
        $this-&amp;gt;gate = $gate;
    }
    protected function getClosureContents(\Closure $closure)
    {
        $reflection = new \ReflectionFunction($closure);
        $closureCode = file($reflection-&amp;gt;getFileName());

        $startLine = $reflection-&amp;gt;getStartLine();
        $endLine = $reflection-&amp;gt;getEndLine();

        $contents = array_slice($closureCode, $startLine - 1, $endLine - $startLine + 1);

        return implode('', $contents);
    }
    public function handle()
    {
        $username = $this-&amp;gt;argument('username');
        $user = User::where('username', $username)-&amp;gt;first();

        if (!$user) {
            $this-&amp;gt;error("No user found with username: $username");
            return;
        }

        $gates = $this-&amp;gt;gate-&amp;gt;abilities();
        $self = $this;

        $tableData = array_reduce(array_keys($gates), function ($carry, $key) use ($gates, $user, $self) {
            $value = $gates[$key];
            $hasAccess = $this-&amp;gt;gate-&amp;gt;forUser($user)-&amp;gt;check($key);

            $carry[] = [
                'Gate Name' =&amp;gt; $key,
                'Access' =&amp;gt; $hasAccess ? '&amp;lt;fg=green&amp;gt;Pass&amp;lt;/&amp;gt;' : '&amp;lt;fg=red&amp;gt;Restricted&amp;lt;/&amp;gt;',
                'Closure Contents' =&amp;gt; $self-&amp;gt;getClosureContents($value),
            ];

            return $carry;
        }, []);

        $this-&amp;gt;table(['Gate Name','Access', 'Closure Contents'], $tableData);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>php</category>
      <category>laravel</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Create a Laravel Command to Display All Authorization Gates Similar to route:list [3/4]</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Fri, 26 May 2023 12:56:36 +0000</pubDate>
      <link>https://dev.to/graffino/create-a-laravel-command-to-display-all-authorization-gates-similar-to-routelist-34-3558</link>
      <guid>https://dev.to/graffino/create-a-laravel-command-to-display-all-authorization-gates-similar-to-routelist-34-3558</guid>
      <description>&lt;p&gt;Create the ListGates command file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new file called &lt;code&gt;ListGates.php&lt;/code&gt; inside the &lt;code&gt;app/Console/Commands&lt;/code&gt; directory of your Laravel project.&lt;/li&gt;
&lt;li&gt;Place the following code inside the &lt;code&gt;ListGates.php&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ul&gt;

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

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Auth\Access\Gate;

class ListGates extends Command
{
    protected $signature = 'gate:list';
    protected $description = 'List all defined gates in Laravel';

    protected $gate;

    public function __construct(Gate $gate)
    {
        parent::__construct();
        $this-&amp;gt;gate = $gate;
    }

    protected function getClosureContents(\Closure $closure)
    {
        $reflection = new \ReflectionFunction($closure);
        $closureCode = file($reflection-&amp;gt;getFileName());

        $startLine = $reflection-&amp;gt;getStartLine();
        $endLine = $reflection-&amp;gt;getEndLine();

        $contents = array_slice($closureCode, $startLine - 1, $endLine - $startLine + 1);

        return implode('', $contents);
    }

    public function handle()
    {
        $gates = $this-&amp;gt;gate-&amp;gt;abilities();
        $self = $this;

        $tableData = array_reduce(array_keys($gates), function ($carry, $key) use ($gates, $self) {
            $value = $gates[$key];

            $carry[] = [
                'Gate Name' =&amp;gt; $key,
                'Closure Contents' =&amp;gt; $self-&amp;gt;getClosureContents($value),
            ];

            return $carry;
        }, []);

        $this-&amp;gt;table(['Gate Name', 'Closure Contents'], $tableData);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only additional task we need to perform is formatting the gates array in a structure suitable for the table format expected by the &lt;code&gt;table&lt;/code&gt; method of the Command class. Laravel provides a range of convenient methods for CLI output formatting with the Symphony Console component, making this process much easier.&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

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    // ...

    protected $commands = [
        // Other commands...
        \App\Console\Commands\ListGates::class,
    ];

    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can run the gates:list command from your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan gate:list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And get this beautiful table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---------------+----------------------------------------------------------+
| Gate Name     | Closure Contents                                         |
+---------------+----------------------------------------------------------+
| viewHorizon   |         Gate::define('viewHorizon', function ($user) {   |
|               |             return in_array($user-&amp;gt;email, [              |
|               |                 //                                       |
|               |             ]);                                          |
|               |         });                                              |
|               |                                                          |
| viewTelescope |         Gate::define('viewTelescope', function ($user) { |
|               |             return in_array($user-&amp;gt;email, [              |
|               |                 //                                       |
|               |             ]);                                          |
|               |         });                                              |
|               |                                                          |
+---------------+----------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>laravel</category>
      <category>webdev</category>
      <category>php</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to use the PHP Reflection API for Inspecting Closure Contents [2/4]</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Fri, 26 May 2023 12:53:52 +0000</pubDate>
      <link>https://dev.to/graffino/how-to-use-the-php-reflection-api-for-inspecting-closure-contents-24-1bo7</link>
      <guid>https://dev.to/graffino/how-to-use-the-php-reflection-api-for-inspecting-closure-contents-24-1bo7</guid>
      <description>&lt;p&gt;The Reflection API in PHP is a set of classes that allow you to introspect your code. It provides the ability to retrieve detailed information about classes, methods, properties, and functions at runtime, such as their names, parameters, and modifiers (like public, private, protected), among other things. It's commonly used for advanced tasks like building development tools, debuggers, or components for a dependency injection container.&lt;/p&gt;

&lt;p&gt;Closures (or anonymous functions) in PHP are considered "black boxes" because they encapsulate their behavior and environment when defined. This means that their internal variables and code can't be directly accessed or inspected from the outside like regular variables - you can only interact with them through their inputs and outputs. When you try to dump a closure with &lt;code&gt;var_dump()&lt;/code&gt;, &lt;code&gt;print_r()&lt;/code&gt;, or Laravel's &lt;code&gt;dd()&lt;/code&gt;, you don't see the actual PHP code inside the closure. This is why you need tools like the Reflection API to inspect their contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$getClosureContents = function(\Closure $closure)
{
    $reflection = new ReflectionFunction($closure);
    $closureCode = file($reflection-&amp;gt;getFileName());

    $startLine = $reflection-&amp;gt;getStartLine();
    $endLine = $reflection-&amp;gt;getEndLine();

    $contents = array_slice($closureCode, $startLine - 1, $endLine - $startLine + 1);

    return implode('', $contents);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we're doing here is pretty simple: We find the exact PHP file that has the closure, read the content of this file, get all the lines from the start to the end, and put the function back together as a multiline string. But this process would not be possible without the useful features of PHP's Reflection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$closureContents = array_map($getClosureContents, $gates);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will put out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
     "viewHorizon" =&amp;gt; """
               Gate::define('viewHorizon', function ($user) {\n
                   return in_array($user-&amp;gt;email, [\n
                       //\n
                   ]);\n
               });\n
       """,
     "viewTelescope" =&amp;gt; """
               Gate::define('viewTelescope', function ($user) {\n
                   return in_array($user-&amp;gt;email, [\n
                       //\n
                   ]);\n
               });\n
       """,
   ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are able to: &lt;a href="https://dev.to/graffino/create-a-laravel-command-to-display-all-authorization-gates-similar-to-routelist-34-3558"&gt;Create a Laravel Command to Display All Authorization Gates Similar to route:list&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>api</category>
      <category>php</category>
    </item>
    <item>
      <title>How to List All Authorization Gates in Your Laravel Application [1/4]</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Fri, 26 May 2023 12:50:25 +0000</pubDate>
      <link>https://dev.to/graffino/how-to-list-all-authorization-gates-in-your-laravel-application-14-4i12</link>
      <guid>https://dev.to/graffino/how-to-list-all-authorization-gates-in-your-laravel-application-14-4i12</guid>
      <description>&lt;p&gt;While Laravel doesn't provide an Artisan command specifically for listing gates, there's a valid reason for this. The need to inspect these gates doesn't arise frequently. If such a situation does occur, you can rely on the ol’ debugging tools.&lt;/p&gt;

&lt;p&gt;But for now I need to put together something quick and explore my options. That’s a job for the tinker command  which allows us to evaluate PHP and Laravel code on-the-fly and see the results immediately, which can be incredibly useful in our scenario. &lt;/p&gt;

&lt;p&gt;When it comes to what you can do with the Gates class,  although the available methods are not explicitly exposed in the official Laravel documentation, contracts and facades serve as excellent sources of documentation for what you can accomplish with them.&lt;/p&gt;

&lt;p&gt;Here, I am retrieving all the defined abilities and listing their names to provide a quick overview.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Illuminate\Contracts\Auth\Access\Gate;

$gates = app(Gate::class)-&amp;gt;abilities();
echo implode("\n", array_keys($gates));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the abilities method gives us is an associative array with key names and the corresponding closures - because that's how gate-based authorization works in Laravel. Gates provide a simple, Closure (a type of anonymous function in PHP) based approach to authorization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  "viewHorizon" =&amp;gt; Closure($user) {#446 …4},
  "viewTelescope" =&amp;gt; Closure($user) {#449 …4},
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, we'll output a list with all their names. Helpful? A bit, yes - I can now at least know what to search for and inspect in my codebase. Should we be able to take a quick look at the contents as well? Well, the whole closure aspect of it requires some extra tinkering before we can look under their hood.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>Boolean flip helper for Elm</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Fri, 15 May 2020 07:19:53 +0000</pubDate>
      <link>https://dev.to/graffino/boolean-flip-helper-for-elm-4a9o</link>
      <guid>https://dev.to/graffino/boolean-flip-helper-for-elm-4a9o</guid>
      <description>&lt;p&gt;There is no such thing as !True to get a False value in Elm.&lt;/p&gt;

&lt;p&gt;Here's how I do it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Helpers.Bool exposing (flip)

flip: Bool -&amp;gt; Bool
flip bool = 
    if bool == True then
    False
  else
    True
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Helpers.Bool

...

Helpers.Bool.flip True
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For more: &lt;a href="https://graffino.com/til/"&gt;Today I Learned&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elm</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ruby's .times in JavaScript</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Wed, 11 Dec 2019 09:58:33 +0000</pubDate>
      <link>https://dev.to/graffino/ruby-s-times-in-javascript-1ok5</link>
      <guid>https://dev.to/graffino/ruby-s-times-in-javascript-1ok5</guid>
      <description>&lt;p&gt;Never modify JavaScript's standard built-in objects. That's what they &lt;a href="https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice#answer-14034242"&gt;say&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But just for fun, let's see how Ruby's &lt;a href="https://ruby-doc.org/core-2.2.2/Integer.html#times-method"&gt;.times&lt;/a&gt; would look like in JavaScript.&lt;/p&gt;

&lt;p&gt;Here's how we do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String.prototype.times = function (n) {
    for (var i = 0; i &amp;lt; parseInt(this); i++) {
        n();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var myFunc = function () { console.log('Hello World') }
"2".times(myFunc)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Hello World"
"Hello World"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;nickciolpan&lt;br&gt;
29 May 2018&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
      <category>loops</category>
      <category>objectprototype</category>
    </item>
    <item>
      <title>You can write better jQuery</title>
      <dc:creator>Nick Ciolpan</dc:creator>
      <pubDate>Tue, 23 Jul 2019 12:43:22 +0000</pubDate>
      <link>https://dev.to/graffino/you-can-write-better-jquery-38f3</link>
      <guid>https://dev.to/graffino/you-can-write-better-jquery-38f3</guid>
      <description>&lt;p&gt;While almost every new article mentioning it, talks about its demise, I’ve decided to write as about one of the most recurrent jQuery bad practices I came across and how to deal with it. Here it is:&lt;/p&gt;

&lt;h4&gt;
  
  
  Going from this:
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
$('.multiSelectOne').multiselect({
    buttonClass: 'btn btn-default',
    buttonWidth: '100%',
    ...
});
$('.multiSelectTwo').multiselect({
    buttonClass: 'btn btn-default',
    buttonWidth: '100%',
    nonSelectedText: '---',
    ...
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  To This:
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;select class="js-multiselect" 
    data-include-select-all-option="true" 
    data-all-selected-text="All"&amp;gt;
    &amp;lt;option&amp;gt;&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;

$('.js-multi-select).each(function () {
    let options = {};

    Object.entries($(this).data())
        .map(property =&amp;gt; options[property[0]] = property[1]);

  $(this).multiselect(options);

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;And never go back for adjustments in the script file ever again.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>jquery</category>
      <category>dry</category>
    </item>
  </channel>
</rss>
