Gabotronix

Gabotronix

Member Since 2 Years Ago

Experience Points
25,150
Total
Experience

4,850 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
45
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 6
25,150 XP
Mar
26
1 week ago
Activity icon

Started a new Conversation Question Regarding Promises And Then Catch

Hi everybody, when I click a button I fire a vuex action, this action returns an axios promise from the vuex store, in my component I want to reset form fileds ONLY when the action success, however right now it resets form fileds ALWAYS, even if the promise fails ... I'm using then and catch for this puropse, having the resetForm method fire in the then resolve, sadly it always resets no matter what...

This is the code in my component:

const self = this;
        

        this.sendContactMail(payload)
        .then((response) => {
            //This always fires, even if promise fails
            self.resetData();
        }, 
        (error) => {
            
        });

My vuex action:

sendContactMail({ commit }, payload)
    {        
        commit('Loader/SET_LOADER', { status:1 }, { root: true });
        return axios.post('/api/contacts/send-contact-mail', payload)
        .then((response) => {
            commit('Loader/SET_LOADER', { status:2, response: response }, { root: true });
        }, 
        (error) => {
            commit('Loader/SET_LOADER', { status:3, errors: error }, { root: true });
        });
    }
Activity icon

Started a new Conversation WhereMonth Failing To Retrieve Appointment Dates By Month

Hi everybody, I have two models in my application, Appointment and Date, an appointment has many dates and a date belongs to an appointment, now I want to search for appointments with dates which were created in a specific month, I do this by looking at appointments with dates, where this dates fullDate field is equal to the passed month, I use eloquent whereMonth for this.

Sadly the functions returns no results despite being results, I suspect this might be because Date model fullDate field is a string instead of a timestamp so maybe that's why it's failing, I tried casting fullDate to timestamp but I'm getting the same results.

fullDate is a string like this: "26-3-2020".

This is my controller method:

public function list2(Request $request)
    {
        $month = $request->input('month');

        $appointments = Appointment::whereHas('dates', function ($query) use ($month){
            $query->whereMonth('fullDate', $month);
        })->with(['user'])->latest()->paginate($request->input('paginate'));
		
        
    }

Date model migrations:

public function up()
    {
        Schema::create('dates', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('appointment_id')->index();
            $table->foreign('appointment_id')->references('id')->on('appointments')->onDelete('cascade')->onUpdate('cascade');
            $table->string('fullDate');//34-3-2020
            $table->timestamps();
        });
    }

Any idea why it's failing.

Mar
21
1 week ago
Activity icon

Started a new Conversation Make All Models Use Triat/Scope In Laravel

Hi, I have a laravel scope (I think these work as a trait basically) and I'd like all models to use it, currently I have to import the scope in all my models with use statement, is there a way to make all my models use it istead?

This is my scope:

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;

trait Filterable
{
    public function scopeFilter($query, QueryFilters $filters)
    {
        return $filters->apply($query);
    }
}
Activity icon

Started a new Conversation Validation In Controller Or Service Layer

I recently learnt about service layer and slim controllers, I was wondering where should I place input validation (not business validation), in controller or maybe in service layer?

If I have a createOrder in my OrderService class, should I validate the payllad inside my mehtod or in the controller method which executes the service method later. When having services which call other services for me it makes sense to put validation in the service layer but I have read multiple times that controllers should take request, validate, delegate and deliver a response.

Mar
19
2 weeks ago
Activity icon

Started a new Conversation Automatically Resolving Dependencies Without Passing Parameters To Constructor?

Hi everybody, I have a laravel search helper, my helper class needs laravel request object and another class called QueryFilters, I want to inlcude these dependencies INSIDE the class itself so I don't have to pass them as parameters:

This helper class looks like this:

<?php
namespace App\Helpers;
use App\Filters\QueryFilters;
use App\Filters\Filterable;
use Illuminate\Http\Request;


class Search
{


    public function __construct(Request $request, QueryFilters $filters)
    {
        $this->request = $request;
        $this->filters = $filters;
    }

    public static function search( $model, $relationships = [] )
    {
        $requestModel = $request->model;
        
        $model = app("App\Model\{$requestModel}");
        
        $results = $model::search($request->input('search'), '')->get(); 

        if(!$results->isEmpty())
        {
            $ids = implode(',', $results->pluck('id')->toArray());
            $filters->merge(['whereIn' => $ids]);    
        }

        $results = $model::filter($filters)->with($relationships)->paginate(10);

        return $results; 
    }


}

In my controler method when I instantiate the search class it tells me I need to pass two arguments to the class, is there a way to automatically add these dependencies INSIDE my class so I don't need to pass them each time? I thought putting them in my class constructor would automatically resolve them for me but obviously that's not the case:

$search = new Search();
$products = $search->search('Product', ['productcategory']);
Mar
18
2 weeks ago
Activity icon

Started a new Conversation Stripe Webhooks With Laravel

Hi everybody, I have a laravel app where I want to enable Stripe payments, particuraly the asynchronous flow using webhooks! I haven't used webhooks yet so I'm pretty confused and have a few questions:

First I create a paymentIntent in the server and send the PI secret to client.

public function createPaymentIntent(Request $request)
    {

            $intent = PaymentIntent::create([
                'setup_future_usage' => 'off_session',
                'amount' => 1099,
                'currency' => 'usd',
            ]);

            return response()->json([
                'intent_secret' => $intent->client_secret,
            ], 200); 

        
    }

Now in client I execute confirmCardPayment, this returns a Promise

this.stripe.confirmCardPayment(
        this.intent_secret,
        {
            payment_method: {card: this.cardNumberElement}
        }
        )
        .then(function(result)
        {
            if (result.error) 
            {
            // Display error.message in your UI.
            }
            else
            {
            // The payment has succeeded
            // Display a success message
            }
        });

Now this is when it gets confusing, apparently I have to setup webhooks to listen for when auth/payment is completed, I checked the docs and I salvaged their PHP example into my laravel code but I have so many questions:

public function stripeWebhook(Request $request)
    {

        // You can find your endpoint's secret in your webhook settings
        $endpoint_secret = config('services.stripe.webhooksecret');

        $payload = @file_get_contents('php://input');
        $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
        $event = null;

        try
        {
            $event = \Stripe\Webhook::constructEvent($payload, $sig_header, $endpoint_secret);
        } 
        catch(\UnexpectedValueException $e)
        {
                // Invalid payload
                return response()->json([
                    'message' => 'Invalid payload',
                ], 200);
        }
        catch(\Stripe\Exception\SignatureVerificationException $e)
        {
            // Invalid signature
            return response()->json([
                'message' => 'Invalid signature',
            ], 200);
        }

        if ($event->type == "payment_intent.succeeded")
        {
            //As I understand here is where I should do things like send order info by mail and deplete stock accordingly

            $intent = $event->data->object;

            //$this->completeOrderInDatabase()
            //$this->sendMail();

            return response()->json([
                'intentId' => $intent->id,
                'message' => 'Payment succeded'
            ], 200); 
        } 
        elseif ($event->type == "payment_intent.payment_failed")
        {
            //Payment failed to be completed
            
            $intent = $event->data->object;
            $error_message = $intent->last_payment_error ? $intent->last_payment_error->message : "";

            return response()->json([
                'intentId' => $intent->id,
                'message' => 'Payment failed: '.$error_message
            ], 400); 
        }

        
    }

So first, am I supposed to create a POST route called domain.com/webhook from where I will call my webhookController method?

Second, what is payload and signature? these seem like required params but I don't know what exactly they are...

Where am I supossed to attach the payment method to the customer? In the docs I'm supossed to get the payment method from PaymentIntent object but is that in client or server.

https://stripe.com/docs/payments/payment-intents/migration#saving-cards-checkout

From the docs:

$payment_method = \Stripe\PaymentMethod::retrieve('{{PAYMENT_METHOD_ID}}');
$payment_method->attach(['customer' => '{{CUSTOMER_ID}}']);
Feb
26
1 month ago
Activity icon

Replied to Is There An Easier Alternative To Stripe SDK

Yeah I know, I think it's just too much code, my vue/vuex components also lots of logic in them, I actually feel "safer" myself, handling all this in my code.

Maybe people want to post their Stripe PHP implementation in here?

Activity icon

Started a new Conversation Is There An Easier Alternative To Stripe SDK

Hi everybody, in my personal EU based project I want to have one time charges and posibly subscription billing in the future, I heard good things abut Stripe so I decided to use it in my projects.

But after the new EU SCA regulations becoming SCA compliant has made my sync charge workflow much harder to test. With paymentIntents confirmations now I have to take extra trips between client and server, using the same endpoint, having a method to generate different responses based on required action, it was much more easy before.

So I'm asking , is there an alternative to Stripe, SCA compliant with an easier dev workflow than Stripe, maybe Paypal does it easier?

Currently, for a one time charge my workflow looks like this, before it was much SHORTER and STRAIGHTFORWARD.

public function confirmPayment(Request $request)
    {
        //Check if customer was created and user is logged
        $customer = Auth::check() && Auth::user()->stripeId ? Customer::retrieve(Auth::user()->stripeId) : false;
        $user = Auth::user();

        if(!$customer)
        {
            return response()->json([
                'message' => 'Registrate para disfrutar de nuestros mejores descuentos.',
                'customer' => null,
            ], 500);
        }

        //If request has a payment method then customer was just created and credit card introduced, 3d secure not completed yet
        if ($request->input('paymentMethodId'))
        {
            $outOfStock = Discount::outOfStockItems($request->input('cartItems'));

            if(!empty($outOfStock)){
                return response()->json([
                    'message' => 'No nos quedan suficientes existencias de '.$outOfStock[0].'. Escoge una cantidad menor.',
                ], 500);   
            }

            $amount = (int) ($request->input('cartTotal')*100);
            /*
            $receiptData = 
            [
                'userId' => $user['id'],
                'stripeCustomerId' => $customer->id,
                'paymentIntentId' => $paymentIntent->id,
                'cartItems' => $request->input('cartItems'),
                'cartTotal' => $request->input('cartTotal'),
            ];
            */

            $user->cartItems = $request->input('cartItems');
            $user->cartTotal = $request->input('cartTotal');
            $user->save();
            
            $paymentIntent = PaymentIntent::create([
                'payment_method' => $request->input('paymentMethodId'),
                'customer' => $customer->id,
                'amount' => $amount,
                'currency' => 'eur',
                'confirmation_method' => 'manual',
                'payment_method_types' => ['card'],
                'confirm' => true,
                'setup_future_usage' => 'off_session',
                'save_payment_method' => true,
            ], 
            [
                "idempotency_key" => sha1(Carbon::now()) 
            ]);

        }

        //If request has paymentIntent object then 3d secure was completed
        if ($request->input('paymentIntent'))
        {
            $paymentIntent = PaymentIntent::retrieve($request->input('paymentIntent')['id']);
            $paymentIntent->confirm();

            $this->completePayment($paymentIntent);
        }

        //After one of the two options is completed, generate the proper response to client
        return $this->generatePaymentResponse($paymentIntent);
    }


    public function generatePaymentResponse($paymentIntent)
    {

        if ($paymentIntent->status == 'requires_source_action' && $paymentIntent->next_action->type == 'use_stripe_sdk')
        {
            
            # Tell the client to handle the action, this is completing 3D Secure Auth.
            return response()->json([
                'message' => 'El pago requiere confirmación',
                'requires_action' => true,
                'payment_intent_client_secret' => $paymentIntent->client_secret,
            ], 200);  
        }
        else if ($paymentIntent->status == 'succeeded')
        {
            # The payment didn’t need any additional actions and completed succesfully!
            $this->completePayment($paymentIntent);
            
            return response()->json([
                'message' => 'Completaste el pago con exito',
            ], 200);  
        } 
        else
        {
            # Invalid status, something wrong happened
            return response()->json([
                'message' => 'Intención de pago invalida, intentalo de nuevo.',
            ], 500);  
        }
    }


    public function completePayment($paymentIntent)
    {

        $user = Auth::user();
        
        $orderData = 
        [
            'userId' => $user['id'],
            'paymentiIntent' => $paymentIntent['id'],
            'cartItems' => $user->cartItems,
            'cartTotal' => $user->cartTotal,
        ];

        $order = Item::purchaseItems($orderData);

        $item = new Item();
        $item->sendMail1($order);

        return response()->json([
            'message' => '¡Exito! Pago completado con exito',
        ], 200); 
    }
Activity icon

Replied to Error With Artisan Command To Create Database

I missed CHARACTER and COLLATION in my .env file so the database was not being created.

Activity icon

Replied to Unknown Column 'ìtem_size_id' In HasManyThrough Relationship

Sorry guys, it was because of í instead of i ...

Activity icon

Replied to Can't Use PHP Trait Inside Laravel Model

Hi, this is unrelated but can you use CSS classes in your blade templates, I currently have to resort to inline styles but I feel this is not a good aproach for ongterm.

Feb
24
1 month ago
Activity icon

Started a new Conversation Unknown Column 'ìtem_size_id' In HasManyThrough Relationship

Hi everybody, I'm trying to build my own e-commerce shop as training with laravel, I set up a hasManyThrough relationship with models Item, ItemOption,ItemSize and ItemColor. Isssue arises when I seed my database with dummy data, I get the following error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ìtem_size_id' in 'field list' (SQL: insert into `item_options` (`item_id`, `item_color_id`, `ìtem_size_id`, `stock`) values (1, 1, 1, 10))

This is the seed file where error happens:

<?php


use Illuminate\Database\Seeder;
use Carbon\Carbon;


class ItemOptionsSeeder extends Seeder
{
    
    
    public function run()
    {
        //blancas
        DB::table('item_options')->insert([ 'item_id' => 1, 'item_color_id' => 1, 'ìtem_size_id' => 1, 'stock' => 10 ]);
        //negras
        DB::table('item_options')->insert([ 'item_id' => 1, 'item_color_id' => 2, 'ìtem_size_id' => 2, 'stock' => 10 ]);
        //rojas
        DB::table('item_options')->insert([ 'item_id' => 1, 'item_color_id' => 3, 'ìtem_size_id' => 3, 'stock' => 10 ]);
        //verdes
        DB::table('item_options')->insert([ 'item_id' => 1, 'item_color_id' => 4, 'ìtem_size_id' => 4, 'stock' => 10 ]);

    }


}

I think I set up relationships and models correctly and I can't seem to find what's wrong with my code, let's start with My models and then migrations:

Models:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class Item extends Model
{
    
    
    protected $table = 'items';
    
    
    public function options()
    {
        return $this->hasMany(ItemOption::class);
    }

    public function sizes()
    {
        return $this->hasManyThrough(ItemSize::class, ItemOption::class, 'item_size_id', 'id');
    }

    public function colors()
    {
        return $this->hasManyThrough(ItemColor::class, ItemOption::class, 'item_color_id', 'id');
    }
}
<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class ItemOption extends Model
{
    
    protected $fillable = ['item_id', 'item_color_id', 'item_size_id', 'stock'];
    
    public function item()
    {
        return $this->belongsTo('App\Models\Item', 'item_id');
    }
    
    public function color()
    {
        return $this->belongsTo('App\Models\ItemColor', 'item_color_id');
    }

    public function size()
    {
        return $this->belongsTo('App\Models\ItemSize', 'item_size_id');
    }
}
<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class ItemSize extends Model
{
    
    
    protected $table = 'item_sizes';

    
}

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class ItemColor extends Model
{
    
    
    protected $table = 'item_colors';

    
}

And migrations:

<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class ItemOptions extends Migration
{
    

    public function up()
    {


        Schema::create('item_options', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('item_id')->index()->nullable();
            $table->foreign('item_id')->references('id')->on('items')->nullable();
            $table->unsignedInteger('item_size_id')->index()->nullable();
            $table->foreign('item_size_id')->references('id')->on('item_sizes')->nullable();
            $table->unsignedInteger('item_color_id')->index()->nullable();
            $table->foreign('item_color_id')->references('id')->on('item_colors')->nullable();
            $table->integer('stock');
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('item_options');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}

<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class Items extends Migration
{
    

    public function up()
    {


        Schema::create('items', function (Blueprint $table) {
            $table->increments('id');
            $table->string('image')->nullable();
            $table->string('title');
            $table->string('url')->unique();
            $table->string('slug')->unique();
            $table->text('body');
            $table->decimal('finalPrice', 5,2);
            $table->boolean('isVisible')->default(false);
            $table->boolean('isFeatured')->default(false);
            $table->boolean('beenPublished')->default(false);
            $table->boolean('scheduleForMail')->default(false);
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('items');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}

<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class ItemSizes extends Migration
{
    

    public function up()
    {


        Schema::create('item_sizes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('item_sizes');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}
<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class ItemColors extends Migration
{
    

    public function up()
    {


        Schema::create('item_colors', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('colorCode');
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('item_colors');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}

Any idea what I did wrong?

Feb
21
1 month ago
Activity icon

Replied to Can't Use PHP Trait Inside Laravel Model

It doesn't support batch sending.

Activity icon

Replied to Can't Use PHP Trait Inside Laravel Model

You were right about that, but now I'm getting this error:

Using $this when not in object context
Activity icon

Started a new Conversation Can't Use PHP Trait Inside Laravel Model

Hi everybody, I have a trait I use to send mails using mailgun PHP sdk, I'm getting the following error when I try to send mails:

 Trait 'App\Models\sendMailgunSdkApi' not found

This is my Discount model where I use the trait inside sendDiscountMail1 method,

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use App\Models\DiscountCode;
use App\Models\Order;
use Carbon\Carbon;
use App\Models\Scopes\Discounts;
use Mailgun\Mailgun;
use App\Traits\SendMail;


class Discount extends Model
{
    
    
    use Discounts, sendMailgunSdkApi;

      public static function sendMail1($order)
    {
        
        $mailData = 
        [
            'order' => $order
        ];

        $mail = $this->sendMailgunSdkApi('emails.discounts.discount-mail-1', $mailData, 'Disfruta de tu nuevo descuento en '.config('app.name').'.', '[email protected]');
        
        return response()->json([
            'mail' => $mail,
        ]);
    }


}

Why is it trying to look for a trait in my models folder?

My trait just in case:

<?php
namespace App\Traits;


trait SendMail
{


    public function sendMailgunSdkApi($view, $mailData, $subject, $to)
    {
        $html = view($view, compact('mailData'))->render();

        $result = app(Mailgun::class)->messages()->send(config('mail.mailgun.domain'), [
            'from' => config('mail.from.name').' <'.config('mail.from.address').'>',
            'to' => $to,
            'subject' => $subject,
            'html' => $html,
        ]);
        
        return $result;
    }

    

    
}
Feb
18
1 month ago
Activity icon

Started a new Conversation Can't Give Default Value To Database Text Field In Laravel App (mysql)

Hi everybody, in my laravel app I have a Post "body" field of text type, I'm trying to give the field a default value like "This sis the default text for a blog post, feel free to change it" but mysql is throwing an error.

$table->text('body')->default('This is the default text for a blog post, feel free to change it.');

This isn't working...

According to docs BLOB/TEXT fields CAN'T have default values, this is pretty weird tbh.

https://dev.mysql.com/doc/refman/5.7/en/blob.html

I guess I could change the field type from text to string but afaik string won't have as many characters as string type and I knpw for certain that my Blog posts will be loooong. How could I approach this?

Thanks in advance.

Feb
16
1 month ago
Activity icon

Started a new Conversation SQLSTATE[42S22]: Column Not Found, Laravel Relationship Error?

Hi everybody, in my app I have Product and ProductCategory models, a ProductCategory has many Products and a Product belongs to one ProductCategory, in my seed file I succesfully created categories and their products.

Now the issue is in my controller I'm trying to use eager loading method with to load all product categories along with their respective products, like this:

$productCategories = ProductCategory::with('products')->get();

However I'm getting the following error message:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'products.product_category_id' in 'where clause' (SQL: select * from `products` where `products`.`product_category_id` in (1, 2, 3, 4))

These are my models:

Product:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class Product extends Model
{
    
    
    protected $table = 'products';
    
    
    public function productcategory()
    {
        return $this->belongsTo('App\Models\ProductCategory', 'productcategory_id');
    }
}

ProductCategory:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class ProductCategory extends Model
{
    
    
    protected $table = 'productcategories';
    
    
    public function products()
    {
        return $this->HasMany('App\Models\Product');
    }


}

And now my migrations:

<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class CreateProductsTable extends Migration
{
    

    public function up()
    {
        

        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('productcategory_id')->index();
            $table->foreign('productcategory_id')->references('id')->on('productcategories')->onDelete('cascade')->onUpdate('cascade');
            $table->string('title');
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('products');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}
<?php


use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;


class CreateProductCategoriesTable extends Migration
{
    

    public function up()
    {
        
        
        Schema::create('productcategories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title')->unique();
            $table->timestamps();
        });


    }

    
    public function down()
    {
        DB::statement('SET FOREIGN_KEY_CHECKS = 0');
        Schema::dropIfExists('productcategories');
        DB::statement('SET FOREIGN_KEY_CHECKS = 1');
    }


}

Activity icon

Started a new Conversation Inserting Null Values When Seeding Laravel App From Json File

In my laravel app I have a json file I'm tying to use to seed some products into my database. For some reason when I try to save a product I'm inserting empty values for title and productcategory_id fields, even thought the array values are there, the json is transformed into an array with json_decode all right.

This is my logic:

<?php
use Illuminate\Database\Seeder;
use App\Models\Product;


class ProductsSeeder extends Seeder
{
   

    public function run()
    {
        $json = File::get(base_path().'/json/Products.json');

        $products = json_decode($json, true);

        var_dump($products);

        foreach ($products as $product)
        {
            echo($product['title']);
            echo($product['productcategory_id']);
            $product = new Product();
            $product->title = $product['title'];
            $product->productcategory_id = $product['productcategory_id'];
            $product->save();
        }
    }
}

An excerpt of my json file:

[
    { "productcategory_id" : 1, "title":"Hamb.Ternera Maxi"},
    { "productcategory_id" : 1, "title":"Hamb. Ternera Doble"}, 
    { "productcategory_id" : 1, "title":"Hamb. Pollo"}, 
    { "productcategory_id" : 1, "title":"Hamb. Mini"}, 
    { "productcategory_id" : 1, "title":"Camp. clásico"}, 
    { "productcategory_id" : 1, "title":"Camp. ternera"}, 
]

As you can see I use var_dump to see the json data is converted correctly into php assoc array, bt I still get the error. Full error message in my shell is:

   Illuminate\Database\QueryException  : SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'title' cannot be null (SQL: insert into `products` (`title`, `productcategory_id`, `updated_at`, `created_at`) values (, , 2020-02-16 20:25:51, 2020-02-16 20:25:51))

  at C:\xampp\htdocs\dtcburger\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668|

  Exception trace:

  1   PDOException::("SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'title' cannot be null")
      C:\xampp\htdocs\dtcburger\vendor\laravel\framework\src\Illuminate\Database\Connection.php:458

  2   PDOStatement::execute()
      C:\xampp\htdocs\dtcburger\vendor\laravel\framework\src\Illuminate\Database\Connection.php:458

  Please use the argument -v to see more details.
Feb
13
1 month ago
Activity icon

Replied to Change Model Namespace On Project Creation

Never heard about sed command, what is:

sed -i '' 's/App/App\Models/g' app/Models/User.php

doing? String between quotes seems to be a regex but not sure which...

Feb
12
1 month ago
Activity icon

Started a new Conversation Change Model Namespace On Project Creation

Hi everybody, the way I use laravel is with composer create-project command, in all my projects after ding this I have to make a few changes like changing Model namespace from App folder to App/Models folder in a few places of the codebase, this to me makes more sense. My question is , is there a way I can do these changes automatically so I don't have to make the changes manually each new project?

Maybe creating an artisan command? or creating the php files from scratch or using stubs?

Jan
17
2 months ago
Activity icon

Started a new Conversation Can't Find Axios Module ? Module Build Failed: Error: ENOENT: No Such File Or Directory

I'm getting the following error in my laravel-vue app:

Error: Module build failed: Error: ENOENT: no such file or directory, open 'C:\xampp\htdocs\candemtown.es\node_modules\axios\index.js

Pretty weird considering I can see the file is there, I tried deleting node_modules and package-lock.json and doing a npm install again but I keep getting the error.

My package.json file:

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "babel-eslint": "^8.2.6",
        "babel-plugin-dynamic-import-webpack": "^1.1.0",
        "babel-preset-env": "^1.7.0",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "laravel-mix": "^4.0.15",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.2",
        "sass": "^1.17.2",
        "sass-loader": "^7.1.0"
    },
    "dependencies": {
        "axios": "^0.18.1",
        "chart.js": "^2.8.0",
        "jquery": "^3.4.1",
        "lodash": "^4.17.15",
        "vue": "^2.6.8",
        "vue-moment": "^4.1.0",
        "vue-parallaxy": "^1.1.1",
        "vue-slick": "^1.1.15",
        "vue-template-compiler": "^2.6.8",
        "vue2-datepicker": "^2.6.4",
        "vue2-editor": "^2.6.6",
        "vuex": "^3.1.0",
        "vuex-persistedstate": "^2.5.4"
    }
}

Activity icon

Replied to Can't Restart/reload Nginx In My Ubuntu Droplet

None of this worked, see OP again for more details.

Jan
16
2 months ago
Activity icon

Started a new Conversation Can't Restart/reload Nginx In My Ubuntu Droplet

I have a DigitalOcean droplet, after launching a laravel app into production I tried the following command:

sudo systemctl reload nginx

But I get this error:

Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.

I ran sudo nginx -t to see if there were errors but conf and syntax is ok, after that I ran:

sudo nano /var/log/nginx/error.log

and I got this:

2020/01/16 14:53:53 [notice] 14195#14195: signal process started
2020/01/16 14:53:53 [error] 14195#14195: invalid PID number "" in "/run/nginx.pid"
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:80 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:80 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:80 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:80 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:443 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: bind() to 0.0.0.0:80 failed (98: Address already in use)
2020/01/16 14:53:53 [emerg] 14198#14198: still could not bind()

Any idea why I can't restart my web server, my webs are still visible but I can't seem to restart or reload nginx.

Jan
03
2 months ago
Activity icon

Started a new Conversation Error With Artisan Command To Create Database

Hi everybody, I created an artisan command to make life easier, this commadn creates a mysql database from the command prompt, it looks like this:

<?php
namespace App\Console\Commands;


use Illuminate\Console\Command;
use DB;


class CreateDatabase extends Command
{
    protected $description = 'This command creates a new database';
    protected $signature = 'db:create';


    public function handle()
    {
        $database = config("database.connections.mysql.database");
        $charset = config("database.connections.mysql.charset");
        $collation = config("database.connections.mysql.collation");

        $query = "CREATE DATABASE IF NOT EXISTS $database CHARACTER SET $charset COLLATE $collation;";

        DB::statement($query);
    }

}

I tried to keep it simple, when I run this command I get this error:

C:\xampp\htdocs\herboristeriajara>php artisan db:create

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [1049] Unknown database 'herboristeriajara' (SQL: CREATE DATABASE IF NOT EXISTS herboristeriajara CHARACTER SET  COLLATE ;)

  at C:\xampp\htdocs\herboristeriajara\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668|

  Exception trace:

  1   PDOException::("SQLSTATE[HY000] [1049] Unknown database 'herboristeriajara'")
      C:\xampp\htdocs\herboristeriajara\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php:70

  2   PDO::__construct("mysql:host=127.0.0.1;port=3306;dbname=herboristeriajara", "GabotronES", "Perolaperra2206624012017<38", [])
      C:\xampp\htdocs\herboristeriajara\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php:70

  Please use the argument -v to see more details.
Activity icon

Replied to Access Model Variable From Outside Model

Sorry guys, I missed the $ haha

Dec
23
3 months ago
Activity icon

Started a new Conversation Access Model Variable From Outside Model

Hi everybody, I want to access a variable I created in my Prize Eloquent model in laravel, I want to access it like this in my Middleware/Controller:

Prize::activePrize;

I defined $activePrize in my Model:

<?php
namespace App\Models;


use Illuminate\Database\Eloquent\Model;


class Prize extends Model
{


    protected $table = 'prizes';
    public static $activePrize = 'Una copa a tu gusto';


    public function user()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }
    
    
}

I'm trying to do $prize = Prize::activePrize; but I'm getting the following error:

Undefined class constant 'activePrize'
Dec
22
3 months ago
Activity icon

Started a new Conversation Pass Html Element String To Vue Directive, Issue With Eslint

Hi everybdy, I created two custom vue directives to insert an html element after or before another element, I pass an html element string to the element I apply the directive but VS Code is giving me the following error:

Parsing error: unexpected-character-in-attribute-name.eslint-plugin-vue

This is how I'm doing it:

<rad-stack title="Precio final" v-insert-before="'<div class="RADcard3_texts_info_divider"></div>'">{{ item.finalPrice }} €</rad-stack>

My directive looks like this:

Vue.directive('insert-before', {
    isLiteral: true,
    inserted: (el, binding, vnode) => {
        el.parentNode.insertBefore(binding.value, el);
    }
});
Dec
21
3 months ago
Activity icon

Started a new Conversation Help With Dependency Injection And Static Method For My Models

Hi everybidy, I created a helper class for searching and filtering my laravel models (method uses tntsearch and a custom scope), currently it works all right but I want to make some improvements to it, sadly it's proving difficult to achieve what I want:

What I want to improve:

  1. Being able to call search method statically on all my laravel models, like this:
Model::search();

Currently I have to instantiate the class and call the method like:

 $results = $searchHelper->search($request, $filters);

2)Right now I also have to pass two arguments to constructor, in my class I try dependency injection in construct magic method but I still have to pass request and filters as arguments...

How it looks in my controller:

public function search(Request $request, QueryFilters $filters)
    {
        $search = new Search($request, $filters);

        
        $posts = $search->search('Post', ['postcategory', 'author', 'favorites']);

        return response()->json([
            'message' => 'Encontramos unas coincidencias',
            'posts' => $posts,
        ], 200);   
    }

My helper class:

<?php
namespace App\Helpers;


use Illuminate\Http\Request;
use App\Filters\QueryFilters;
use App\Filters\Filterable;


class Search
{

    public $request;
    public $filters;

    public function __construct(Request $request, QueryFilters $filters)
    {
        $this->request = $request;
        $this->filters = $filters;
    }

    public function search( $model, $relationships = [] )
    {
        $model = app("App\Models\".$model."); 
        
        $results = $model::search($this->request->input('search'), '')->get(); 

        if(!$results->isEmpty())
        {
            $ids = implode(',', $results->pluck('id')->toArray());
            $filters->merge(['whereIn' => $ids]);    
        }

        $results = $model::filter($this->filters)->with($relationships)->paginate(10);

        return $results; 
    }


}

I want to call the method like this, NO passing arguments to constructor (DI should handle that), call method STATICALLY

Appointments::search();
Activity icon

Started a new Conversation Can't Access Data Property From Parent In Slot Child Component

I have two components rad-list and rad-card, I placed a slot element in rad-list where I will place rad-card, now rad-card receices an object from computedResults array (in parent scope) and iterates through them and pass result to item prop in rad-card, but since computedResults is defined in parent component my rad-card instance doesn't have access to it?

<rad-list model="Discount" module="Discount" results="discounts">
        <rad-card :item="result" v-for="result in computedResults" :key="result.id" :model="module"></rad-card>
    </rad-list>

I get following error:

[Vue warn]: Property or method "computedResults" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

(found in <Root>)

My rad-list component:

<template>
<div class="RADlist_maincontainer">
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
    <div class="RADlist_wrapper">
        <!--rad-card, or any other component which will use computedResults GOES HERE-->
        <slot></slot>
    </div>
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState } from 'vuex';
export default{
name: 'RADlist',


computed:
{
    computedResults: function()
    { 
        return this.$store.state[this.module][this.results];
    },
    pagination: function()
    { 
        return this.$store.state[this.module].pagination;
    },
    ...mapState('Loader', ['loader'])
},


props:
{
    component: { default:'rad-card', type:String },
    module: { default:'Post', type:String },
    action: { default:'list', type:String },
    results: { default:'posts', type:String },
    page: { default:1, type:Number },
    paginate: { default:6, type:Number },

},


mounted()
{
    console.log(this.$options.name+' component successfully mounted');
    this.$store.dispatch(this.module+'/'+this.action, { page: this.page, paginate: this.paginate, loaderId:2473});
},


}
</script>
Dec
20
3 months ago
Activity icon

Started a new Conversation Vue: Access Parent Component Data In Slotted Child Component?

I have two components rad-list and rad-card, I placed a slot element in rad-list where I will place rad-card, now rad-card needs to access a computedResults data from parent rad-list component, how can I access it using vue slots, is it possible?

RAD LIST

<template>
<div class="RADlist_maincontainer">
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
    <div class="RADlist_wrapper">
        <!--rad-card, or any other component which will use computedResults GOES HERE-->
        <slot></slot>
    </div>
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
</div>
</template>

This is how it loks in my template:

<rad-list model="Discount" module="Discount" results="discounts">
        <rad-card :item="result" v-for="result in computedResults" :key="result.id" :model="module"></rad-card>
    </rad-list>

My full RADlist component justi in case it's needed:

<template>
<div class="RADlist_maincontainer">
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
    <div class="RADlist_wrapper">
        <!--rad-card, or any other component which will use computedResults GOES HERE-->
        <slot></slot>
    </div>
    <layout-pagination-1 v-show="pagination.last_page > 1" :pagination="pagination" @paginate="paginate({ page:pagination.current_page, paginate:paginate })"></layout-pagination-1>
</div>
</template>
<!--SCRIPTS-->
<script>
import { mapState } from 'vuex';
export default{
name: 'RADlist',


computed:
{
    computedResults: function()
    { 
        return this.$store.state[this.module][this.results];
    },
    pagination: function()
    { 
        return this.$store.state[this.module].pagination;
    },
    ...mapState('Loader', ['loader'])
},


props:
{
    component: { default:'rad-card', type:String },
    module: { default:'Post', type:String },
    action: { default:'list', type:String },
    results: { default:'posts', type:String },
    page: { default:1, type:Number },
    paginate: { default:6, type:Number },

},


mounted()
{
    console.log(this.$options.name+' component successfully mounted');
    this.$store.dispatch(this.module+'/'+this.action, { page: this.page, paginate: this.paginate, loaderId:2473});
},


}
</script>

Dec
13
3 months ago
Dec
11
3 months ago
Activity icon

Started a new Conversation Use StripeController Action In ProductController?

Hi everybody, I created my own laravel-vue e-commerce app, people buy Product Model with Stripe PHP sdk, what I was doing till now is I created a StripeController for handling stripe operations like charge, start subscriptions, refunds (for me this made sense), but I noticed my StripeController is not the best way to do this, before finsihing a charge I performed some actions like:

1)Transform cartTotalPrice to cents. 2)Check if cart items were all on stock with Product::outOfStock($cartItems);

  1. And maybe some simple auth check

This to me started to smell of bad code practice, so I'm thinking now I should move this actions (atleast charging and subscribing) to their related Model controllers (Product in this case) adn maybe transform my StripeController into a helper calss where I can wrap my refund, charge, createCustomer and getCustomerPaymentMethods actions into a Stripe helper class I would call in my ProductController, DiscountController or any other "buyable" model right?.

Another option would be calling my StripeController actions from ProductController but that smells even worse honestly.

What do you guys think of my idea?

Dec
09
3 months ago
Activity icon

Started a new Conversation "value.toString(...).toUppercase Is Not A Function"

Hi everybody, in my vue component I have an "uppercase" filter to tranform strings into uppercase, however I'm gettinh the following error:

TypeError: "value.toString(...).toUppercase is not a function"

This is my filter:

Vue.filter('uppercase', function (value) {
    console.log(typeof value); // this returns string
    if (!value) return '';
    value = value.toString().toUppercase();
    return value;
});
Dec
06
3 months ago
Activity icon

Replied to Use Model Methods In Seeder?

Could this also work in my seeders?

$newUser = new User();
$newUser->generateSlots();
$newUser->save();

If so I begin to use this method instead since that's how my controllers look normaly (CRUD endpoints...), that way I will be able to access my model variables and methods.

Also is there a way to put model Scopes (basically traits) in the model class, like actually putting the query builder struff in the model, I 'm all for separation of concerns but I prefer having entity Model related stuff close together.

Activity icon

Started a new Conversation Use Model Methods In Seeder?

Hi everybody, I have a seeder file for creating some default users, I want to seed some relations via using a User instance method, this could be easy in a controller method ($user->generateSlots(); ) but in my seeder file I use insert instead of save method like in controller, how can I do this?

My method looks like this:

public function generateSlots()
    {
        for ($i = 0; $i < $this->slotsPerUser; $i++)
        {
            $slot = new Slot();
            $slot->user_id = $this->id;
            $slot->unicode = $this->generateRandomToken2();
            $this->slots()->save($slot);
        }
    }

My seeder looks like this:

DB::table('users')->insert([
            //'name' => config('admin.name'),
            'email' => config('admin.mail'),
            'password' => bcrypt(config('admin.password')),
            'privileges' => 3,
            'confirmationKey' => sha1(Carbon::now()),
            'confirmed' => true,
            'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
            'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
        ]);
Dec
03
3 months ago
Activity icon

Started a new Conversation Laravel Authentication In Nativescript-vue App, Anyone Has Done It?

Hi everybody, I'm fairly new to nativescript-vue dev and I'd like to set authentication for my native app, I have been thinking about using firebase auth but I'd rather go the laravel route (if it's a good choice at all).

How I think I'd handle this is to send a post request to my backend (which is a laravel app) into my custom auth controller, then in the success callback I'd change isLogged in the vuex store to true or false, since I'm suing also vuex-persistedstate to persist some data into my localStorage (actually it's Application Settings in natviescript afaik).

Is my way of doing this okk? has anyone done it?

Dec
01
4 months ago
Activity icon

Started a new Conversation Adding Script With Blade Syntax In From App.js In Vue

Hi everybody, is it possible to add a javascript inline script to my html head page using javascript, in my app which uses laravel and vue I want to add the following script from the created method in my entry app.js file.

<script type="text/javascript">window.$app = {!! json_encode(app(App\Helpers\Javascript::class)->app) !!};</script>

As you can see there's some blade syntax in there.

Is it possible to do? I know I could add a partial to my master layout but something like what I'm trying to do is better/more maintaneable imo.

Nov
18
4 months ago
Activity icon

Started a new Conversation How Can I Get A Vertical Print Of My Webpage In PDF/Image

Hi everybody, I want to get a vertical image/PDF print of my webpage, I have tried many online tools which transform pages into PDF for free but the results are really bad, the CSS styles appear all fucked up, is there a way to get an image like this for free?

https://i.pinimg.com/originals/cd/a5/80/cda580be017f344a6b743dbacf088250.png

Nov
16
4 months ago
Activity icon

Started a new Conversation Merging Request Params With Array

Hi everybody, I'm trying to get laravel-scout tntsearch with eloquent's query builder, this has proven difficult so my current approach is to first use tntsearch to get results, pluck ids from the results adn then add a wherIn clause with the plucked ids, to do this I have an additional class QueryFilters to sort and filter in a composable way.

Issue is I'm getting the following error:

Call to undefined method App\Filters\QueryFilters::merge()

Here is my code:

public function search(Request $request, QueryFilters $filters)
    {
        //Search with tntsearch 
        $posts = Post::search($request->input('search'))->get();

        //Grab ids and prepare to merge with $filters
        $postIds = $posts->pluck('id');
        $toMerge = collect(['whereIn' => $postIds]);

        $filters->merge($toMerge);
        //Filter and sort results
        $posts = Post::filter($filters)->with(['postcategory','author','favorites'])->paginate(10);
}

How QueryFilters works is iterating throught the request object looking for methods with the same name and returning each time an instance of the query builder.

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class QueryFilters
{
    protected $request;
    protected $builder;
  
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function title($term)
    {
        $lowerCaseTerm = strtolower($term);

        return $this->builder->where('title', 'LIKE', "%$lowerCaseTerm%");
    }

    public function postCategory($term)
    {
        if($term == 0)
        {
            return $this->builder->whereHas('postcategory', function ($query) use ($term){
                $query->where('id', '>', 0);
            });
        }
        
        return $this->builder->whereHas('postcategory', function ($query) use ($term){
            $query->where('id', $term);
        });
    }
    
    public function sortBy($term)
    {
        $sortArray = explode(",", $term);

        for($i = 0; $i < count($sortArray); $i++)
        {
            $sortBy = substr_replace($sortArray[$i], "", -1);

            $sortChar = substr($sortArray[$i], -1);
        
            $sortOrder = $sortChar == '+' ? 'ASC' : 'DESC';  
           
            $this->builder->orderBy($sortBy, $sortOrder);
        }

        return $this->builder;
    }

    public function whereIn($postIds)
    {
        return $this->builder->whereIn('id', $postIds);
    }
  
    public function apply(Builder $builder)
    {
        $this->builder = $builder;
        foreach ($this->filters() as $name => $value)
        {
            //if method doesn't exists continue out of the loop 
            if ( ! method_exists($this, $name))
            {
                continue;
            }
            //method exists so check if it has a value payload so call the method with arguments
            if (strlen($value)) 
            {
                $this->$name($value);
            } 
            //it doesn't have a payload so call the method without arguments
            else 
            {
                $this->$name();
            }
        }
        return $this->builder;
    }
  
    public function filters()
    {
        //returns associative array of request body key value pairs
        return $this->request->all();
    }

}

To know more about this class see this medium article: https://medium.com/@mykeels/writing-clean-composable-eloquent-filters-edd242c82cc8

If I dd $filters I get this:

QueryFilters {#457
  #request: Request {#43
    #json: null
    #convertedFiles: null
    #userResolver: Closure($guard = null) {#421
      class: "Illuminate\Auth\AuthServiceProvider"
      this: AuthServiceProvider {#41 …}
      use: {
        $app: Application {#2 …}
      }
      file: "C:\xampp\htdocs\dog-media.es\vendor\laravel\framework\src\Illuminate\Auth\AuthServiceProvider.php"
      line: "83 to 85"
    }
    #routeResolver: Closure() {#423
      class: "Illuminate\Routing\Router"
      this: Router {#26 …}
      use: {
        $route: Route {#220 …}
      }
      file: "C:\xampp\htdocs\dog-media.es\vendor\laravel\framework\src\Illuminate\Routing\Router.php"
      line: "650 to 652"
    }
    +attributes: ParameterBag {#45
      #parameters: []
    }
    +request: ParameterBag {#51
      #parameters: array:3 [
        "loaderId" => "1111"
        "postCategory" => "0"
        "sortBy" => "created_at+"
      ]
    }
    +query: ParameterBag {#51}
    +server: ServerBag {#47

...
Nov
15
4 months ago
Activity icon

Started a new Conversation Using V-model With Nested Components In Vue

Hi everybody, in my admin app I have an <admin-rich-editor>, inside this component I also have Vue 2's quill rich editor which uses v-model for its data, now I want to pass the v-model from my child vue-2-editor to my own parent component, the docs say you can have custom v-model in yur compoennt with props value and emiting an 'input' event with that value, but how can I pass one v-model to another, from child to parent component.

Im using vue 2 editor, A text editor using Vue.js and Quill: https://github.com/davidroyer/vue2-editor

My component <admin-editor>:

<template>
<div style="width:auto; height:auto; display:flex; flex-direction.column;">
    <button @click="editorVisible = true">Show Editor</button>
    <vue-editor v-model="value" :editorToolbar="customToolbar" useCustomImageHandler @imageAdded="handleImageAdded"></vue-editor>
</div>
</template>
<!--SCRIPTS-->
<script>
import { VueEditor } from 'vue2-editor';
export default {
name: 'ADMINeditor',


props:
{
    value:{ required:true, type:String }
},


data()
{
    return { 
        editorVisible:false
    }
},


methods:
{

    wrote()
    {
        this.$emit('input', this.value);
    }
}


}
</script>
<!--STYLES-->
<style scoped>
</style>

I want to be able to do:

<admin-editor v-model="text"></admin-editor>

More info about -model in custom components.

https://alligator.io/vuejs/add-v-model-support/

Activity icon

Started a new Conversation Using Laravel-scout Tntsearch Along With Eloquent Query Builder

Hi everybody, I want the user to sort, filter AND tnt-search Model entries, in my laravel backend I have a search method API call, currently I can't get scout's Model::search method to work along with Eloquent's query builder, so you either:

  1. Search by text if request has 'search'.
  2. Sort or filter with eloquent query builder (see link bellow for more info).

How can I get both the results from tnt-search term search and eloquent query builder to return a merged result, paginated;

My search method:

public function search(Request $request, QueryFilters $filters)
    {

        if($request->has('search'))
        {
            $posts = Post::search($request->input('search'))->paginate(10);
            $posts->load(['postcategory','author','favorites']); 

            if($posts->isEmpty())
            {
                return response()->json([
                    'message' => 'No se encontraron resultados',
                ],500);    
            }

            return response()->json([
                'message' => 'Encontramos unas coincidencias',
                'posts' => $posts,
            ], 200);
        }
        else
        {
            $posts = Post::filter($filters)->with(['postcategory','author','favorites'])->paginate(10);

            if($posts->isEmpty())
            {
                return response()->json([
                    'message' => 'No se encontraron resultados',
                ],500);    
            }

            return response()->json([
                'message' => 'Encontramos unas coincidencias',
                'posts' => $posts,
            ], 200);
        }
        
    }

And in case you are wondering what does Model::filter do, it just iterates through the request query params and uses Eloquent to sort and filter, you can check this medium article:

https://medium.com/@mykeels/writing-clean-composable-eloquent-filters-edd242c82cc8

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class QueryFilters
{
    protected $request;
    protected $builder;
  
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function title($term)
    {
        $lowerCaseTerm = strtolower($term);
        return $this->builder->where('title', 'LIKE', "%$lowerCaseTerm%");
    }
  
    public function apply(Builder $builder)
    {
        $this->builder = $builder;
        foreach ($this->filters() as $name => $value)
        {
            //if method doesn't exists continue out of the loop 
            if ( ! method_exists($this, $name))
            {
                continue;
            }
            //method exists so check if it has a value payload so call the method with arguments
            if (strlen($value)) 
            {
                $this->$name($value);
            } 
            //it doesn't have a payload so call the method without arguments
            else 
            {
                $this->$name();
            }
        }
        return $this->builder;
    }
  
    public function filters()
    {
        //returns associative array of request body key value pairs
        return $this->request->all();
    }

}
Nov
14
4 months ago
Activity icon

Started a new Conversation Get Model By Id Plus 10 Previous And 10 After It

Hi everybody, given an id of a model I want to grab that model, the ten previous model entries and ten after the selected id, I also want to return them paginated.

So if I get id 11 I want to return ids: 1 2 3 4 5 6 7 8 9 10 <- 11 -> 12 13 14 15 16 17 18 19 20

Nov
12
4 months ago
Activity icon

Started a new Conversation SQLSTATE[22007]: Invalid Datetime Format: 1366 Incorrect Integer Value: 'true' For Column 'isVisible'

Hi everybody, I'm sending data with FormData object to my laravel backend, issue is I have a checkbox input which is causing me trouble, my backend logs the following error message:

SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: 'true' for column 'isVisible' ...

In my migrations isVisible field is declared as a boolean:

$table->boolean('isVisible')->default(false);

If I hack into the payload and send an 1 instead of 'true' or 0 instead of 'false' my Post entry is created succesfully.

Any idea how I can solve this?

Nov
11
4 months ago
Activity icon

Started a new Conversation Model Not Returning Properties With Default Value After Creation

Hi everybody, in my controller after I create a new Post I return the new post in a post variable, for some reason I don't get the properties with default values back, I noticed if I set the value to something in controller it does indeed return the properties in the payload.

public function create(Request $request)
    {
        $validatedData = $request->validate(PostValidator::$create);
        
        $post = new Post();
        $post->postcategory_id = $request->input('postcategoryid');
        $post->user_id = $request->input('authorid');
        $post->thumbnail = $this->uploadFile($request, 'thumbnail', config('app.defaultImage'));
        $post->video = $request->input('video');
        $post->slug = $this->slugify($request->input('title'));
        $post->url = '/publicaciones/'.$this->slugify($request->input('title'));
        $post->title = $request->input('title');
        $post->body = $request->input('body');
        $post->isVisible = false; //IF I DO THIS isVisible is returned in $post variable
        $post->save();

        $post->load(['postcategory','author']);
        
        return response()->json([
            'post' => $post,
        ]);
        
    }
Activity icon

Started a new Conversation Question About Server Date And Laravel Cron Jobs

Hi everybody, I just learnt about cron jobs in the server and larave crons, in my laravel apps I set timezone in .env file like this:

APP_TIMEZONE='Europe/Madrid'

Now in my ubuntu VPS I ran the command

date

And noticed it says UTC with one hour earlier than my local time (one hour less sorry for english), Now I have two questions:

When I run a cron job from laravel using the schedule command what time does the app take into account to run the commands, my VPS time (UTC, one hour less) or my laravel app time (Europe/Madrid)?

I want to fix my VPS time so its the same as my local time (changing it to UTC+1 would fix it) , how can I change the date/timezone? Is it a good idea to do this?

Nov
09
4 months ago
Activity icon

Started a new Conversation Help With Spread Operator On Laravel Blade

Hi everybody, my app is based on a bunch of empty blade templates filled with vue components, I pass props to this components and this props come from my backend through Vue prototype global variables, I'm trying to pass to my component only item 1 and 2 of an array of three, I know I could do this with computed property but I'm trying to do this with spread operator and inline.

I'm getting the following error:

Error in render: "TypeError: $app.globals.allSections[0] is not iterable"

This is how it looks in my blade template:

@extends('layouts.master')
@section('content')
<v-wrapper :jc="'space-around,flex-start'" :h="'calc(100vh - var(--navHeight)),auto'" :p="'20px,10px'">
    <layout-card-7 v-for="item in [ ...$app.globals.allSections[0], ...$app.globals.allSections[1] ]" :item="item" :key="item.id"></layout-card-7>
</v-wrapper>
@endsection

Is there another way to achieve this in a single line?

Nov
08
4 months ago
Activity icon

Started a new Conversation SQLSTATE[HY000]: General Error: 1364 Field 'parent_id' Doesn't Have A Default Value

Hi everybody, I'm building my own forum as practice, I set up Topic and Comment models with polymorphic relationship, a comment can belong to a topic or another comment, this is because I want to have nested comments. Another issue is when I reply to the topic I get the following error:

SQLSTATE[HY000]: General error: 1364 Field 'parent_id' doesn't have a default value (SQL: insert into `comments` (`user_id`, `body`, `commentable_id`, `commentable_type`, `updated_at`, `created_at`) values (1, <p>ljlnlnlnlnlnllnlnlnlnlnln</p>, 1, App\Models\Topic, 2019-11-08 20:41:43, 2019-11-08 20:41:43))

My models and Migrations.

Topic model:

class Topic extends Model
{
    
    
    protected $table = 'topics';
    
    public function author()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }

    public function comments()
    {
        return $this->morphMany('App\Models\Comment', 'commentable')->whereNull('parent_id');
    }

public function up()
    {
        Schema::create('topics', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id')->index();
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('title');
            $table->text('body');
            $table->string('url')->unique();
            $table->string('slug')->unique();
            $table->boolean('isVisible')->default(false);
            $table->timestamps();
        });
    }


}

Comment model:

class Comment extends Model
{
    
    
    protected $table = 'comments';

    public function author()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }

    public function replies()
    {
        return $this->hasMany('App\Models\Comment', 'parent_id');
    }


}


public function up()
    {
    Schema::create('comments', function (Blueprint $table) {
       $table->bigIncrements('id');
       $table->integer('user_id')->unsigned();
       $table->integer('parent_id')->unsigned();
       $table->integer('commentable_id')->unsigned();
       $table->string('commentable_type');
       $table->text('body');
       $table->timestamps();
    });
    }
Activity icon

Started a new Conversation Paginate Polymorphic Relationship, Topic->comments()

Hi everybody, I'm building a basic forum, there are many topics and each topic has comments, a comment or "commentable" can be a a comment or a reply (commented a comment), this is because I want to have nested comments, that's where parent_id is useful. I'm wondering if my polymorphic relationship is the best way to achieve this so I'm open to any suggestions. The first issue I came up with is I don't know hw to do ajax pagination of topic->comments ..., I thought with something like Comment::whereHas('topic') ... but my comments dont' have a topic relationship defined in the model.

I'm using laravel advanced ajax pagination, how can I paginate comments?

Topic model:

class Topic extends Model
{
    
    
    protected $table = 'topics';
    
    public function author()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }

    public function comments()
    {
        return $this->morphMany('App\Models\Comment', 'commentable')->whereNull('parent_id');
    }

public function up()
    {
        Schema::create('topics', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id')->index();
            $table->foreign('user_id')->references('id')->on('users');
            $table->string('title');
            $table->text('body');
            $table->string('url')->unique();
            $table->string('slug')->unique();
            $table->boolean('isVisible')->default(false);
            $table->timestamps();
        });
    }


}

Comment model:

class Comment extends Model
{
    
    
    protected $table = 'comments';

    public function author()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }

    public function replies()
    {
        return $this->hasMany('App\Models\Comment', 'parent_id');
    }


}


public function up()
    {
    Schema::create('comments', function (Blueprint $table) {
       $table->bigIncrements('id');
       $table->integer('user_id')->unsigned();
       $table->integer('parent_id')->unsigned();
       $table->integer('commentable_id')->unsigned();
       $table->string('commentable_type');
       $table->text('body');
       $table->timestamps();
    });
    }

This is where I took inspiration:

Nov
04
4 months ago
Activity icon

Started a new Conversation Remove @mailservice.com From Email String With PHP

Hi everybody, in PHP I want to get only the characters before "@", if I get [email protected] I want to get supercool back.

Oct
30
5 months ago
Activity icon

Started a new Conversation Using Laravel Scout Tntsearch Driver With Other Eloquent Methods For Sorting/filtering.

Hi everybody, in my larave-vue app I want to be able to filter by a search term using laravel scout tntsearch, along with this I also perform additional filtering, sorting or where clauses in my controller. I can't get both to work correctly in my app.

In my controller I have this:

$posts = Post::filter($filters)->search($request->input('query'))->paginate(0);
            $posts->load(['postcategory.section','author']);

            if($posts->isEmpty())
            {
                return response()->json([
                    'message' => 'No results found',
                ],500);    
            }

            return response()->json([
                'message' => 'Results found',
                'posts' => $posts,
            ]);

It gives me the following error:

Call to undefined method Illuminate\Database\Eloquent\Builder::search()

For some reason It's not working, I have tried changing the order of the filter, search and paginate but I still get errors.

In case you are wondering how does my filter method works it's basically a scope

You can read an indepth write up about it here:

https://medium.com/@mykeels/writing-clean-composable-eloquent-filters-edd242c82cc8

See my QueryFilters and Filterable trait bellow just in case

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class QueryFilters
{
    protected $request;
    protected $builder;
  
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function title($term)
    {
        $lowerCaseTerm = strtolower($term);
        return $this->builder->where('title', 'LIKE', "%$lowerCaseTerm%");
    }

    public function postCategory($term)
    {

        return $this->builder->whereHas('postcategory', function ($query) use ($term){
            $query->where('id', $term);
        });
    }

    public function sort($term)
    {
        $sortArray = explode(",", $term);

        for($i = 0; $i <= $sortArray.length; $i++)
        {
            $sortBy = substr_replace($sortArray[i], "", -1);

            $sortChar = substr($sortArray[i], -1);
        
            $sortOrder = $sortChar == '+' ? 'ASC' : 'DESC';  
           
            $this->bulider->orderBy($sortBy, $sortOrder);
        }

        return $this->builder;
    }
  
    public function apply(Builder $builder)
    {
        $this->builder = $builder;
        foreach ($this->filters() as $name => $value)
        {
            //if method doesn't exists continue out of the loop 
            if ( ! method_exists($this, $name))
            {
                continue;
            }
            //method exists so check if it has a value payload so call the method with arguments
            if (strlen($value)) 
            {
                $this->$name($value);
            } 
            //it doesn't have a payload so call the method without arguments
            else 
            {
                $this->$name();
            }
        }
        return $this->builder;
    }
  
    public function filters()
    {
        //returns associative array of request body key value pairs
        return $this->request->all();
    }

}

And Filterable Trait

<?php
namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;

trait Filterable
{
    public function scopeFilter($query, QueryFilters $filters)
    {
        return $filters->apply($query);
    }
}