How to Store Array Value From Select2 JS in Laravel - laravel

I'm using MySQL Database. I have select2 js with multiple value
Here is my code
My Blade View And JS
<input type="text" class="form-control tools_id" name="tools_id[]" multiple/>
var $tools_id = jQuery('.tools_id');
$tools_id.select2({
multiple: true,
placeholder: 'Tools',
ajax: {
url: 'sample/gettools',
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
q: term, //search term
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.tools,
id: item.tools_id
}
})
};
},
cache: true
}
});
My Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sample extends Model
{
protected $primaryKey = 'id';
public $incrementing = false;
protected $table = 'lab_sample';
protected $casts = [
'tools_id' => 'array'
];
protected $fillable = ['name','summary','tools_id'];
}
My Controller
public function store(Request $request)
{
$sample = Sample::create([
'name' => $request->name,
'summary' => $request->summary,
'tools_id' => $request->input('tools_id'),
]);
return Response::json($sample);
}
My code was successfully save the data, but the problem is when i selected more than one value/tags, it saved the array value (tools_id) like this
["20,21"]
Where it supposed to be like this
["20","21"]

Related

Subscriptions and subscription_item database is empty using Stripe checkout

I try to create a website using Stripe for monthly subscription.
I got a pricing page, when i choose a product, i create a checkout session using JS, and when i pay, i got successfully the payement and everything, but my subscription database is empty. The default cashier webhook do nothing but he are called successfully on my stripe cli, I also tryied to create a webhook but i got nothing from it i got every times error 500 on stripe cli.
Do you have an idea ?
Here is my JS
<script src="https://js.stripe.com/v3/"></script>
<script defer>
$("#form").submit(function(e){
e.preventDefault();
});
var handleResult = function(result) {
if (result.error) {
showErrorMessage(result.error.message);
}
};
function subscribe(offer)
{
fetch("{{ route('subscription_setup') }}", {
method: "GET",
headers: {
"Content-Type": "application/json",
}
})
.then((result) => result.json())
.then(function(result) {
var publishableKey = result.publishableKey;
var stripe = Stripe(publishableKey);
var createCheckoutSession = function(offer) {
return fetch("{{ route('subscription_create_checkout_session') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
body: JSON.stringify({
offer: offer
})
}).then(function(result) {
return result.json();
});
}
createCheckoutSession(offer).then(function(data) {
stripe.redirectToCheckout({
sessionId: data.sessionId
}).then(handleResult);
});
})
}
</script>
Here is my PHP :
<?php
namespace App\Http\Controllers;
use Exception;
use Illuminate\Http\Request;
use \Stripe\Stripe;
use Illuminate\Support\Facades\Auth;
use Laravel\Cashier\Cashier;
use \Stripe\Checkout\Session;
class SubscriptionController extends Controller
{
public function __construct() {
Stripe::setApiKey(env('STRIPE_SECRET'));
}
public function index()
{
return view('subscription/index');
}
public function create_checkout_session(Request $request)
{
$user = Auth::user();
// User is not in stripe database
if(empty($user->stripe_id))
{
$stripe_user = $user->createAsStripeCustomer();
}
// User already in stripe database
else
{
$stripe_user = Cashier::findBillable($user->stripe_id);
}
// After retrieve the stripe user
$offer = $request->post('offer');
if($offer == 'football')
{
$price = 'price_1I4z8kDdfEiamf5bMiTElVAM';
}
else
{
return response()->json(['error' => 'Vous n\'avez pas sélectionné une offre valide']);
}
$checkout_session = Session::create([
'payment_method_types' => ['card'],
'line_items' => [
[
'price' => $price,
'quantity' => 1,
],
],
'mode' => 'subscription',
'success_url' => url('/'),
'cancel_url' => url('/subscription'),
'customer' => $stripe_user['stripe_id']
]);
return response()->json(['sessionId' => $checkout_session['id']]);
}
public function setup()
{
return response()->json([
'publishableKey' => env('STRIPE_KEY')
]);
}
}
I'm open to every suggestions, thank's a lot.
Edit :
My custom webhook
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;
use \Stripe\Subscription;
use Illuminate\Support\Facades\DB;
class WebhookController extends CashierController
{
/**
* Handle invoice payment succeeded.
*
* #param array $payload
* #return \Symfony\Component\HttpFoundation\Response
*/
public function handleInvoicePaymentSucceeded($payload)
{
$session = $payload['data']['object'];
$user = Auth::user();
// $plan = Subscription::retrieve($session['subscription']['items']['data']['price']['id']);
DB::transaction(function () use ($session, $user) {
$user->update(['stripe_id' => $session['customer']]);
$user->subscriptions()->create([
'name' => 'default',
'stripe_id' => $session['subscription'],
'stripe_status' => 'active',
'stripe_plan' => 'price_1I4z8kDdfEiamf5bMiTElVAM',
'quantity' => 1,
'trial_ends_at' => null,
'ends_at' => now()->addDays(30),
]);
});
return $this->successMethod();
}
}
My verifycsrftoken.php
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'stripe/*',
];
}
my routes :
Route::post('/stripe/webhook', [WebhookController::class, 'handleWebhook']);
I got a error 500 into my stripe cli while i sub to a product.
Edit : I finally used this tutorial https://weeklyhow.com/create-website-subscription-with-laravel-cashier/#:~:text=Laravel%20cashier%20is%20a%20package,and%20even%20generate%20invoice%20PDFs. and don't use stripe checkout anymore.

Can not update a boolean value in table by vue and laravel

I have a boolean field when I try to update from false to true for a single or multiple records it works but when trying to update it back to false it works for the first record only and can not repeat to update multiple records at the same time without refreshing the page 1- my vue component that handles the request is like this:
<template>
<div v-for="(channel, index) in items" :key="channel.id">
<a href="" #click.prevent="toggleVisibility(channel)">
<i v-if="channel.active" class="fas fa-stop default-stop" data-toggle="tooltip" title="Stop Channel">
</i>
<i v-else class="fas fa-play" data-toggle="tooltip" title="Start Channel"></i>
</a>
</div>
</template>
export default {
name: "Channels",
props: ['allChannels'],
data() {
return {
items: this.allChannels
}
},
methods: {
toggleVisibility(channel) {
axios[channel.active ? 'delete' : 'post'](`/visible-channels/${channel.name}`);
}
}
}
and my routes:
Route::post('/visible-channels/{channel}', 'ChannelsController#activate');
Route::delete('/visible-channels/{channel}', 'ChannelsController#deactivate');
my controller:
public function activate(Channel $channel, Request $request)
{
if ($request->method() == 'POST') {
$channel->update(['active' => true]);
}
return back();
}
public function deactivate(Channel $channel, Request $request)
{
if ($request->method() == 'DELETE') {
$channel->update(['active' => false]);
}
}
The model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Channel extends Model
{
protected $guarded = [];
protected $casts = [
'active' => 'boolean',
];
protected static function boot()
{
parent::boot();
static::updating(function () {
return Cache::forget('activeChannels');
});
}
public function getRouteKeyName()
{
return 'name';
}
}
Since laravel stores boolean as 1 and 0 in database, You should probably set active property to boolean in your model
That's because laravel treat false as string so when you set active to false it compares it as 'false' == true which is true so it stores 1 in database.
class Channel extends Model
{
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'active' => 'boolean',
];
}
I figured it out just change in the boot function to wait until the update finish
static::updated(function () {
return Cache::forget('activeChannels');
});

DB::table('table')->select returning empty string Laravel 6

I am using Laravel 6 with Vue axios, I want to populate a form-select with what I have in my "fjl_groups" table. But everytime I check the console for the result it is returning me an empty string, any idea why is this? My Laravel logs aren't returning any error either, so I have no idea what's going on.
Vue's part
<b-col cols="4">
<label for="editorial">Group</label>
<b-form-select v-model="group" :options="groups" id="groups" name="groups"></b-form-select>
</b-col>
<script>
export default {
data() {
return {
group: null,
groups: [{
value: null,
text: 'Select'
}]
}
},
created(){
axios.get('/clubs/create')
.then(res => {
this.groups = res.data;
console.log(this.groups);
}).catch(e => {
console.log(e);
})
},
}
}
</script>
I have a club and I want to assign a group for it from the ones I have added in my database, this is why I have it like that.
My controller (ClubsController)
use Illuminate\Support\Facades\DB;
use App\Models\Club;
use App\Models\Group;
public function create(Request $request)
{
if($request->ajax()){
DB::table('fjl_groups')->select('id as value', 'nom as text')->get();
}
else{
return view('clubs.create');
}
}
Group Model
class Group extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'fjl_groups';
public $timestamps = false;
}
You are not returning a value. You're just performing the select.
Try returning it:
return response()->json([
'data' => DB::table('fjl_groups')->select('id as value', 'nom as text')->get()
]);

Why deleting row in related row boot() is not triggered?

In my Laravel 5.7 app I have 2 tables Tag, TagDetail(One to One relation) and the second table has image uploaded to storage and image field.
I want using boot method for automatic deletion of related rows and image. As result deleting Tag row related TagDetail is deleted, but image of TagDetail
is not deleted.
I have 2 models and new Tag())->d( is just debugging function
app/Tag.php :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use DB;
use App\MyAppModel;
use App\TagDetail;
use App\Http\Traits\funcsTrait;
use Illuminate\Validation\Rule;
use App\Rules\TagUniqueness;
class Tag extends MyAppModel
{
use funcsTrait;
protected $table = 'tags';
protected $primaryKey = 'id';
public $timestamps = false;
private $votes_tag_type= 'votesTagType';
public function getTableName() : string
{
return $this->table;
}
public function getPrimaryKey() : string
{
return $this->primaryKey;
}
public function tagDetail()
{
return $this->hasOne('App\TagDetail', 'tag_id', 'id');
}
protected static function boot() {
parent::boot();
static::deleting(function($tag) {
with (new Tag())->d( '<pre>Tag BOOT $tag::' . $tag->id);
$relatedTagDetail= $tag->tagDetail();
if ( !empty($relatedTagDetail) ) {
$relatedTagDetail->delete(); // I see this is triggered and relatedTagDetail is deleted
}
});
}
and app/TagDetail.php :
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use DB;
use App\MyAppModel;
use App\library\ImagePreviewSize;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use App\Http\Traits\funcsTrait;
class TagDetail extends MyAppModel
{
use Notifiable;
use funcsTrait;
protected $table = 'tag_details';
protected $primaryKey = 'id';
public $timestamps = false;
protected $fillable = [
'tag_id',
'image',
'description',
];
public function getTableName() : string
{
return $this->table;
}
public function getPrimaryKey() : string
{
return $this->primaryKey;
}
public function Tag()
{
return $this->belongsTo('App\Tag', 'tag_id');
}
protected static function boot() {
parent::boot();
static::deleting(function($tagDetail) { // THIS METHOD IS NOT TRIGGERED AT ALL!
with (new TagDetail())->d( '<pre>TagDetail BOOT $tagDetail::' . $tagDetail->id);
$tag_detail_image_path= TagDetail::getTagDetailImagePath($tagDetail->id, $tagDetail->image, true);
with (new TagDetail())->d( '<pre>TagDetail BOOT $tag_detail_image_path::' . $tag_detail_image_path);
TagDetail::deleteFileByPath($tag_detail_image_path, true);
});
}
Is something wrong in my models declarations ?
MODIFIED BLOCK # 2:
In my included file public/js/defaultBS41Backend/admin/tag.js I have method:
backendTag.prototype.deleteTag = function (id, name) {
confirmMsg('Do you want to delete "' + name + '" tag with all related data ?', function () {
var href = this_backend_home_url + "/admin/tag/destroy";
$.ajax({
type: "DELETE",
dataType: "json",
url: href,
data: {"id": id, "_token": this_csrf_token},
success: function (response) {
$("#btn_run_search").click()
},
error: function (error) {
alertMsg(error.responseJSON.message, 'Tag deleting error!', 'OK', 'fa fa-exclamation-triangle')
}
});
}
);
} // backendTag.prototype.deleteTag = function ( id, name ) {
and in control :
public function destroy(Request $request)
{
$id = $request->get('id');
$tag = MyTag::find($id);
if ($tag == null) {
return response()->json(['error_code' => 11, 'message' => 'Tag # "' . $id . '" not found!', 'tag' => null],
HTTP_RESPONSE_INTERNAL_SERVER_ERROR); //500
}
DB::beginTransaction();
try {
$tag->delete();
DB::commit();
} catch (Exception $e) {
DB::rollBack();
return response()->json(['error_code' => 1, 'message' => $e->getMessage(), 'tag' => null], HTTP_RESPONSE_INTERNAL_SERVER_ERROR);
}
return response()->json(['error_code' => 0, 'message' => ''], HTTP_RESPONSE_OK_RESOURCE_DELETED); // 204
} // public function delete(Request $request)
and in routes/web.php :
Route::group(['middleware' => ['auth', 'isVerified'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::delete('/tag/destroy', 'Admin\TagsController#destroy');
...
The issue is $tag->tagDetail(): You are using the query builder and deleting the model directly in the database. But the deleting event can only be triggered when you retrieve the model first.
Replace $relatedTagDetail = $tag->tagDetail(); with $relatedTagDetail= $tag->tagDetail;.

Yajra Relationship Call to undefined relationship [XXX_id] on model [App\XXX]

I get an error like below
Call to undefined relationship [hotel_id] on model [App\Room]
Model file Hotel.php
class Hotel extends Model {
protected $primaryKey = 'id';
protected $fillable = ['hotel_name', 'hotel_area'];
public function room() {
return $this->hasMany('App\Room', 'hotel_id');
}
}
Model File Room.php
class Room extends Model {
protected $primaryKey = 'id';
protected $fillable = ['hotel_id', 'room_name', 'bonus_sum'];
public function hotel() {
return $this->belongsTo('App\Hotel', 'hotel_id');
}
}
Controller File RoomController.php
public function apiRoom() {
$rooms = Room::with('hotel');
return Datatables::eloquent($rooms)
->addColumn('action', function ($rooms) {
return '<a onclick="editForm('.$rooms->id.')" data-toggle="tooltip" data-original-title="Edit"> <i class="fa fa-pencil text-inverse m-r-10"></i> </a>'.
'<a onclick="deleteData('.$rooms->id.')" data-toggle="tooltip" data-original-title="Close"> <i class="fa fa-close text-danger"></i> </a>';
})
->escapeColumns()
->toJson();
Route file web.php
Route::get('rooms-list', 'RoomController#list');
Route::resource('room', 'RoomController', [
'except' => ['create']
]);
Route::get('api/room', 'RoomController#apiRoom')->name('api.room');
Migrate create_new_room
$table->increments('id');
$table->integer('hotel_id')->unsigned();
$table->foreign('hotel_id')->references('id')->on('hotels')->onDelete('cascade');
$table->string('room_name');
$table->string('bonus_sum');
$table->timestamps();
View File
$('#room-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('api.room') }}",
columns: [
{data: 'id', name: 'id'},
{data: 'hotel.hotel_name', name: 'hotel.hotel_name'},
{data: 'room_name', name: 'room_name'},
{data: 'bonus_sum', name: 'bonus_sum'},
{data: 'action', name: 'action', orderable: false, searchable: false}
]
});
It's not related to the database. There is probably an error in the ajax file.
Your hasMany has been defined incorrectly in your Hotel class.
Per the API documentation here, you need to pass an instance of the Room class through.
public function room() {
return $this->hasMany(App\Room::class, 'hotel_id');
// OR
return $this->hasMany('App\Room', 'hotel_id');
}
Same applies your Room class.
public function hotel() {
return $this->belongsTo(App\Hotel::class, 'hotel_id');
// OR
return $this->belongsTo('App\Hotel', 'hotel_id');
}
-- EDIT --
On the comment, the belongsTo function has the definition:
belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
For your hotel() relationship on the Room class to work, you need to pass the related models key as the second parameter. You should write it like this:
public function hotel() {
return $this->belongsTo('App\Hotel', 'id', 'hotel_id');
}

Resources