Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

best way to run string functions over returned database object

I need to run various string functions over the data returned from the database before I send it to the view using Laravel 5.3. Basic stuff like str_replace().

Now maybe there's a good way to setup Accessors on my model and somehow use the model on the landing page but I thought I would go a different route and just do this one query manually outside of the model.

So I have a view provider that successfully gets my data into the view. It looks like this:

class ViewLandingProvider extends ServiceProvider {
   public function boot() {
    // process when featured homepage element is present...
    View::composer('mybladetemplate', function ($view){

        $featuredProperties = DB::table('properties')
            ->where([
                ['featured_property', '=', '1'],
                ['supplier_id', '=', 123],
            ])
            ->orderBy('prop_id', 'desc')
            ->limit(6)
            ->get();

        // run str_replace!
        $featuredProperties->each(function($property){
            $property->prop_url=str_replace("http://domain.com/","http://www.domain.com/",$property->prop_url);
        });

        View::share('featuredProperties', $featuredProperties);
    });
  }
}

this then loops within a view and it all works nicely

 @if(isset($featuredProperties))
     @foreach ($featuredProperties as $property)
         <li>
             <a title="{{ $property->prop_name }}" href="{{ $property->prop_url }}"></a>
         </li>           
    @endforeach
@endif

As you can see in the example above, I have str_replace() running over the data collection using ->each() and that's working to let me do a simple string replacement that I need to undertake.

Being Laravel though, I'm sure there's some magic that could be pulled here to do this more intelligently.

So is there a way in the actual database request code that I can specify that a certain column to be returned should automatically have a function run over it ?

Just to clarify, I want to make these changes in the provider php rather than the view file and I want to do this outside of a model with Accessors.

like image 909
AdamJones Avatar asked Oct 26 '16 02:10

AdamJones


2 Answers

You can write select query as:

$featuredProperties = DB::table('properties')
    ->where([
        ['featured_property', '=', '1'],
        ['supplier_id', '=', 123],
    ])
    ->select('*', DB::raw("replace(prop_url, 'http://domain.com/', 'http://www.domain.com/') as new_prop_url"))
    ->orderBy('prop_id', 'desc')
    ->limit(6)
    ->get();

And then in your view, you can do as:

@if(isset($featuredProperties))
   @foreach ($featuredProperties as $property)
       <li>
           <a title="{{ $property->prop_name }}" href="{{ $property->new_prop_url }}"></a>
       </li>           
  @endforeach
@endif
like image 66
Amit Gupta Avatar answered Sep 29 '22 02:09

Amit Gupta


I think you may be looking for a collection macro. You would register it in your AppServiceProvider like:

Collection::macro('formatPropUrl', function() {

    return collect($this->items)->map(function($property) {
        $property->prop_url=str_replace("http://domain.com/","http://www.domain.com/",$property->prop_url);

        return $property;
    });

});

Then for your query you could do:

$featuredProperties = DB::table('properties')
    ->where([
        ['featured_property', '=', '1'],
        ['supplier_id', '=', 123],
    ])
    ->orderBy('prop_id', 'desc')
    ->limit(6)
    ->get()
    ->formatPropUrl();
like image 31
Eric Tucker Avatar answered Sep 29 '22 02:09

Eric Tucker