3

Running into a brick wall here with Query String/Parameter building, I have a feeling it shouldn't be this complicated but wanted to get best practice advice.

I am currently building a community platform that allows/requires users to tag their content. The content is tagged via two query string parameters.

Please note all relationships, tagging logic for posts including attaching/detaching is done, this is purely a filter system issue.

Category - posts must have a category but only one category, on searching the query string would be appended as such. Eg. ?category=plants

Tags - posts can have (optionally) many tags, this would append to the query string as such. Eg. ?tags=hardy

So far. I have created two functions (through a helper.php file) that "add_query_params" and "remove_query_params". These are helpful as it allows me to add and remove either ?category or ?tag without removing the other. MY PROBLEM is that I can not for the life of me seem to work out how to add MULTIPLE of the same tag to the query string to allow me to filter on MULTIPLE parameter options!

For example

I can build

website.com?category=plants&tags=hardy 

// I can also remove either tag without affecting the other

I cannot build


.com?category=plants&tags=hardy&tags=perenial
// (I can't add two of the same tag to the query string to allow me to filter on these in the controller/request

My functions that allow me to add/remove tags are as follows


/**
 * URL before:
 * https://example.com/orders/123?order=ABC009&status=shipped
 *
 * 1. remove_query_params(['status'])
 * 2. remove_query_params(['status', 'order'])
 *
 * URL after:
 * 1. https://example.com/orders/123?order=ABC009
 * 2. https://example.com/orders/123
 */
function remove_query_params(array $params = [])
{
    $url = url()->current(); // get the base URL - everything to the left of the "?"
    $query = request()->query(); // get the query parameters (what follows the "?")

    foreach($params as $param) {
        unset($query[$param]); // loop through the array of parameters we wish to remove and unset the parameter from the query array
    }

    return $query ? $url . '?' . http_build_query($query) : $url; // rebuild the URL with the remaining parameters, don't append the "?" if there aren't any query parameters left
}

/**
 * URL before:
 * https://example.com/orders/123?order=ABC009
 *
 * 1. add_query_params(['status' => 'shipped'])
 * 2. add_query_params(['status' => 'shipped', 'coupon' => 'CCC2019'])
 *
 * URL after:
 * 1. https://example.com/orders/123?order=ABC009&status=shipped
 * 2. https://example.com/orders/123?order=ABC009&status=shipped&coupon=CCC2019
 */
function add_query_params(array $params = [])
{

    $query = array_merge(
        request()->query(),
        $params
    ); // merge the existing query parameters with the ones we want to add


    return url()->current() . '?' . http_build_query($query); // rebuild the URL with the new parameters array
}


And in the blade comment they would be called like so

//Add query param
<a href="{{add_query_params(['tags' => $tag->id]) }}"
                class="inline-block bg-gray-100  px-3 py-1 text-xs uppercase font-button">
                #{{$tag->name}}
</a>


//Remove query param
<a href="{{remove_query_params(['category']) }}"
                class="inline-block bg-gray-300  px-3 py-1 text-xs uppercase font-button">
                #{{$has_category->name}}
                            
 </a>

It's driving me bonkers, most sites, e-commerce, travel sites allow you to update the query string and this approach I felt was the easiest to be called from anywhere in the site and agnostic from being tied down to a particular page, function, it also makes the builder extensible and reusable for more tags.

But I just can't work it out.

Anybody have any tips or direction on how to add multiple tags to the query string????

Cheers

2
  • In PHP query string arrays follow syntax tags[]=tag1&tags[]=tag2 and laravel does work with this, or you can pass them as comma separated e.g. tags=tag1,tag2 and split them in code. That's it though, there may be other hacky ways to do it the way you're trying, but just use the tools PHP and Laravel offers Commented Oct 7, 2020 at 11:13
  • Why didn't you add tags like this way: &tags=one,two,three and explode them by comma? Commented Oct 7, 2020 at 11:15

2 Answers 2

1

You can try this:
.com?category=plants&tags=hardy,perenial.
Get tags in controller from query string as an array via
$tags = explode(',', request()->tags);

function for adding tags:

add_query_params(array $params = [])    {        
    // defining parameters being used in requests
    $tags = request()->tags;

    // param key (name) and its value being added
    $param = null
    $value = null;
    foreach($params as $key => $value){
        $param = $key;
        $value = $val;
    }

    // merging new ones
    switch ($key) {
        case 'tags':
            array_push($tags, $value)
            break;
        case 'some other param':
            // push value to array, like tags case
            break;
        default:
            break;
     }

     $query = array_merge(request()->query(),$tags);
     return http_build_query($query); 
     // rebuild the URL with the new parameters array 
} 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you. This is exactly what I am looking for. I am just struggling to work out how to construct the query string like this. So I am trying to work out how I would update this function. function add_query_params(array $params = []) { $query = array_merge( request()->query(), $params ); return url()->current() . '?' . http_build_query($query); // rebuild the URL with the new parameters array } and this action add_query_params(['tags' => $tag->id])
if you have a variable being passed to view, you can try $variable->appends(request()->all()), it should append your parameters from previous request
@AdamCatlow here is a snippet collabedit.com/jsdhu
this is great. Thank you very much, it's really helped point me in the right direction! :D
1

You can not do that. It's like you have a variable reassigned a new value. The old one will be lost.

What you can do is pass a comma-separated string like:

tags=test1,test2,test3

as values in your query param. Then use explode() function to make an array out of it and use the values.

Another idea is that your query parameter is created as an array so you should have something like:

tags[]=test1&tags[]=test2&tags[]=test3

That way when you request the parameter tags you already have an array in place to use and is closed to your first approach.

So you actually insert new values inside array tags

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.