megacolorboy

Abdush Shakoor's Weblog

Writings, experiments & ideas.

Create a unique multidimensional array using a key index

Let's say, you have a multidimensional array like this:

<?php
$cars = [
    [
        "id" => 1,
        "name" => "Mercedes Benz",
        "color" => "Black"
    ],
    [
        "id" => 2,
        "name" => "Toyota",
        "color" => "Red"
    ],
    [
        "id" => 3,
        "name" => "Toyota",
        "color" => "White"
    ],
    [
        "id" => 4,
        "name" => "Nissan",
        "color" => "Grey"
    ],
];
?>

And say, you want to be able to return unique cars by name or color, use this method:

<?php
function multi_array_unique($array, $key) {
    $i = 0;
    $temp_array = [];
    $key_array = [];

    foreach($array as $val) {
        // insert only unique keys
        if (!in_array($val[$key], $key_array)) {
            $key_array[$i] = $val[$key];
            $temp_array[$i] = $val;
        }
        $i++;
    }
    return $temp_array;
}
?>

Call this method from anywhere in your code like this:

<?php
$unique_cars = multi_array_unique($cars, "name");
dd($unique_cars);
?>

And now, you'll get something like this:

<?php
[
    [
        "id" => 1,
        "name" => "Mercedes Benz",
        "color" => "Black"
    ],
    [
        "id" => 2,
        "name" => "Toyota",
        "color" => "Red"
    ],
    [
        "id" => 4,
        "name" => "Nissan",
        "color" => "Grey"
    ],
];
?>

You might wonder why I tried this instead of PHP's array_unique() method and the reason I didn't use it is because it doesn't support multidimensional arrays.

Hope you found this useful!

Extract YouTube Channel ID from URL

Using PHP's in-built function, parse_url, you can write a helper method to pull the channel ID off a YouTube URL especially if you're pulling videos using YouTube's Data API. Here's the code:

<?php
public function extractChannelID($url){
    // Parse the link and trim any whitespaces
    $parsed_link = parse_url(rtrim($url, '/'));

    // Return the channel ID if it matches the pattern
    if (isset($parsed_link['path']) && preg_match('/^\/channel\/(([^\/])+?)$/', $parsed_link['path'], $matches)) {
        return $matches[1];
    }

    throw new Exception("This {$url} is not a valid YouTube channel URL");
    return null;
}
?>

Writing tiny methods like these can help save time and be reusable in more than one context.

Hope you find this tip useful! ๐Ÿ˜

Using zipcloak to encrypt files within an archive

Whenever you're sending a bunch of files or an archive that contains sensitive or confidential information, it's wise to encrypt before you send it to the person that you intend to.

Using zipcloak, you'll be able to encrypt files within your existing archive.

Do the following after you've created a zip archive:

zipcloak files.zip    

Now, you'll be prompted twice to enter a new password and verify your entered password. If they match, your archive will get encrypted. So whenever, you try to unzip or open using an Archive Manager, you'll be prompted to enter the password or else, you won't be able to access it.

You also have the choice of not encrypting the original archive and creating a new one instead, just like this:

zipcloak files.zip -O encrypted.zip    

On the other hand, if you do wish to remove the encryption from your archive, just type the following:

zipcloak -d files.zip

And you'll be prompted again to enter your password before it removes it's encryption.

Hope this helps you out! ๐Ÿ˜

How to cache your queries on your Laravel application?

Although, Laravel is a good framework, it's quite heavy when it comes to executing queries especially if you're using the Eloquent ORM instead of the normal query builder.

But Laravel does offer the option of caching your queries in the server and will only make calls to your database if there's a change in content.

Quite handy when you're having a content-heavy website and huge amount of user traffic.

Using the Cache class, you can cache your queries like this:

<?php
$apples = \Cache::rememberForever('apples_cache', function(){
    return FruitsModel::where('item_name', 'LIKE', '%apples')
        ->get();
});
?>

In the above example, apples_cache is the key that stores your queries of apples forever and which will be used to obtain your cached results from the server.

Oh, be sure to create distinctive names for different types of queries or else, you'll end up being confused! ๐Ÿ˜œ

You can also give it a time limit in milliseconds:

<?php
$apples = \Cache::remember('apples_cache', 300000, function(){
    return FruitsModel::where('item_name', 'LIKE', '%apples')
        ->get();
});
?>

Hope this tip helps you out! ๐Ÿ˜€

Looping infinitely around an array

Sometimes, I find myself in a situation where I might have a fixed array of colors, text, numbers or something like that but I want to loop around infinitely like a carousel.

Let's say we have an array like this:

var colors = ["#111", "#222", "#333"];

The code is an array of three colors that we want to apply to, hmmm, say a list of HTML DOM elements like <div> containers or any element that you prefer. In this example, we'll add some colors to a bunch of <div> elements that has the classname .card or we'll just call them "cards".

Behold, the Modulus operator!

You may think of writing different conditions or loops to achieve a solution but a more elegant one is by using the Modulus operator a.k.a the Remainder operator (%). Using this operator gives you the remainder after the division of a number.

Hmm, confused? Okay, here's a simple example of how a Modulus operator would be like:

In plain english, if you have 10 apples and you divide them by 4 and by doing so, you'll end up with 2 sets of 4 apples and the remaining set would be 2 apples. Thus, the remainder is 2.

Did that make sense? If not, then try the following code in your browser:

var x = 10 % 4;
console.log(x); // output will be 2

Let's say we have 10 "cards" and we want every 3 three cards to have 3 different colors, we must just define a way to determine the index of each color while iterating through a loop of cards. So, we can easily get the index by doing so:

var currentColor = colors[i % colors.length-1];

Here's the full code:

var elements = document.querySelectorAll('.card');
for(var i=0; i<elements.length; i++){
    var currentColor = colors[i % colors.length-1];
    elements[i].style.backgroundColor = currentColor;
}

The following code will apply the colors to each "card" with respect to it's order and will reset back to the first color once it's reached it's last color based on the remainder of the next iteration in the loop.

Read about Modulus Operation to know more about it.

Enable HTTP Strict Transport Security (HSTS)

As part of a project that I was working on, I learnt about HTTP Strict Transport Security protocol which tells the browser about making future web requests over HTTPS only. So, even if you attempt to use http://, the browser will force you to use https:// URLs in the future.

You can enable it by writing this header in your .htaccess file in your public directory:

Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS

Please note that once you enable this protocol, your web application is committed to using SSL i.e. you won't be able to use insecure HTTP for your web application.

Forcing HTTP to HTTPS redirect after enabling SSL

You can manually force HTTP to HTTPS after enabling your SSL certificate by adding the following condition at the beginning of your .htaccess file in your public directory:

RewriteCond %{HTTP:X-Forward-Proto} !=https
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Save your file and restart your Apache server and now, your web application will redirect all your users to https:// instead of http:// URLs in the future.

Enable copy-paste clipboard in URxvt Terminal Emulator

In my current Arch Linux installation, I decided to use a window manager called i3. It's really awesome and it comes with a really lightweight terminal emulator called urxvt. It's very minimal and I lked it but when I tried to copy-paste text from one terminal to another, I wasn't able to.

However, thanks to the internet, I did some research and figured a way out.

1. Install xClip

First, you need to ensure that you have installed the xclip package, which will be used to copy-paste text in the emulator.

Type the following command to install the package:

pacman -S xclip

2. Activate Clipboard using Perl

Now, you have to paste these custom commands into your clipboard file, which is found in /usr/lib/urxvt/perl directory:

# paste selection from clipboard
sub paste {
     my ($self) = @_;
     my $content = `/usr/bin/xclip -loop 1 -out -selection clipboard` ;
     $self->tt_write ($content);
}

# copy text to clipbard on selection
sub on_sel_grab {
     my $query = $_[0]->selection;
     open (my $pipe, '| /usr/bin/xclip -in -selection clipboard') or die;
     print $pipe $query;
     close $pipe;
 }

3. Modify your .Xresources

Add these keybindings to your .Xresources file:

URxvt.keysym.Shift-Control-V: perl:clipboard:paste
URxvt.iso14755: False
URxvt.perl-ext-common: default,clipboard

After adding it, refresh your .Xresources settings:

xrdb -merge .Xresources

Reboot your terminal and try selecting some text from your terminal using your mouse and paste it using Ctrl+Shift+V and it should work!

That's it! Enjoy ๐Ÿ˜ƒ