if (!function_exists('dd')) {
function dd(...$vars)
{
// ألوان مختلفة ومتناغمة
$colors = [
'#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#c2c2f0',
'#ffb3e6', '#c2f0c2', '#ffccff', '#ffb3b3', '#c2c2c2'
];
$colorCount = count($colors);
// الحصول على معلومات إضافية
$backtrace = debug_backtrace();
$debugInfo = [
'line' => $backtrace[0]['line'],
'file' => $backtrace[0]['file'],
'function' => $backtrace[1]['function'] ?? 'N/A',
'request' => $_REQUEST,
'session' => $_SESSION ?? []
];
// عرض المعلومات الافتراضية إذا لم يتم تمرير أي متغيرات
if (empty($vars)) {
$vars[] = [
'file' => $debugInfo['file'],
'line' => $debugInfo['line'],
'function' => $debugInfo['function'],
'request' => $debugInfo['request'],
'session' => $debugInfo['session'],
];
}
echo '<div style="font-family: Arial, sans-serif; line-height: 1.5;">';
foreach ($vars as $index => $var) {
// حدد اللون بناءً على الفهرس
$color = $colors[$index % $colorCount];
echo '<div style="background-color: ' . $color . '; padding: 10px; border-radius: 5px; margin-bottom: 10px; color: #fff;">';
// عنوان البلوك
echo '<strong>Breakpoint (' . $debugInfo['file'] . ' on line ' . $debugInfo['line'] . ') ---> Function: ' . $debugInfo['function'] . '</strong><br>';
echo '<strong>Request Data:</strong><br>';
echo '<pre>' . json_encode($debugInfo['request'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
echo '<strong>Session Data:</strong><br>';
echo '<pre>' . json_encode($debugInfo['session'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
// عرض المتغيرات
echo '<strong>Variable ' . ($index + 1) . ':</strong><br>';
if (is_array($var) || is_object($var)) {
echo '<pre>' . json_encode($var, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
} elseif (is_bool($var) || is_null($var)) {
var_dump($var);
} else {
echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
}
echo '</div>';
}
echo '</div>';
die(1);
}
}
<?php
namespace App\Http\Controllers\Callback;
use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use Razorpay\Api\Api;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;
class RazorpayController extends Controller
{
public $gateway = "razorpay";
public $status = "paid";
public $settings;
/**
* Payment gateway callback
*
* @param Request $request
* @return mixed
*/
public function callback(Request $request)
{
try {
// Get payment gateway settings
$settings = AutomaticPaymentGateway::where('slug', $this->gateway)
->where('is_active', true)
->firstOrFail();
// Set settings
$this->settings = $settings;
// Get payment id
$payment_id = $request->get('payment_id');
// Get order id
$order_id = $request->get('order_id');
// Get signature
$signature = $request->get('signature');
// Get action
$action = $request->get('action');
// Check webhook event
if ( $payment_id && $order_id && $signature ) {
// Check if payment succeeded
$response = $this->verify($payment_id, $order_id, $signature);
// Check if payment succeeded
if ( is_array($response) && $response['success'] === TRUE) {
// Check if deposit callback
if ($action === "D") {
// Get saved webhook data in our database
$data = DepositWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Handle deposit callback
$this->deposit($data->user_id, $data->amount, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('deposit');
}
// Check if checkout callback
if ($action === "G") {
// Get saved webhook data in our database
$data = CheckoutWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Get cart
$cart = $data->data['cart'];
// Get user
$user = User::where('id', $data->data['buyer_id'])->firstOrFail();
// Handle deposit callback
$this->checkout($cart, $user, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('gigs');
}
}
}
// In case failed redirect to home page
return redirect('/');
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Verify if payment succeeded
*
* @param string $id
* @return array
*/
private function verify($payment_id, $order_id, $signature)
{
try {
// Get payment gateway keys
$key_id = $this->settings?->settings['key_id'];
$key_secret = $this->settings?->settings['key_secret'];
// Set api
$api = new Api($key_id, $key_secret);
// Let's verify first the signature
$api->utility->verifyPaymentSignature([
'razorpay_signature' => $signature,
'razorpay_payment_id' => $payment_id,
'razorpay_order_id' => $order_id
]);
// Fetch this payment
$fetch_payment = $api->payment->fetch($payment_id);
// Check if payment authorized
if ($fetch_payment->status === 'authorized') {
// Let capture this payment
$payment = $api->payment->fetch($payment_id)->capture([
'amount' => $fetch_payment->amount,
'currency' => $fetch_payment->currency
]);
} else if ($fetch_payment->status === 'captured') {
// Set payment
$payment = $fetch_payment;
} else {
// Payment failed
return [
'success' => false,
'message' => __('messages.t_we_could_not_handle_ur_payment')
];
}
// Check if payment succeeded
if ( $payment && $payment->status === 'captured' ) {
// Done
return [
'success' => true,
'response' => $payment
];
} else {
// Failed
return [
'success' => false,
'message' => __('messages.t_error_stripe_payment_failed')
];
}
} catch (\Throwable $th) {
// Error
return [
'success' => false,
'message' => __('messages.t_toast_something_went_wrong')
];
}
}
/**
* Deposit funds into user's account
*
* @param int $user_id
* @param mixed $amount
* @param string $payment_id
* @return void
*/
private function deposit($user_id, $amount, $payment_id)
{
try {
// Set amount
$amount = convertToNumber($amount);
// Calculate fee from this amount
$fee = convertToNumber($this->fee('deposit', $amount));
// Make transaction
$deposit = new DepositTransaction();
$deposit->user_id = $user_id;
$deposit->transaction_id = $payment_id;
$deposit->payment_method = $this->gateway;
$deposit->amount_total = $amount;
$deposit->amount_fee = $fee;
$deposit->amount_net = $amount - $fee;
$deposit->currency = $this->settings->currency;
$deposit->exchange_rate = $this->settings->exchange_rate;
$deposit->status = $this->status;
$deposit->ip_address = request()->ip();
$deposit->save();
// Get user
$user = User::where('id', $user_id)->firstOrFail();
// Add funds
$user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
$user->save();
// Send a notification
$this->notification('deposit', $user);
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Checkout
*
* @param array $cart
* @param object $user
* @param string $payment_id
* @return void
*/
private function checkout($cart, $user, $payment_id)
{
try {
// Set empty variables
$subtotal = 0;
$total = 0;
$tax = 0;
$fee = 0;
// Loop through items in cart
foreach ($cart as $key => $item) {
// Add gig price to subtotal
$subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);
// Check if item has upgrades
$upgrades = $item['upgrades'];
// Loop through upgrades
if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
// Loop through upgrades
foreach ($upgrades as $j => $upgrade) {
// Check if upgrade checked
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Add upgrade price to subtotal
$subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);
}
}
}
}
// Get commission settings
$commission_settings = settings('commission');
// Check if taxes enabled
if ($commission_settings->enable_taxes) {
// Check if type of taxes percentage
if ($commission_settings->tax_type === 'percentage') {
// Set tax amount
$tax = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);
} else {
// Set tax amount
$tax = convertToNumber($commission_settings->tax_value);
}
}
// Calculate payment gateway fee
$fee = convertToNumber($this->fee( 'gigs', $subtotal ));
// Calculate total price
$total = $subtotal + $tax + $fee;
// Get user billing address
$billing_info = $user->billing;
// Set unique id for this order
$uid = uid();
// Get buyer id
$buyer_id = $user->id;
// Save order
$order = new Order();
$order->uid = $uid;
$order->buyer_id = $buyer_id;
$order->total_value = $total;
$order->subtotal_value = $subtotal;
$order->taxes_value = $tax;
$order->save();
// Loop through items in cart
foreach ($cart as $key => $item) {
// Get gig
$gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();
// Check if gig exists
if ($gig) {
// Set quantity
$quantity = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;
// Set gig upgrades
$upgrades = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];
// Set empty variable
$upgrades_amount = 0;
// Loop through upgrades
foreach ($upgrades as $index => $upgrade) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
$upgrades_amount += convertToNumber($upgrade['price']) * $quantity;
}
}
// Set item total price
$item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );
// Calculate commission first
if ($commission_settings->commission_from === 'orders') {
// Check commission type
if ($commission_settings->commission_type === 'percentage') {
// Calculate commission
$commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
} else {
// Fixed amount
$commission = convertToNumber($commission_settings->commission_value);
}
} else {
// No commission
$commission = 0;
}
// Save order item
$order_item = new OrderItem();
$order_item->uid = uid();
$order_item->order_id = $order->id;
$order_item->gig_id = $gig->id;
$order_item->owner_id = $gig->user_id;
$order_item->quantity = $quantity;
$order_item->has_upgrades = count($upgrades) ? true : false;
$order_item->total_value = $item_total;
$order_item->profit_value = $item_total - $commission;
$order_item->commission_value = $commission;
$order_item->save();
// Loop through upgrades again
foreach ($upgrades as $index => $value) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Get upgrade
$upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
// Check if upgrade exists
if ($upgrade) {
// Save item upgrade
$order_item_upgrade = new OrderItemUpgrade();
$order_item_upgrade->item_id = $order_item->id;
$order_item_upgrade->title = $upgrade->title;
$order_item_upgrade->price = $upgrade->price;
$order_item_upgrade->extra_days = $upgrade->extra_days;
$order_item_upgrade->save();
}
}
}
// Update seller pending balance
$gig->owner()->update([
'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
]);
// Increment orders in queue
$gig->increment('orders_in_queue');
// Order item placed successfully
// Let's notify the seller about new order
$gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );
// Check user's level
check_user_level($buyer_id);
// Send notification
notification([
'text' => 't_u_received_new_order_seller',
'action' => url('seller/orders/details', $order_item->uid),
'user_id' => $order_item->owner_id
]);
}
}
// Save invoice
$invoice = new OrderInvoice();
$invoice->order_id = $order->id;
$invoice->payment_method = $this->gateway;
$invoice->payment_id = $payment_id;
$invoice->firstname = $billing_info->firstname ?? $user->username;
$invoice->lastname = $billing_info->lastname ?? $user->username;
$invoice->email = $user->email;
$invoice->company = !empty($billing_info->company) ? clean($billing_info->company) : null;
$invoice->address = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
$invoice->status = 'paid';
$invoice->save();
// Update balance
$user->update([
'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
]);
// Now everything succeeded
// Let's empty the cart
session()->forget('cart');
// Now let's notify the buyer that his order has been placed
$user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Calculate fee value
*
* @param string $type
* @param mixed $amount
* @return mixed
*/
private function fee($type, $amount = null)
{
try {
// Set amount for deposit
$amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;
// Remove long decimal
$amount = convertToNumber( number_format($amount, 2, '.', '') );
// Check fee type
switch ($type) {
// Deposit
case 'deposit':
// Get deposit fixed fee
if (isset($this->settings->fixed_fee['deposit'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get deposit percentage fee
if (isset($this->settings->percentage_fee['deposit'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return number_format($fee_value, 2, '.', '');
break;
// Gigs
case 'gigs':
// Get gigs fixed fee
if (isset($this->settings->fixed_fee['gigs'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get gigs percentage fee
if (isset($this->settings->percentage_fee['gigs'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return $fee_value;
break;
}
} catch (\Throwable $th) {
// Something went wrong
return 0;
}
}
/**
* Calculate exchange rate
*
* @param mixed $amount
* @param mixed $exchange_rate
* @param boolean $formatted
* @param string $currency
* @return mixed
*/
private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
{
try {
// Convert amount to number
$amount = convertToNumber($amount);
// Get currency settings
$currency_settings = settings('currency');
// Get default currency exchange rate
$default_exchange_rate = convertToNumber($currency_settings->exchange_rate);
// Get exchanged amount
$exchanged_amount = convertToNumber( $amount * $default_exchange_rate / $exchange_rate );
// Check if we have to return a formatted value
if ($formatted) {
return money( $exchanged_amount, $currency, true )->format();
}
// Return max deposit
return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));
} catch (\Throwable $th) {
// Something went wrong
return $amount;
}
}
/**
* Send a notification to user
*
* @param string $type
* @param object $user
* @return void
*/
private function notification($type, $user)
{
try {
// Check notification type
switch ($type) {
// Deposit funds
case 'deposit':
break;
// Gig checkout
case 'gig':
break;
// Project payment
case 'project':
break;
// Bid payment
case 'bid':
break;
}
} catch (\Throwable $th) {
// Something went wrong
return;
}
}
/**
* Redirecting
*
* @param string $type
* @param string $status
* @return void
*/
private function redirect($type, $status = 'success')
{
// Check where to redirect
switch ($type) {
// Deposit history
case 'deposit':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
// Gigs order
case 'gigs':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
}
}
}
<?php
namespace App\Http\Controllers\Callback;
use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;
class PaymobPkController extends Controller
{
public $gateway = "paymob-pk";
public $status = "paid";
public $settings;
/**
* Payment gateway callback
*
* @param Request $request
* @return mixed
*/
public function callback(Request $request)
{
try {
// Get payment gateway settings
$settings = AutomaticPaymentGateway::where('slug', $this->gateway)
->where('is_active', true)
->firstOrFail();
// Set settings
$this->settings = $settings;
// Get transaction id
$transaction_id = $request->get('id');
// Check webhook event
if ( $transaction_id ) {
// Check if payment succeeded
$response = $this->verify($transaction_id);
// Check if payment succeeded
if ( is_array($response) && $response['success'] === TRUE) {
// Get action
$action = $response['response']['obj']['order']['shipping_data']['shipping_method'];
// Check if deposit callback
if ( isset($action) && $action === "D" ) {
// Get saved webhook data in our database
$data = DepositWebhook::where('payment_id', $transaction_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Handle deposit callback
$this->deposit($data->user_id, $data->amount, $transaction_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('deposit');
}
// Check if checkout callback
if ( isset($action) && $action === "G" ) {
// Get saved webhook data in our database
$data = CheckoutWebhook::where('payment_id', $transaction_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Get cart
$cart = $data->data['cart'];
// Get user
$user = User::where('id', $data->data['buyer_id'])->firstOrFail();
// Handle deposit callback
$this->checkout($cart, $user, $transaction_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('gigs');
}
}
}
// In case failed redirect to home page
return redirect('/');
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Verify if payment succeeded
*
* @param string $id
* @return array
*/
private function verify($id)
{
try {
// Get auth token
$auth = Http::acceptJson()->post('https://pakistan.paymob.com/api/auth/tokens', [
'api_key' => $this->settings?->settings['api_key'],
])->json();
// Check if token is set
if (isset($auth['token'])) {
// Get payment details
$payment = Http::withToken($auth['token'])
->get("https://pakistan.paymob.com/api/acceptance/transactions/$id")
->json();
// Check if payment succeeded
if ( is_array($payment) && isset($payment['obj']['success']) && $payment['obj']['success'] == true ) {
// Done
return [
'success' => true,
'response' => $payment
];
} else {
// Failed
return [
'success' => false,
'message' => __('messages.t_error_stripe_payment_failed')
];
}
} else {
// Failed
return [
'success' => false,
'message' => __('messages.t_error_stripe_payment_failed')
];
}
} catch (\Throwable $th) {
// Error
return [
'success' => false,
'message' => __('messages.t_toast_something_went_wrong')
];
}
}
/**
* Deposit funds into user's account
*
* @param int $user_id
* @param mixed $amount
* @param string $payment_id
* @return void
*/
private function deposit($user_id, $amount, $payment_id)
{
try {
// Set amount
$amount = convertToNumber($amount);
// Calculate fee from this amount
$fee = convertToNumber($this->fee('deposit', $amount));
// Make transaction
$deposit = new DepositTransaction();
$deposit->user_id = $user_id;
$deposit->transaction_id = $payment_id;
$deposit->payment_method = $this->gateway;
$deposit->amount_total = $amount;
$deposit->amount_fee = $fee;
$deposit->amount_net = $amount - $fee;
$deposit->currency = $this->settings->currency;
$deposit->exchange_rate = $this->settings->exchange_rate;
$deposit->status = $this->status;
$deposit->ip_address = request()->ip();
$deposit->save();
// Get user
$user = User::where('id', $user_id)->firstOrFail();
// Add funds
$user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
$user->save();
// Send a notification
$this->notification('deposit', $user);
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Checkout
*
* @param array $cart
* @param object $user
* @param string $payment_id
* @return void
*/
private function checkout($cart, $user, $payment_id)
{
try {
// Set empty variables
$subtotal = 0;
$total = 0;
$tax = 0;
$fee = 0;
// Loop through items in cart
foreach ($cart as $key => $item) {
// Add gig price to subtotal
$subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);
// Check if item has upgrades
$upgrades = $item['upgrades'];
// Loop through upgrades
if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
// Loop through upgrades
foreach ($upgrades as $j => $upgrade) {
// Check if upgrade checked
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Add upgrade price to subtotal
$subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);
}
}
}
}
// Get commission settings
$commission_settings = settings('commission');
// Check if taxes enabled
if ($commission_settings->enable_taxes) {
// Check if type of taxes percentage
if ($commission_settings->tax_type === 'percentage') {
// Set tax amount
$tax = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);
} else {
// Set tax amount
$tax = convertToNumber($commission_settings->tax_value);
}
}
// Calculate payment gateway fee
$fee = convertToNumber($this->fee( 'gigs', $subtotal ));
// Calculate total price
$total = $subtotal + $tax + $fee;
// Get user billing address
$billing_info = $user->billing;
// Set unique id for this order
$uid = uid();
// Get buyer id
$buyer_id = $user->id;
// Save order
$order = new Order();
$order->uid = $uid;
$order->buyer_id = $buyer_id;
$order->total_value = $total;
$order->subtotal_value = $subtotal;
$order->taxes_value = $tax;
$order->save();
// Loop through items in cart
foreach ($cart as $key => $item) {
// Get gig
$gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();
// Check if gig exists
if ($gig) {
// Set quantity
$quantity = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;
// Set gig upgrades
$upgrades = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];
// Set empty variable
$upgrades_amount = 0;
// Loop through upgrades
foreach ($upgrades as $index => $upgrade) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
$upgrades_amount += convertToNumber($upgrade['price']) * $quantity;
}
}
// Set item total price
$item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );
// Calculate commission first
if ($commission_settings->commission_from === 'orders') {
// Check commission type
if ($commission_settings->commission_type === 'percentage') {
// Calculate commission
$commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
} else {
// Fixed amount
$commission = convertToNumber($commission_settings->commission_value);
}
} else {
// No commission
$commission = 0;
}
// Save order item
$order_item = new OrderItem();
$order_item->uid = uid();
$order_item->order_id = $order->id;
$order_item->gig_id = $gig->id;
$order_item->owner_id = $gig->user_id;
$order_item->quantity = $quantity;
$order_item->has_upgrades = count($upgrades) ? true : false;
$order_item->total_value = $item_total;
$order_item->profit_value = $item_total - $commission;
$order_item->commission_value = $commission;
$order_item->save();
// Loop through upgrades again
foreach ($upgrades as $index => $value) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Get upgrade
$upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
// Check if upgrade exists
if ($upgrade) {
// Save item upgrade
$order_item_upgrade = new OrderItemUpgrade();
$order_item_upgrade->item_id = $order_item->id;
$order_item_upgrade->title = $upgrade->title;
$order_item_upgrade->price = $upgrade->price;
$order_item_upgrade->extra_days = $upgrade->extra_days;
$order_item_upgrade->save();
}
}
}
// Update seller pending balance
$gig->owner()->update([
'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
]);
// Increment orders in queue
$gig->increment('orders_in_queue');
// Order item placed successfully
// Let's notify the seller about new order
$gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );
// Check user's level
check_user_level($buyer_id);
// Send notification
notification([
'text' => 't_u_received_new_order_seller',
'action' => url('seller/orders/details', $order_item->uid),
'user_id' => $order_item->owner_id
]);
}
}
// Save invoice
$invoice = new OrderInvoice();
$invoice->order_id = $order->id;
$invoice->payment_method = $this->gateway;
$invoice->payment_id = $payment_id;
$invoice->firstname = $billing_info->firstname ?? $user->username;
$invoice->lastname = $billing_info->lastname ?? $user->username;
$invoice->email = $user->email;
$invoice->company = !empty($billing_info->company) ? clean($billing_info->company) : null;
$invoice->address = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
$invoice->status = 'paid';
$invoice->save();
// Update balance
$user->update([
'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
]);
// Now everything succeeded
// Let's empty the cart
session()->forget('cart');
// Now let's notify the buyer that his order has been placed
$user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Calculate fee value
*
* @param string $type
* @param mixed $amount
* @return mixed
*/
private function fee($type, $amount = null)
{
try {
// Set amount for deposit
$amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;
// Remove long decimal
$amount = convertToNumber( number_format($amount, 2, '.', '') );
// Check fee type
switch ($type) {
// Deposit
case 'deposit':
// Get deposit fixed fee
if (isset($this->settings->fixed_fee['deposit'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get deposit percentage fee
if (isset($this->settings->percentage_fee['deposit'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return number_format($fee_value, 2, '.', '');
break;
// Gigs
case 'gigs':
// Get gigs fixed fee
if (isset($this->settings->fixed_fee['gigs'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get gigs percentage fee
if (isset($this->settings->percentage_fee['gigs'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return $fee_value;
break;
}
} catch (\Throwable $th) {
// Something went wrong
return 0;
}
}
/**
* Calculate exchange rate
*
* @param mixed $amount
* @param mixed $exchange_rate
* @param boolean $formatted
* @param string $currency
* @return mixed
*/
private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
{
try {
// Convert amount to number
$amount = convertToNumber($amount);
// Get currency settings
$currency_settings = settings('currency');
// Get default currency exchange rate
$default_exchange_rate = convertToNumber($currency_settings->exchange_rate);
// Get exchanged amount
$exchanged_amount = convertToNumber( $amount * $default_exchange_rate / $exchange_rate );
// Check if we have to return a formatted value
if ($formatted) {
return money( $exchanged_amount, $currency, true )->format();
}
// Return max deposit
return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));
} catch (\Throwable $th) {
// Something went wrong
return $amount;
}
}
/**
* Send a notification to user
*
* @param string $type
* @param object $user
* @return void
*/
private function notification($type, $user)
{
try {
// Check notification type
switch ($type) {
// Deposit funds
case 'deposit':
break;
// Gig checkout
case 'gig':
break;
// Project payment
case 'project':
break;
// Bid payment
case 'bid':
break;
}
} catch (\Throwable $th) {
// Something went wrong
return;
}
}
/**
* Redirecting
*
* @param string $type
* @param string $status
* @return void
*/
private function redirect($type, $status = 'success')
{
// Check where to redirect
switch ($type) {
// Deposit history
case 'deposit':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
// Gigs order
case 'gigs':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
}
}
}
<?php
namespace App\Http\Controllers\Callback;
use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;
class FlutterwaveController extends Controller
{
public $gateway = "flutterwave";
public $status = "paid";
public $settings;
/**
* Payment gateway callback
*
* @param Request $request
* @return mixed
*/
public function callback(Request $request)
{
try {
// Get payment gateway settings
$settings = AutomaticPaymentGateway::where('slug', $this->gateway)
->where('is_active', true)
->firstOrFail();
// Set settings
$this->settings = $settings;
// Get transaction id
$transaction_id = $request->get('transaction_id');
// Check webhook event
if ( $transaction_id ) {
// Check if payment succeeded
$response = $this->verify($transaction_id);
// Check if payment succeeded
if ( is_array($response) && $response['success'] === TRUE) {
// Get order id
$order_id = $response['response']['data']['tx_ref'];
// Check if deposit callback
if (Str::startsWith($order_id, "DD")) {
// Get saved webhook data in our database
$data = DepositWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Handle deposit callback
$this->deposit($data->user_id, $data->amount, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('deposit');
}
// Check if checkout callback
if (Str::startsWith($order_id, "GG")) {
// Get saved webhook data in our database
$data = CheckoutWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Get cart
$cart = $data->data['cart'];
// Get user
$user = User::where('id', $data->data['buyer_id'])->firstOrFail();
// Handle deposit callback
$this->checkout($cart, $user, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('gigs');
}
}
}
// In case failed redirect to home page
return redirect('/');
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Verify if payment succeeded
*
* @param string $id
* @return array
*/
private function verify($id)
{
try {
// Get payment gateway keys
$secret_key = $this->settings?->settings['secret_key'];
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $secret_key,
'Accept' => 'application/json',
])->get("https://api.flutterwave.com/v3/transactions/$id/verify")->json();
// Check if payment succeeded
if ( is_array($response) && $response['status'] === 'success' ) {
// Done
return [
'success' => true,
'response' => $response
];
} else {
// Failed
return [
'success' => false,
'message' => __('messages.t_error_stripe_payment_failed')
];
}
} catch (\Throwable $th) {
// Error
return [
'success' => false,
'message' => __('messages.t_toast_something_went_wrong')
];
}
}
/**
* Deposit funds into user's account
*
* @param int $user_id
* @param mixed $amount
* @param string $payment_id
* @return void
*/
private function deposit($user_id, $amount, $payment_id)
{
try {
// Set amount
$amount = convertToNumber($amount);
// Calculate fee from this amount
$fee = convertToNumber($this->fee('deposit', $amount));
// Make transaction
$deposit = new DepositTransaction();
$deposit->user_id = $user_id;
$deposit->transaction_id = $payment_id;
$deposit->payment_method = $this->gateway;
$deposit->amount_total = $amount;
$deposit->amount_fee = $fee;
$deposit->amount_net = $amount - $fee;
$deposit->currency = $this->settings->currency;
$deposit->exchange_rate = $this->settings->exchange_rate;
$deposit->status = $this->status;
$deposit->ip_address = request()->ip();
$deposit->save();
// Get user
$user = User::where('id', $user_id)->firstOrFail();
// Add funds
$user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
$user->save();
// Send a notification
$this->notification('deposit', $user);
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Checkout
*
* @param array $cart
* @param object $user
* @param string $payment_id
* @return void
*/
private function checkout($cart, $user, $payment_id)
{
try {
// Set empty variables
$subtotal = 0;
$total = 0;
$tax = 0;
$fee = 0;
// Loop through items in cart
foreach ($cart as $key => $item) {
// Add gig price to subtotal
$subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);
// Check if item has upgrades
$upgrades = $item['upgrades'];
// Loop through upgrades
if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
// Loop through upgrades
foreach ($upgrades as $j => $upgrade) {
// Check if upgrade checked
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Add upgrade price to subtotal
$subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);
}
}
}
}
// Get commission settings
$commission_settings = settings('commission');
// Check if taxes enabled
if ($commission_settings->enable_taxes) {
// Check if type of taxes percentage
if ($commission_settings->tax_type === 'percentage') {
// Set tax amount
$tax = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);
} else {
// Set tax amount
$tax = convertToNumber($commission_settings->tax_value);
}
}
// Calculate payment gateway fee
$fee = convertToNumber($this->fee( 'gigs', $subtotal ));
// Calculate total price
$total = $subtotal + $tax + $fee;
// Get user billing address
$billing_info = $user->billing;
// Set unique id for this order
$uid = uid();
// Get buyer id
$buyer_id = $user->id;
// Save order
$order = new Order();
$order->uid = $uid;
$order->buyer_id = $buyer_id;
$order->total_value = $total;
$order->subtotal_value = $subtotal;
$order->taxes_value = $tax;
$order->save();
// Loop through items in cart
foreach ($cart as $key => $item) {
// Get gig
$gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();
// Check if gig exists
if ($gig) {
// Set quantity
$quantity = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;
// Set gig upgrades
$upgrades = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];
// Set empty variable
$upgrades_amount = 0;
// Loop through upgrades
foreach ($upgrades as $index => $upgrade) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
$upgrades_amount += convertToNumber($upgrade['price']) * $quantity;
}
}
// Set item total price
$item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );
// Calculate commission first
if ($commission_settings->commission_from === 'orders') {
// Check commission type
if ($commission_settings->commission_type === 'percentage') {
// Calculate commission
$commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
} else {
// Fixed amount
$commission = convertToNumber($commission_settings->commission_value);
}
} else {
// No commission
$commission = 0;
}
// Save order item
$order_item = new OrderItem();
$order_item->uid = uid();
$order_item->order_id = $order->id;
$order_item->gig_id = $gig->id;
$order_item->owner_id = $gig->user_id;
$order_item->quantity = $quantity;
$order_item->has_upgrades = count($upgrades) ? true : false;
$order_item->total_value = $item_total;
$order_item->profit_value = $item_total - $commission;
$order_item->commission_value = $commission;
$order_item->save();
// Loop through upgrades again
foreach ($upgrades as $index => $value) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Get upgrade
$upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
// Check if upgrade exists
if ($upgrade) {
// Save item upgrade
$order_item_upgrade = new OrderItemUpgrade();
$order_item_upgrade->item_id = $order_item->id;
$order_item_upgrade->title = $upgrade->title;
$order_item_upgrade->price = $upgrade->price;
$order_item_upgrade->extra_days = $upgrade->extra_days;
$order_item_upgrade->save();
}
}
}
// Update seller pending balance
$gig->owner()->update([
'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
]);
// Increment orders in queue
$gig->increment('orders_in_queue');
// Order item placed successfully
// Let's notify the seller about new order
$gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );
// Check user's level
check_user_level($buyer_id);
// Send notification
notification([
'text' => 't_u_received_new_order_seller',
'action' => url('seller/orders/details', $order_item->uid),
'user_id' => $order_item->owner_id
]);
}
}
// Save invoice
$invoice = new OrderInvoice();
$invoice->order_id = $order->id;
$invoice->payment_method = $this->gateway;
$invoice->payment_id = $payment_id;
$invoice->firstname = $billing_info->firstname ?? $user->username;
$invoice->lastname = $billing_info->lastname ?? $user->username;
$invoice->email = $user->email;
$invoice->company = !empty($billing_info->company) ? clean($billing_info->company) : null;
$invoice->address = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
$invoice->status = 'paid';
$invoice->save();
// Update balance
$user->update([
'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
]);
// Now everything succeeded
// Let's empty the cart
session()->forget('cart');
// Now let's notify the buyer that his order has been placed
$user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Calculate fee value
*
* @param string $type
* @param mixed $amount
* @return mixed
*/
private function fee($type, $amount = null)
{
try {
// Set amount for deposit
$amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;
// Remove long decimal
$amount = convertToNumber( number_format($amount, 2, '.', '') );
// Check fee type
switch ($type) {
// Deposit
case 'deposit':
// Get deposit fixed fee
if (isset($this->settings->fixed_fee['deposit'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get deposit percentage fee
if (isset($this->settings->percentage_fee['deposit'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return number_format($fee_value, 2, '.', '');
break;
// Gigs
case 'gigs':
// Get gigs fixed fee
if (isset($this->settings->fixed_fee['gigs'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get gigs percentage fee
if (isset($this->settings->percentage_fee['gigs'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return $fee_value;
break;
}
} catch (\Throwable $th) {
// Something went wrong
return 0;
}
}
/**
* Calculate exchange rate
*
* @param mixed $amount
* @param mixed $exchange_rate
* @param boolean $formatted
* @param string $currency
* @return mixed
*/
private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
{
try {
// Convert amount to number
$amount = convertToNumber($amount);
// Get currency settings
$currency_settings = settings('currency');
// Get default currency exchange rate
$default_exchange_rate = convertToNumber($currency_settings->exchange_rate);
// Get exchanged amount
$exchanged_amount = convertToNumber( $amount * $default_exchange_rate / $exchange_rate );
// Check if we have to return a formatted value
if ($formatted) {
return money( $exchanged_amount, $currency, true )->format();
}
// Return max deposit
return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));
} catch (\Throwable $th) {
// Something went wrong
return $amount;
}
}
/**
* Send a notification to user
*
* @param string $type
* @param object $user
* @return void
*/
private function notification($type, $user)
{
try {
// Check notification type
switch ($type) {
// Deposit funds
case 'deposit':
break;
// Gig checkout
case 'gig':
break;
// Project payment
case 'project':
break;
// Bid payment
case 'bid':
break;
}
} catch (\Throwable $th) {
// Something went wrong
return;
}
}
/**
* Redirecting
*
* @param string $type
* @param string $status
* @return void
*/
private function redirect($type, $status = 'success')
{
// Check where to redirect
switch ($type) {
// Deposit history
case 'deposit':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
// Gigs order
case 'gigs':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
}
}
}
<?php
namespace App\Http\Controllers\Callback;
use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use App\Models\AffiliateTransaction;
use App\Models\AffiliateRegisteration;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;
use Srmklive\PayPal\Services\PayPal as PayPalClient;
class PaypalController extends Controller
{
public $gateway = "paypal";
public $status = "paid";
public $settings;
/**
* Payment gateway callback
*
* @param Request $request
* @return mixed
*/
public function callback(Request $request)
{
try {
// Get payment gateway settings
$settings = AutomaticPaymentGateway::where('slug', $this->gateway)
->where('is_active', true)
->firstOrFail();
// Set settings
$this->settings = $settings;
// Get transaction id
$transaction_id = $request->get('order');
// Check webhook event
if ( $transaction_id ) {
// Check if payment succeeded
$response = $this->verify($transaction_id);
// Check if payment succeeded
if ( is_array($response) && $response['success'] === TRUE) {
// Get order id
$order_id = $response['response']['purchase_units'][0]['payments']['captures'][0]['invoice_id'];
// Check if deposit callback
if (Str::startsWith($order_id, "D-")) {
// Get saved webhook data in our database
$data = DepositWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Handle deposit callback
$this->deposit($data->user_id, $data->amount, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('deposit');
}
// Check if checkout callback
if (Str::startsWith($order_id, "G-")) {
// Get saved webhook data in our database
$data = CheckoutWebhook::where('payment_id', $order_id)
->where('payment_method', $this->gateway)
->where('status', 'pending')
->firstOrFail();
// Get cart
$cart = $data->data['cart'];
// Get user
$user = User::where('id', $data->data['buyer_id'])->firstOrFail();
// Handle deposit callback
$this->checkout($cart, $user, $order_id);
// Delete saved webhook data in our database
$data->delete();
// Redirecting
return $this->redirect('gigs');
}
}
}
// In case failed redirect to home page
return redirect('/');
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Verify if payment succeeded
*
* @param string $id
* @return array
*/
private function verify($id)
{
// Get payment gateway keys
$client_id = $this->settings?->settings['client_id'];
$client_secret = $this->settings?->settings['client_secret'];
$env = $this->settings?->settings['env'];
// Set gateway config
$config = [
'mode' => 'sandbox' ,
'live' => [
'client_id' => $client_id,
'client_secret' => $client_secret,
'app_id' => '',
],
'sandbox' => [
'client_id' => $client_id,
'client_secret' => $client_secret,
'app_id' => '',
],
'payment_action' => 'Sale',
'currency' => $this->settings?->currency,
'notify_url' => 'https://2lancer.ma/paypal/notify',
'locale' => 'en_US',
'validate_ssl' => true,
];
// Set paypal provider and config
$client = new PayPalClient();
// Set client credentials
$client->setApiCredentials($config);
// Get paypal access token
$client->getAccessToken();
// Capture this order
$order = $client->capturePaymentOrder($id);
// Check if payment succeeded
if ( is_array($order) && isset($order['status']) && $order['status'] === 'COMPLETED' ) {
// Done
return [
'success' => true,
'response' => $order
];
} else {
// Failed
return [
'success' => false,
'message' => __('messages.t_error_stripe_payment_failed')
];
}
}
/**
* Deposit funds into user's account
*
* @param int $user_id
* @param mixed $amount
* @param string $payment_id
* @return void
*/
private function deposit($user_id, $amount, $payment_id)
{
try {
// Set amount
$amount = convertToNumber($amount);
// Calculate fee from this amount
$fee = convertToNumber($this->fee('deposit', $amount));
// Make transaction
$deposit = new DepositTransaction();
$deposit->user_id = $user_id;
$deposit->transaction_id = $payment_id;
$deposit->payment_method = $this->gateway;
$deposit->amount_total = $amount;
$deposit->amount_fee = $fee;
$deposit->amount_net = $amount - $fee;
$deposit->currency = $this->settings->currency;
$deposit->exchange_rate = $this->settings->exchange_rate;
$deposit->status = $this->status;
$deposit->ip_address = request()->ip();
$deposit->save();
// Get user
$user = User::where('id', $user_id)->firstOrFail();
// Add funds
$user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
$user->save();
// Send a notification
$this->notification('deposit', $user);
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Checkout
*
* @param array $cart
* @param object $user
* @param string $payment_id
* @return void
*/
private function checkout($cart, $user, $payment_id)
{
try {
// Set empty variables
$subtotal = 0;
$total = 0;
$tax = 0;
$fee = 0;
// Loop through items in cart
foreach ($cart as $key => $item) {
// Add gig price to subtotal
$subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);
// Check if item has upgrades
$upgrades = $item['upgrades'];
// Loop through upgrades
if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
// Loop through upgrades
foreach ($upgrades as $j => $upgrade) {
// Check if upgrade checked
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Add upgrade price to subtotal
$subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);
}
}
}
}
// Get commission settings
$commission_settings = settings('commission');
// Check if taxes enabled
if ($commission_settings->enable_taxes) {
// Check if type of taxes percentage
if ($commission_settings->tax_type === 'percentage') {
// Set tax amount
$tax = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);
} else {
// Set tax amount
$tax = convertToNumber($commission_settings->tax_value);
}
}
// Calculate payment gateway fee
$fee = convertToNumber($this->fee( 'gigs', $subtotal ));
// Calculate total price
$total = $subtotal + $tax + $fee;
// Get user billing address
$billing_info = $user->billing;
// Set unique id for this order
$uid = uid();
// Get buyer id
$buyer_id = $user->id;
// Save order
$order = new Order();
$order->uid = $uid;
$order->buyer_id = $buyer_id;
$order->total_value = $total;
$order->subtotal_value = $subtotal;
$order->taxes_value = $tax;
$order->save();
// Loop through items in cart
foreach ($cart as $key => $item) {
// Get gig
$gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();
// Check if gig exists
if ($gig) {
// Set quantity
$quantity = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;
// Set gig upgrades
$upgrades = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];
// Set empty variable
$upgrades_amount = 0;
// Loop through upgrades
foreach ($upgrades as $index => $upgrade) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
$upgrades_amount += convertToNumber($upgrade['price']) * $quantity;
}
}
// Set item total price
$item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );
// Calculate commission first
if ($commission_settings->commission_from === 'orders') {
// Check commission type
if ($commission_settings->commission_type === 'percentage') {
// Calculate commission
$commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
} else {
// Fixed amount
$commission = convertToNumber($commission_settings->commission_value);
}
} else {
// No commission
$commission = 0;
}
// Save order item
$order_item = new OrderItem();
$order_item->uid = uid();
$order_item->order_id = $order->id;
$order_item->gig_id = $gig->id;
$order_item->owner_id = $gig->user_id;
$order_item->quantity = $quantity;
$order_item->has_upgrades = count($upgrades) ? true : false;
$order_item->total_value = $item_total;
$order_item->profit_value = $item_total - $commission;
$order_item->commission_value = $commission;
$order_item->save();
// Loop through upgrades again
foreach ($upgrades as $index => $value) {
// Check if upgrade is selected
if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
// Get upgrade
$upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
// Check if upgrade exists
if ($upgrade) {
// Save item upgrade
$order_item_upgrade = new OrderItemUpgrade();
$order_item_upgrade->item_id = $order_item->id;
$order_item_upgrade->title = $upgrade->title;
$order_item_upgrade->price = $upgrade->price;
$order_item_upgrade->extra_days = $upgrade->extra_days;
$order_item_upgrade->save();
}
}
}
// Update seller pending balance
$gig->owner()->update([
'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
]);
// Increment orders in queue
$gig->increment('orders_in_queue');
// Order item placed successfully
// Let's notify the seller about new order
$gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );
// Check user's level
check_user_level($buyer_id);
// Send notification
notification([
'text' => 't_u_received_new_order_seller',
'action' => url('seller/orders/details', $order_item->uid),
'user_id' => $order_item->owner_id
]);
}
}
// Save invoice
$invoice = new OrderInvoice();
$invoice->order_id = $order->id;
$invoice->payment_method = $this->gateway;
$invoice->payment_id = $payment_id;
$invoice->firstname = $billing_info->firstname ?? $user->username;
$invoice->lastname = $billing_info->lastname ?? $user->username;
$invoice->email = $user->email;
$invoice->company = !empty($billing_info->company) ? clean($billing_info->company) : null;
$invoice->address = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
$invoice->status = 'paid';
$invoice->save();
// Update balance
$user->update([
'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
]);
// Now everything succeeded
// Let's empty the cart
session()->forget('cart');
// Now let's notify the buyer that his order has been placed
$user->notify( (new OrderPlaced($order, $total))->locale(config('app.locale')) );
//check for affiliate registeration and check if expired
if(settings('affiliate')->is_enabled)
{
$affiliate_register =AffiliateRegisteration::where('user_id', $buyer_id)
->where('expires_at','>',now())
->first() ;
if($affiliate_register){
// get referral user
$referral_user = User::where('id', $affiliate_register->referral_id)->first();
// calculate referral earning
$referral_earning =(convertToNumber(settings('affiliate')->profit_percentage)/100)*convertToNumber($total);
// add credit to referral wallet
$referral_balance = convertToNumber($referral_user->balance_available) + $referral_earning;
$referral_user->update(['balance_available'=>$referral_balance]);
// create new affiliate transaction
$affiliate_transaction = new AffiliateTransaction();
$affiliate_transaction->user_id = $buyer_id ;
$affiliate_transaction->referral_id = $referral_user->id ;
$affiliate_transaction->order_id = $order->id ;
$affiliate_transaction->referral_earning = $referral_earning ;
$affiliate_transaction->save();
}
}
} catch (\Throwable $th) {
// Error
throw $th;
}
}
/**
* Calculate fee value
*
* @param string $type
* @param mixed $amount
* @return mixed
*/
private function fee($type, $amount = null)
{
try {
// Set amount for deposit
$amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;
// Remove long decimal
$amount = convertToNumber( number_format($amount, 2, '.', '') );
// Check fee type
switch ($type) {
// Deposit
case 'deposit':
// Get deposit fixed fee
if (isset($this->settings->fixed_fee['deposit'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get deposit percentage fee
if (isset($this->settings->percentage_fee['deposit'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return number_format($fee_value, 2, '.', '');
break;
// Gigs
case 'gigs':
// Get gigs fixed fee
if (isset($this->settings->fixed_fee['gigs'])) {
// Set fixed fee
$fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
} else {
// No fixed fee
$fee_fixed = 0;
}
// Get gigs percentage fee
if (isset($this->settings->percentage_fee['gigs'])) {
// Set percentage fee
$fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
} else {
// No percentage fee
$fee_percentage = 0;
}
// Calculate percentage of this amount
$fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );
// Calculate exchange rate of this fixed fee
$fee_fixed_exchange = $this->exchange( $fee_fixed, $this->settings->exchange_rate);
// Calculate fee value and visible text
if ($fee_fixed > 0 && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
} else if (!$fee_fixed && $fee_percentage > 0) {
// Calculate fee value
$fee_value = convertToNumber($fee_percentage_amount);
} else if ($fee_fixed > 0 && !$fee_percentage) {
// Calculate fee value
$fee_value = convertToNumber($fee_fixed_exchange);
} else if (!$fee_percentage && !$fee_fixed) {
// Calculate fee value
$fee_value = 0;
}
// Return fee value
return $fee_value;
break;
}
} catch (\Throwable $th) {
// Something went wrong
return 0;
}
}
/**
* Calculate exchange rate
*
* @param mixed $amount
* @param mixed $exchange_rate
* @param boolean $formatted
* @param string $currency
* @return mixed
*/
private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
{
try {
// Convert amount to number
$amount = convertToNumber($amount);
// Get currency settings
$currency_settings = settings('currency');
// Get default currency exchange rate
$default_exchange_rate = convertToNumber($currency_settings->exchange_rate);
// Get exchanged amount
$exchanged_amount = convertToNumber( $amount * $default_exchange_rate / $exchange_rate );
// Check if we have to return a formatted value
if ($formatted) {
return money( $exchanged_amount, $currency, true )->format();
}
// Return max deposit
return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));
} catch (\Throwable $th) {
// Something went wrong
return $amount;
}
}
/**
* Send a notification to user
*
* @param string $type
* @param object $user
* @return void
*/
private function notification($type, $user)
{
try {
// Check notification type
switch ($type) {
// Deposit funds
case 'deposit':
break;
// Gig checkout
case 'gig':
break;
// Project payment
case 'project':
break;
// Bid payment
case 'bid':
break;
}
} catch (\Throwable $th) {
// Something went wrong
return;
}
}
/**
* Redirecting
*
* @param string $type
* @param string $status
* @return void
*/
private function redirect($type, $status = 'success')
{
// Check where to redirect
switch ($type) {
// Deposit history
case 'deposit':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
// Gigs order
case 'gigs':
// Check if payment succeeded
if ($status === 'success') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));
} else if ($status === 'pending') {
// Redirect to deposit history page
return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));
}
break;
}
}
}
<!DOCTYPE html>
<html>
<head>
<style id="grid1">
* {
box-sizing: border-box;
}
.wrapper {
max-width: 940px;
margin: 0 auto;
}
.wrapper > div {
border: 2px solid rgb(233 171 88);
border-radius: 5px;
background-color: rgb(233 171 88 / 50%);
padding: 1em;
color: #d9480f;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 5fr);
gap: 10px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column: 1 / 3;
grid-row: 1;
}
.two {
grid-column: 3 ;
grid-row: 1 / 4;
}
.three {
grid-column: 1;
grid-row: 2 / 5;
}
.four {
grid-column: 2;
grid-row: 2 / 4;
}
.five {
grid-column: 2;
grid-row: 4;
}
.six {
grid-column: 3;
grid-row: 4;
}
</style>
<style id="grid2">
.item1 { grid-area: header; }
.item2 { grid-area: menu; }
.item3 { grid-area: main; }
.item4 { grid-area: right; }
.item5 { grid-area: footer; }
.grid-container {
display: grid;
grid-template-areas:
'header header header header header header'
'menu main main main right right'
'menu footer footer footer footer footer';
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
</style>
</head>
<body>
<div class="wrapper" id="grid1">
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="four">Four</div>
<div class="five">Five</div>
<div class="six">Six</div>
</div>
<div class="grid-container" id="grid2">
<div class="item1">Header</div>
<div class="item2">Menu</div>
<div class="item3">Main</div>
<div class="item4">Right</div>
<div class="item5">Footer</div>
</div>
</body>
</html>
i am learning javascript, i created a program to add two number using function
{
"orgName": "Demo company",
"edition": "Developer",
"features": []
}
{
"orgName": "Demo company",
"edition": "Developer",
"features": []
}
// Check to see if running in a Console
var workspaceAPI = component.find("workspace");
workspaceAPI.isConsoleNavigation().then(function(consoleResponse) {
console.log("IsConsole: ", consoleResponse);
if (consoleResponse) {
// Save current tab info
workspaceAPI.getFocusedTabInfo().then(function(tabResponse) {
var closeTabId = tabResponse.tabId;
var closeTitle = tabResponse.title;
var parentTabId = tabResponse.parentTabId;
var isSubtab = tabResponse.isSubtab;
console.log("Current Tab: ", closeTabId + " | " + closeTitle);
console.log("Is Sub: ",isSubtab," ParentId: ",parentTabId);
// Open Visualforce Page in a new tab
if (isSubtab) {
workspaceAPI.openSubtab({
parentTabId: parentTabId,
url: vfURL,
focus: true
}).then(function(openSubResponse) {
console.log("New SubTab Id: ", openSubResponse);
})
.catch(function(error) {
console.log(error);
});
} else {
workspaceAPI.openTab({
url: vfURL,
focus: true
}).then(function(openParResponse) {
console.log("New ParentTab Id: ", openParResponse);
})
.catch(function(error) {
console.log(error);
});
}
// Because exiting the VF page will reopen the object record,
// close the tab we started on
if (tabResponse.closeable && !tabResponse.pinned) {
workspaceAPI.closeTab({
tabId: closeTabId
}).then(function(closeResponse) {
console.log("Closed: ", closeTitle);
})
.catch(function(error) {
console.log(error);
});
} else {
console.log("Left Open: ", tabResponse.title);
}
})
.catch(function(error) {
console.log(error);
})
// Handle non-console user
console.log("Not in Console");
var urlEvent = $A.get("e.force:navigateToURL");
urlEvent.setParams({
"url": vfURL
});
urlEvent.fire();
doInit : function(component, event, helper) {
var params = new Array();
params.push(component.get('v.recordIdVar') + '=' + component.get('v.recordId'));
params.push(component.get('v.otherParams'));
component.set('v.queryString', params.join('&'))
},
openPage : function(component, event, helper) {
// Show spinner once button is pressed
var spinner = component.find('spinner');
$A.util.removeClass(spinner, 'slds-hide');
// Build url for Visualforce page
var vfURL = 'https://' + component.get("v.domain") + '--c.visualforce.com/apex/';
vfURL = vfURL + component.get("v.pageName") + '?';
vfURL = vfURL + component.get("v.queryString");
console.log("VF URL: ",vfURL);
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
<lightning:workspaceAPI aura:id="workspace" />
<aura:attribute name="buttonLabel" type="String" />
<aura:attribute name="buttonVariant" type="String" default="neutral" />
<aura:attribute name="domain" type="String" />
<aura:attribute name="pageName" type="String" />
<aura:attribute name="recordIdVar" type="String" />
<aura:attribute name="otherParams" type="String" />
<aura:attribute name="queryString" type="String" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<lightning:card>
<lightning:layoutItem padding="around-small">
<lightning:button label="{!v.buttonLabel}" variant="{!v.buttonVariant}" onclick="{!c.openPage}" />
<lightning:spinner aura:id="spinner" alternativeText="Loading" variant="brand" size="large" class="slds-hide" />
</lightning:layoutItem>
</lightning:card>
</aura:component>
$ systemctl --user start rpi-connect
$ systemctl --user start rpi-connect
$ sudo apt install rpi-connect-lite
$ sudo apt install rpi-connect
$ sudo apt update $ sudo apt full-upgrade
Creating an audit trail in SQL involves capturing and recording changes made to the data in a database, along with metadata like who made the change, when it was made, and what the original and new values were. Here are some common methods to create an audit trail in SQL:
### 1. *Using Triggers*
Triggers are a common way to create an audit trail in SQL. A trigger can be set up to fire before or after an INSERT, UPDATE, or DELETE operation. The trigger then logs the changes into an audit table.
#### Example:
Suppose you have a table named employees and you want to audit changes.
1. *Create an Audit Table:*
sql
CREATE TABLE employees_audit (
audit_id INT AUTO_INCREMENT PRIMARY KEY,
employee_id INT,
action VARCHAR(10),
old_value VARCHAR(255),
new_value VARCHAR(255),
changed_by VARCHAR(50),
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2. **Create a Trigger for UPDATE:**
sql
CREATE TRIGGER employees_update_audit
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit (employee_id, action, old_value, new_value, changed_by)
VALUES (
OLD.employee_id,
'UPDATE',
OLD.salary,
NEW.salary,
USER()
);
END;
This trigger captures changes made to the salary column and stores the old and new values, the action performed, who performed the action, and when.
3. **Create Triggers for INSERT and DELETE:**
Similar triggers can be created for INSERT and DELETE operations.
### 2. *Change Data Capture (CDC)*
If your database supports Change Data Capture (CDC), you can enable this feature to automatically track changes without creating manual triggers.
- *SQL Server Example:*
sql
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo',
@source_name = 'employees',
@role_name = NULL;
- *Oracle Example:*
Oracle has its own built-in auditing features that can be configured via DBMS packages or directly using the AUDIT command.
### 3. *Manual Logging*
If you want to avoid using triggers, you can manually log changes by writing data into an audit table within your SQL operations.
#### Example:
sql
UPDATE employees
SET salary = 60000
WHERE employee_id = 101;
INSERT INTO employees_audit (employee_id, action, old_value, new_value, changed_by)
VALUES (101, 'UPDATE', '50000', '60000', 'admin');
### 4. *Temporal Tables*
Some databases like SQL Server 2016+ support temporal tables, which automatically keep track of historical data. You can enable a table to be temporal, and SQL Server will automatically manage the history.
#### Example:
sql
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
salary INT,
SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);
### Best Practices:
- *Minimal Performance Impact:* Triggers can introduce performance overhead, so ensure they're optimized and only track necessary data.
- *Data Integrity:* Ensure that the audit trail can't be easily tampered with by using appropriate permissions.
- *Compliance:* Ensure that your audit trail complies with legal and regulatory requirements for data retention and privacy.
By implementing one or more of these methods, you can effectively create an audit trail in SQL to track changes in your database.
#cmd or pwershell gpupdat /force
const animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'];
const foundAnimal = animals.findIndex(a => {
return a === 'elephant';
});
console.log(animals[foundAnimal]); // uses function's returned index to display value
const startsWithS = animals.findIndex(letter => {
return letter[0] === 's';
});
console.log(startsWithS); // function returns index number of first TRUE element
console.log(animals[startsWithS]); // used to display that element's value
Select id, name, Parent__r.name, Parent__r.id from Child__c Select id, name, Parent__r.name,(SELECT id, name, amount__c FROM Children__r) from Parent__c
const favoriteWords = ['nostalgia', 'hyperbole', 'fervent', 'esoteric', 'serene'];
// Call .filter() on favoriteWords below
const longFavoriteWords = favoriteWords.filter(word => {
return word.length > 7;
});
console.log(longFavoriteWords);
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get('id');
console.log(id)
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
<html>
<input id="contact" name="address">
<script>
document.getElementById("contact").attribute = "phone";
//ALTERNATIVE METHOD TO CHANGE
document.getElementById("contact").setAttribute('name', 'phone');
</script>
</html>
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":star: What's on in Melbourne this week! :star:"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "\n\n Hey Melbourne, happy Monday! Please see below for what's on this week! "
}
},
{
"type": "divider"
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Xero Café :coffee:",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "\n :new-thing: This week we are offering some *Arnott's Classics!* \n\n We have Gluten Free Scotch Fingers, Hundreds and Thousands Biscuits & Monte Carlo Biscuits!\n\n *Weekly Café Special*: _Hazelnut Latte_"
}
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": " Wednesday, 21st August :calendar-date-21:",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "\n\n:late-cake: *Afternoon Tea*: From *2pm* in the *L1, L2 and L3* kitchens! Check out the menu in the thread! :thread: \n:massage:*Wellbeing - Massage*: Book a session <https://bookings.corporatebodies.com/|*here*> to relax and unwind. \n *Username:* xero \n *Password:* 1234"
}
},
{
"type": "header",
"text": {
"type": "plain_text",
"text": " Thursday, 22nd August :calendar-date-22:",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":breakfast: *Breakfast*: Provided by *Kartel Catering* from *8:30am - 10:30am* in the Wominjeka Breakout Space.\n\n :cowboyblob: *Nashville Social:* 4pm - 6pm in the Wominjeka Breakout Space!"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=Y19xczkyMjk5ZGlsODJzMjA4aGt1b3RnM2t1MEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Melbourne Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
}
}
]
}
$stripe = new \Stripe\StripeClient('sk_test_51KX5RA...CV00KMzNeBbs
sk_test_51KX5RAHpz0yDkAJjgP65eUwiAJMY1mHeA4LoeX6162wxO6RDyGFZaQR6mOY1X9e7PpVAXkC1AT1HWNfE7ri3HRCV00KMzNeBbs
');
$stripe->customers->update(
'cus_NffrFeUfNV2Hib',
['metadata' => ['order_id' => '6735']]
);
{
"log": {
"version": "1.2",
"creator": {
"name": "WebInspector",
"version": "537.36"
},
"pages": [],
"entries": [
{
"_initiator": {
"type": "script",
"stack": {
"callFrames": [],
"parent": {
"description": "Image",
"callFrames": [
{
"functionName": "sendEventWithTarget",
"scriptId": "10",
"url": "https://js.rbxcdn.com/08a545ae1503441b55f5236794feccec.js",
"lineNumber": 134,
"columnNumber": 130
},
{
"functionName": "Ml.onInterval",
"scriptId": "39",
"url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
"lineNumber": 7,
"columnNumber": 387930
},
{
"functionName": "Ml.window.Worker.worker.worker.onmessage",
"scriptId": "39",
"url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
"lineNumber": 7,
"columnNumber": 388403
}
],
"parentId": {
"id": "1",
"debuggerId": "2503892074991461023.7174108864595547422"
}
}
}
},
"_priority": "Low",
"_resourceType": "image",
"cache": {},
"request": {
"method": "GET",
"url": "https://ecsv2.roblox.com/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat2&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar<=2024-08-09T19%3A37%3A33.374Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73",
"httpVersion": "h3",
"headers": [
{
"name": ":authority",
"value": "ecsv2.roblox.com"
},
{
"name": ":method",
"value": "GET"
},
{
"name": ":path",
"value": "/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat2&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar<=2024-08-09T19%3A37%3A33.374Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73"
},
{
"name": ":scheme",
"value": "https"
},
{
"name": "accept",
"value": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
},
{
"name": "accept-encoding",
"value": "gzip, deflate, br, zstd"
},
{
"name": "accept-language",
"value": "en-US,en;q=0.9"
},
{
"name": "cookie",
"value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
},
{
"name": "priority",
"value": "i"
},
{
"name": "referer",
"value": "https://www.roblox.com/"
},
{
"name": "sec-ch-ua",
"value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
},
{
"name": "sec-ch-ua-mobile",
"value": "?0"
},
{
"name": "sec-ch-ua-platform",
"value": "\"Windows\""
},
{
"name": "sec-fetch-dest",
"value": "image"
},
{
"name": "sec-fetch-mode",
"value": "no-cors"
},
{
"name": "sec-fetch-site",
"value": "same-site"
},
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
],
"queryString": [
{
"name": "evt",
"value": "pageHeartbeat_v2"
},
{
"name": "ctx",
"value": "heartbeat2"
},
{
"name": "url",
"value": "https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar"
},
{
"name": "lt",
"value": "2024-08-09T19%3A37%3A33.374Z"
},
{
"name": "gid",
"value": "-1210413020"
},
{
"name": "sid",
"value": "2cd50938-0f23-4613-92c1-4e08463a1e73"
}
],
"cookies": [
{
"name": "GuestData",
"value": "UserID=-1210413020",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-06T14:06:05.665Z",
"httpOnly": false,
"secure": false
},
{
"name": "RBXSource",
"value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-09-03T17:40:28.482Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmz",
"value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-02-08T07:36:52.000Z",
"httpOnly": false,
"secure": false
},
{
"name": ".RBXIDCHECK",
"value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "rbxas",
"value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXEventTrackerV2",
"value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.688Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmc",
"value": "200924205",
"path": "/",
"domain": ".roblox.com",
"expires": "1969-12-31T23:59:59.000Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga",
"value": "GA1.1.781422761.1723013326",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:50:57.685Z",
"httpOnly": false,
"secure": false
},
{
"name": ".ROBLOSECURITY",
"value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-12T17:52:14.190Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXSessionTracker",
"value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T23:36:53.353Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga_F8VP9T1NT3",
"value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:51:11.309Z",
"httpOnly": false,
"secure": false
},
{
"name": "rbx-ip2",
"value": "1",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:36:50.172Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utma",
"value": "200924205.337854883.1722793505.1723218657.1723232212.12",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T19:36:52.514Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmb",
"value": "200924205.0.10.1723232212",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:06:52.000Z",
"httpOnly": false,
"secure": false
}
],
"headersSize": -1,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "",
"httpVersion": "h3",
"headers": [
{
"name": "alt-svc",
"value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
},
{
"name": "content-length",
"value": "68"
},
{
"name": "content-type",
"value": "image/png"
},
{
"name": "date",
"value": "Fri, 09 Aug 2024 19:37:33 GMT"
},
{
"name": "nel",
"value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
},
{
"name": "report-to",
"value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
},
{
"name": "server",
"value": "public-gateway"
},
{
"name": "strict-transport-security",
"value": "max-age=3600"
},
{
"name": "vary",
"value": "Origin"
},
{
"name": "x-envoy-upstream-service-time",
"value": "1"
},
{
"name": "x-ratelimit-limit",
"value": "3600000, 3600000;w=60, 3600000;w=60"
},
{
"name": "x-ratelimit-remaining",
"value": "3599995"
},
{
"name": "x-ratelimit-reset",
"value": "26"
},
{
"name": "x-roblox-edge",
"value": "bom1"
},
{
"name": "x-roblox-region",
"value": "us-central_rbx"
}
],
"cookies": [],
"content": {
"size": 68,
"mimeType": "image/png",
"text": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=",
"encoding": "base64"
},
"redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 684,
"_error": null,
"_fetchedViaServiceWorker": false
},
"serverIPAddress": "128.116.104.4",
"startedDateTime": "2024-08-09T19:37:33.374Z",
"time": 320.2770000207238,
"timings": {
"blocked": 5.168000029683113,
"dns": -1,
"ssl": -1,
"connect": -1,
"send": 0.7090000000000001,
"wait": 311.9660000256076,
"receive": 2.4339999654330313,
"_blocked_queueing": 2.022000029683113,
"_workerStart": -1,
"_workerReady": -1,
"_workerFetchStart": -1,
"_workerRespondWithSettled": -1
}
},
{
"_initiator": {
"type": "script",
"stack": {
"callFrames": [],
"parent": {
"description": "Image",
"callFrames": [
{
"functionName": "sendEventWithTarget",
"scriptId": "10",
"url": "https://js.rbxcdn.com/08a545ae1503441b55f5236794feccec.js",
"lineNumber": 134,
"columnNumber": 130
},
{
"functionName": "Ml.onInterval",
"scriptId": "39",
"url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
"lineNumber": 7,
"columnNumber": 387930
},
{
"functionName": "Ml.window.Worker.worker.worker.onmessage",
"scriptId": "39",
"url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
"lineNumber": 7,
"columnNumber": 388403
}
],
"parentId": {
"id": "2",
"debuggerId": "2503892074991461023.7174108864595547422"
}
}
}
},
"_priority": "Low",
"_resourceType": "image",
"cache": {},
"request": {
"method": "GET",
"url": "https://ecsv2.roblox.com/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat3&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar<=2024-08-09T19%3A37%3A53.393Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73",
"httpVersion": "h3",
"headers": [
{
"name": ":authority",
"value": "ecsv2.roblox.com"
},
{
"name": ":method",
"value": "GET"
},
{
"name": ":path",
"value": "/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat3&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar<=2024-08-09T19%3A37%3A53.393Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73"
},
{
"name": ":scheme",
"value": "https"
},
{
"name": "accept",
"value": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
},
{
"name": "accept-encoding",
"value": "gzip, deflate, br, zstd"
},
{
"name": "accept-language",
"value": "en-US,en;q=0.9"
},
{
"name": "cookie",
"value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
},
{
"name": "priority",
"value": "i"
},
{
"name": "referer",
"value": "https://www.roblox.com/"
},
{
"name": "sec-ch-ua",
"value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
},
{
"name": "sec-ch-ua-mobile",
"value": "?0"
},
{
"name": "sec-ch-ua-platform",
"value": "\"Windows\""
},
{
"name": "sec-fetch-dest",
"value": "image"
},
{
"name": "sec-fetch-mode",
"value": "no-cors"
},
{
"name": "sec-fetch-site",
"value": "same-site"
},
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
],
"queryString": [
{
"name": "evt",
"value": "pageHeartbeat_v2"
},
{
"name": "ctx",
"value": "heartbeat3"
},
{
"name": "url",
"value": "https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar"
},
{
"name": "lt",
"value": "2024-08-09T19%3A37%3A53.393Z"
},
{
"name": "gid",
"value": "-1210413020"
},
{
"name": "sid",
"value": "2cd50938-0f23-4613-92c1-4e08463a1e73"
}
],
"cookies": [
{
"name": "GuestData",
"value": "UserID=-1210413020",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-06T14:06:05.665Z",
"httpOnly": false,
"secure": false
},
{
"name": "RBXSource",
"value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-09-03T17:40:28.482Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmz",
"value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-02-08T07:36:52.000Z",
"httpOnly": false,
"secure": false
},
{
"name": ".RBXIDCHECK",
"value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "rbxas",
"value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXEventTrackerV2",
"value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.688Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmc",
"value": "200924205",
"path": "/",
"domain": ".roblox.com",
"expires": "1969-12-31T23:59:59.000Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga",
"value": "GA1.1.781422761.1723013326",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:50:57.685Z",
"httpOnly": false,
"secure": false
},
{
"name": ".ROBLOSECURITY",
"value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-12T17:52:14.190Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXSessionTracker",
"value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T23:36:53.353Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga_F8VP9T1NT3",
"value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:51:11.309Z",
"httpOnly": false,
"secure": false
},
{
"name": "rbx-ip2",
"value": "1",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:36:50.172Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utma",
"value": "200924205.337854883.1722793505.1723218657.1723232212.12",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T19:36:52.514Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmb",
"value": "200924205.0.10.1723232212",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:06:52.000Z",
"httpOnly": false,
"secure": false
}
],
"headersSize": -1,
"bodySize": 0
},
"response": {
"status": 200,
"statusText": "",
"httpVersion": "h3",
"headers": [
{
"name": "alt-svc",
"value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
},
{
"name": "content-length",
"value": "68"
},
{
"name": "content-type",
"value": "image/png"
},
{
"name": "date",
"value": "Fri, 09 Aug 2024 19:37:54 GMT"
},
{
"name": "nel",
"value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
},
{
"name": "report-to",
"value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
},
{
"name": "server",
"value": "public-gateway"
},
{
"name": "strict-transport-security",
"value": "max-age=3600"
},
{
"name": "vary",
"value": "Origin"
},
{
"name": "x-envoy-upstream-service-time",
"value": "2"
},
{
"name": "x-ratelimit-limit",
"value": "3600000, 3600000;w=60, 3600000;w=60"
},
{
"name": "x-ratelimit-remaining",
"value": "3599994"
},
{
"name": "x-ratelimit-reset",
"value": "6"
},
{
"name": "x-roblox-edge",
"value": "bom1"
},
{
"name": "x-roblox-region",
"value": "us-central_rbx"
}
],
"cookies": [],
"content": {
"size": 68,
"mimeType": "image/png",
"text": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=",
"encoding": "base64"
},
"redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 683,
"_error": null,
"_fetchedViaServiceWorker": false
},
"serverIPAddress": "128.116.104.4",
"startedDateTime": "2024-08-09T19:37:53.399Z",
"time": 304.0679999976419,
"timings": {
"blocked": 7.885000016190111,
"dns": -1,
"ssl": -1,
"connect": -1,
"send": 0.7570000000000006,
"wait": 293.70699998886136,
"receive": 1.7189999925903976,
"_blocked_queueing": 3.8090000161901116,
"_workerStart": -1,
"_workerReady": -1,
"_workerFetchStart": -1,
"_workerRespondWithSettled": -1
}
},
{
"_initiator": {
"type": "script",
"stack": {
"callFrames": [
{
"functionName": "",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 0,
"columnNumber": 1720
},
{
"functionName": "e.exports",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 0,
"columnNumber": 184
},
{
"functionName": "e.exports",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 0,
"columnNumber": 4657
}
],
"parent": {
"description": "Promise.then",
"callFrames": [
{
"functionName": "s.request",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 0,
"columnNumber": 3347
},
{
"functionName": "",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 0,
"columnNumber": 6592
},
{
"functionName": "",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 7,
"columnNumber": 70477
}
],
"parent": {
"description": "Promise.then",
"callFrames": [
{
"functionName": "ir",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 7,
"columnNumber": 70453
},
{
"functionName": "ur",
"scriptId": "38",
"url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
"lineNumber": 7,
"columnNumber": 70874
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 2964
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 2630
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 2735
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 1671
},
{
"functionName": "h",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 1416
},
{
"functionName": "d",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 2776
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 5442
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 4623
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 4728
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 3664
},
{
"functionName": "b",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 3409
},
{
"functionName": "e.sendPulseAndSetTimeout",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 5315
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 5702
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 4623
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 4728
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 3664
},
{
"functionName": "b",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 3409
},
{
"functionName": "e.onTimeout",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 5589
},
{
"functionName": "",
"scriptId": "48",
"url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
"lineNumber": 0,
"columnNumber": 5502
}
]
}
}
}
},
"_priority": "High",
"_resourceType": "xhr",
"cache": {},
"request": {
"method": "POST",
"url": "https://apis.roblox.com/user-heartbeats-api/pulse",
"httpVersion": "h3",
"headers": [
{
"name": ":authority",
"value": "apis.roblox.com"
},
{
"name": ":method",
"value": "POST"
},
{
"name": ":path",
"value": "/user-heartbeats-api/pulse"
},
{
"name": ":scheme",
"value": "https"
},
{
"name": "accept",
"value": "application/json, text/plain, */*"
},
{
"name": "accept-encoding",
"value": "gzip, deflate, br, zstd"
},
{
"name": "accept-language",
"value": "en-US,en;q=0.9"
},
{
"name": "content-length",
"value": "199"
},
{
"name": "content-type",
"value": "application/json;charset=UTF-8"
},
{
"name": "cookie",
"value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
},
{
"name": "origin",
"value": "https://www.roblox.com"
},
{
"name": "priority",
"value": "u=1, i"
},
{
"name": "referer",
"value": "https://www.roblox.com/"
},
{
"name": "sec-ch-ua",
"value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
},
{
"name": "sec-ch-ua-mobile",
"value": "?0"
},
{
"name": "sec-ch-ua-platform",
"value": "\"Windows\""
},
{
"name": "sec-fetch-dest",
"value": "empty"
},
{
"name": "sec-fetch-mode",
"value": "cors"
},
{
"name": "sec-fetch-site",
"value": "same-site"
},
{
"name": "user-agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
},
{
"name": "x-bound-auth-token",
"value": "acOOtUInHmBzbl9fpgOXX04Ns2j4OUgzhgUHQtQzrkI=|1723232274|TuRJw65L9TpuHDsbcMIwAWhyL6LyA9DqaE6tVeiRFkRdfdw12jhwImWUAp1lVcT1qzBChlF6gJH3sV0Drwlqyw=="
},
{
"name": "x-csrf-token",
"value": "Rjm15WXsfrx8"
}
],
"queryString": [],
"cookies": [
{
"name": "GuestData",
"value": "UserID=-1210413020",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-06T14:06:05.665Z",
"httpOnly": false,
"secure": false
},
{
"name": "RBXSource",
"value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-09-03T17:40:28.482Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmz",
"value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-02-08T07:36:52.000Z",
"httpOnly": false,
"secure": false
},
{
"name": ".RBXIDCHECK",
"value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "rbxas",
"value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.249Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXEventTrackerV2",
"value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-08T17:46:10.688Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmc",
"value": "200924205",
"path": "/",
"domain": ".roblox.com",
"expires": "1969-12-31T23:59:59.000Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga",
"value": "GA1.1.781422761.1723013326",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:50:57.685Z",
"httpOnly": false,
"secure": false
},
{
"name": ".ROBLOSECURITY",
"value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-12T17:52:14.190Z",
"httpOnly": true,
"secure": true
},
{
"name": "RBXSessionTracker",
"value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T23:36:53.353Z",
"httpOnly": false,
"secure": false
},
{
"name": "_ga_F8VP9T1NT3",
"value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T15:51:11.309Z",
"httpOnly": false,
"secure": false
},
{
"name": "rbx-ip2",
"value": "1",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:36:50.172Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utma",
"value": "200924205.337854883.1722793505.1723218657.1723232212.12",
"path": "/",
"domain": ".roblox.com",
"expires": "2025-09-13T19:36:52.514Z",
"httpOnly": false,
"secure": false
},
{
"name": "__utmb",
"value": "200924205.0.10.1723232212",
"path": "/",
"domain": ".roblox.com",
"expires": "2024-08-09T20:06:52.000Z",
"httpOnly": false,
"secure": false
}
],
"headersSize": -1,
"bodySize": 199,
"postData": {
"mimeType": "application/json;charset=UTF-8",
"text": "{\"clientSideTimestampEpochMs\":1723232274741,\"sessionInfo\":{\"sessionId\":\"2cd50938-0f23-4613-92c1-4e08463a1e73\"},\"locationInfo\":{\"robloxWebsiteLocationInfo\":{\"url\":\"https://www.roblox.com/my/avatar\"}}}"
}
},
"response": {
"status": 200,
"statusText": "",
"httpVersion": "h3",
"headers": [
{
"name": "access-control-allow-credentials",
"value": "true"
},
{
"name": "access-control-allow-origin",
"value": "https://www.roblox.com"
},
{
"name": "alt-svc",
"value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
},
{
"name": "content-type",
"value": "application/json; charset=utf-8"
},
{
"name": "date",
"value": "Fri, 09 Aug 2024 19:37:55 GMT"
},
{
"name": "nel",
"value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
},
{
"name": "report-to",
"value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
},
{
"name": "server",
"value": "public-gateway"
},
{
"name": "strict-transport-security",
"value": "max-age=3600"
},
{
"name": "vary",
"value": "Origin"
},
{
"name": "x-envoy-upstream-service-time",
"value": "2"
},
{
"name": "x-roblox-edge",
"value": "bom1"
},
{
"name": "x-roblox-region",
"value": "us-central_rbx"
}
],
"cookies": [],
"content": {
"size": 78,
"mimeType": "application/json",
"text": "{\"sessionId\":\"2cd50938-0f23-4613-92c1-4e08463a1e73\",\"status\":200,\"message\":\"\"}"
},
"redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 680,
"_error": null,
"_fetchedViaServiceWorker": false
},
"serverIPAddress": "128.116.104.4",
"startedDateTime": "2024-08-09T19:37:54.757Z",
"time": 314.01399994501844,
"timings": {
"blocked": 8.659999978940935,
"dns": -1,
"ssl": -1,
"connect": -1,
"send": 1.689,
"wait": 301.7659999998622,
"receive": 1.8989999662153423,
"_blocked_queueing": 3.612999978940934,
"_workerStart": -1,
"_workerReady": -1,
"_workerFetchStart": -1,
"_workerRespondWithSettled": -1
}
}
]
}
}
public function rules()
{
return [
[['id_ente', 'id_estado', 'id_aeropuerto', 'id_linea', 'id_indicador', 'id_concep', 'pasajeros_transportados_n', 'pasajeros_transportados_i', 'cantidad_aeronaves_operativas_n', 'cantidad_aeronaves_operativas_i', 'cantidad_aeronaves_recuperadas_n', 'cantidad_aeronaves_recuperadas_i', 'cantidad_aeronaves_recuperar_n', 'cantidad_aeronaves_necesarias_n', 'cantidad_aeronaves_necesarias_i', 'cantidad_aeronaves_operativas_ci', 'cantidad_aeronaves_operativas_cn', 'numero_operaciones_vu', 'id_municipio', 'id_parroquia','id_plazo_ae', 'id_tip_trans_ae', 'id_tip_inve_ae', 'id_estatus_obra'], 'integer'],
[['vuelo', 'uso', 'moneda'], 'string'],
[['monto', 'cantidad_aeronaves_recuperar_i'], 'number', 'min' => 0],
[['fecha', 'carga_transportada_i', 'carga_transportada_n'], 'safe'],
[['nombre_proyecto'], 'string', 'max' => 250],
[['descripcion'], 'string', 'max' => 250],
[['id_municipio'], 'exist', 'skipOnError' => true, 'targetClass' => Municipios::className(), 'targetAttribute' => ['id_municipio' => 'id_municipio']],
[['id_parroquia'], 'exist', 'skipOnError' => true, 'targetClass' => Parroquias::className(), 'targetAttribute' => ['id_parroquia' => 'id_parroquia']],
[['id_tip_trans_ae'], 'exist', 'skipOnError' => true, 'targetClass' => TipoTransporteAe::className(), 'targetAttribute' => ['id_tip_trans_ae' => 'id_tip_trans_ae']],
[['id_tip_inve_ae'], 'exist', 'skipOnError' => true, 'targetClass' => TiposInversiones::className(), 'targetAttribute' => ['id_tip_inve_ae' => 'id_tip_inve']],
[['fecha'], 'required'],
];
}
<div style="flex: 1 0 100%; display: block;" id='carga_transportada_i'>
<?= $form->field($model, 'carga_transportada_i')->widget(MaskedInput::className(), [
'clientOptions' => [
'alias' => 'decimal',
'groupSeparator' => '.',
'radixPoint' => ',',
'autoGroup' => true,
'digits' => 2,
'digitsOptional' => false,
'allowMinus' => false,
'rightAlign' => false
],
'options' => [
'class' => 'form-control',
//'placeholder' => '600 (Número entero)',
//'maxlength' => 10
]
]) ?>
</div>
<?= $form->field($model, 'carga_transportada_n')->widget(MaskedInput::className(), [
'clientOptions' => [
'alias' => 'decimal',
'groupSeparator' => '.',
'radixPoint' => ',',
'autoGroup' => true,
'digits' => 2,
'digitsOptional' => false,
'allowMinus' => false,
'rightAlign' => false
],
'options' => [
'class' => 'form-control campo-suma',
//'placeholder' => '600 (Número entero)',
//'maxlength' => 10
]
]) ?>
const fs = require('fs');
const path = require('path');
const settingsPath = path.join(__dirname, 'settings.json');
const settingsContent = fs.readFileSync(settingsPath, 'utf8');
const settings = JSON.parse(settingsContent);
// Toggle editor.glyphMargin
if (settings['editor.glyphMargin'] === undefined) {
console.log(settings['editor.glyphMargin']);
settings['editor.glyphMargin'] = false;
} else {
delete settings['editor.glyphMargin'];
}
// Toggle editor.lineNumbers
if (settings['editor.lineNumbers'] === undefined) {
settings['editor.lineNumbers'] = 'off';
} else {
delete settings['editor.lineNumbers'];
}
// Toggle vim.smartRelativeNumber
if (settings['vim.smartRelativeLine'] === undefined || settings['vim.smartRelativeLine'] === false) {
settings['vim.smartRelativeLine'] = true;
} else {
delete settings['vim.smartRelativeLine'];
}
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
console.log('Settings toggled successfully.');
//node C:\Users\st96481.ttl\AppData\Roaming\Code\User\toggleSettings.js
// Along with both the below combo this script changes the setting.json to toggle zen mode with glyphMargin, lineNumbers and vim.smartRelativeLine
// this is the setting.json snippet
{
"multiCommand.commands": [
{
"command": "extension.toggleZenModeAndSettings",
"sequence": [
"workbench.action.toggleZenMode",
{
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "node C:\\Users\\st96481.ttl\\AppData\\Roaming\\Code\\User\\toggleSettings.js\n"
}
}
]
}
],
}
// this is key binding from keybindings.json
{
"key": "alt+shift+z alt+shift+m",
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"extension.toggleZenModeAndSettings"
]
}
}
def AddNum(a, b): summ = a + b return summ
<?php
class Elementor_Custom_Video_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'custom_video_widget';
}
public function get_title() {
return __('Custom Video Widget', 'plugin-name');
}
public function get_icon() {
return 'eicon-video-camera';
}
public function get_categories() {
return ['basic'];
}
protected function _register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => __('Content', 'plugin-name'),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'source',
[
'label' => __('Source', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
'self_hosted' => __('Self Hosted', 'plugin-name'),
'external' => __('External URL', 'plugin-name'),
],
'default' => 'self_hosted',
]
);
$this->add_control(
'video_url',
[
'label' => __('Choose Video File', 'plugin-name'),
'type' => \Elementor\Controls_Manager::MEDIA,
'media_type' => 'video',
'condition' => [
'source' => 'self_hosted',
],
]
);
$this->add_control(
'autoplay',
[
'label' => __('Autoplay', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Yes', 'plugin-name'),
'label_off' => __('No', 'plugin-name'),
'return_value' => 'yes',
'default' => 'yes', // Set default to 'yes'
]
);
$this->add_control(
'play_on_mobile',
[
'label' => __('Play on Mobile', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Yes', 'plugin-name'),
'label_off' => __('No', 'plugin-name'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'mute',
[
'label' => __('Mute', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Yes', 'plugin-name'),
'label_off' => __('No', 'plugin-name'),
'return_value' => 'yes',
'default' => 'no',
]
);
$this->add_control(
'loop',
[
'label' => __('Loop', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Yes', 'plugin-name'),
'label_off' => __('No', 'plugin-name'),
'return_value' => 'yes',
'default' => 'no',
]
);
$this->add_control(
'player_controls',
[
'label' => __('Player Controls', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Show', 'plugin-name'),
'label_off' => __('Hide', 'plugin-name'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->add_control(
'download_button',
[
'label' => __('Download Button', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Show', 'plugin-name'),
'label_off' => __('Hide', 'plugin-name'),
'return_value' => 'yes',
'default' => 'no',
]
);
$this->add_control(
'poster',
[
'label' => __('Poster', 'plugin-name'),
'type' => \Elementor\Controls_Manager::MEDIA,
'media_type' => 'image',
]
);
$this->add_control(
'show_play_button',
[
'label' => __('Show Play/Pause Button', 'plugin-name'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => __('Show', 'plugin-name'),
'label_off' => __('Hide', 'plugin-name'),
'return_value' => 'yes',
'default' => 'yes',
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
// Video HTML
echo '<video id="custom-video" src="' . $settings['video_url']['url'] . '" ' . ($settings['autoplay'] === 'yes' ? 'autoplay' : '') . ' ' . ($settings['mute'] === 'yes' ? 'muted' : '') . ' ' . ($settings['loop'] === 'yes' ? 'loop' : '') . ' ' . ($settings['player_controls'] === 'yes' ? 'controls' : '') . ' poster="' . $settings['poster']['url'] . '"></video>';
// Play/Pause Button
if ($settings['show_play_button'] === 'yes') {
// Default to pause icon if autoplay is enabled
$icon_class = $settings['autoplay'] === 'yes' ? 'fa-pause' : 'fa-play';
echo '<button id="custom-play-pause" class="play-button"><i class="fas ' . $icon_class . '"></i></button>';
}
// JavaScript for Play/Pause Button
echo '<script>
document.addEventListener("DOMContentLoaded", function() {
var video = document.getElementById("custom-video");
var playPauseButton = document.getElementById("custom-play-pause");
var icon = playPauseButton.querySelector("i");
// Play video if autoplay is enabled and video is muted (required by some browsers)
video.addEventListener("loadedmetadata", function() {
if (video.hasAttribute("autoplay")) {
video.play().then(function() {
icon.classList.remove("fa-play");
icon.classList.add("fa-pause");
}).catch(function(error) {
console.log("Autoplay failed: ", error);
icon.classList.remove("fa-pause");
icon.classList.add("fa-play");
});
}
});
playPauseButton.addEventListener("click", function() {
if (video.paused) {
video.play();
icon.classList.remove("fa-play");
icon.classList.add("fa-pause");
} else {
video.pause();
icon.classList.remove("fa-pause");
icon.classList.add("fa-play");
}
});
});
</script>';
}
}
//-------------------------------------------------END-------------------------------------//
Dưới đây là đoạn đăng ký widget
function register_custom_widget($widgets_manager)
{
// Custom video widget
require_once(__DIR__ . '/widgets/custom-video.php');
$widgets_manager->register(new \Elementor_Custom_Video_Widget());
}
add_action('elementor/widgets/register', 'register_custom_widget');
CMD elevated: Dism.exe /online /Cleanup-Image /StartComponentCleanup
Summary == checks for reference equality (i.e., whether two references point to the same object). hashCode() is used in hash-based collections to quickly locate objects. If == returns true, the hashCode() values of the two objects will be the same. If equals() is overridden, hashCode() must also be overridden to ensure that equal objects have the same hash code. Important: Two distinct objects can have the same hashCode(), but equal objects (as determined by equals()) must have the same hashCode().
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*, HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |Select-Object DisplayName, DisplayVersion, Publisher, Size, InstallDate | Format-Table -AutoSize > C:\Users\USERNAME\Desktop\software.txt Get-AppxPackage > C:\Users\USERNAME\Desktop\apps.txt
$pesquisa = json_decode($request->getContent(), true);
return Cache::remember($pesquisa, $seconds, function ()use($pesquisa) {
$produtos = Produto::select('nome', 'valor')->where('nome', 'LIKE', '%'.$pesquisa.'%')->get();
return response()->json($produtos);
});
Reg edit: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control In right-side pane, look for a DWORD SvcHostSplitThresholdInKB Set its value equal or greater than the amount of RAM (in KB) installed in your computer Eg: 8 GB = 8×1024 MB = 8x1024x1024 KB = 8388608 KB Close Registry Editor and restart the pc
##python #coding #python #programming #database #sqllite3 #image #smileydb3
How to generate html file from sqlite3 database using SmileyDB3from faker import Faker
from SmileyDB3 import SmileyDB3
from random import randint
import webbrowser
f = Faker()
db = SmileyDB3('mydb.db')
users = db.table('users')
for i in range(20):
users.Insert(data={
'name': f.name(),
'email': f.email(),
'age': randint(20, 40)
})
users.convert().to_html('out.html')
webbrowser.open('out.html')
//Stored Procedure
CREATE PROCEDURE GetQualifyingMembers
@RewardCriteria NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
IF @RewardCriteria = 'Placed a Booking'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Bookings b ON b.Member_ID = m.Member_ID;
END
ELSE IF @RewardCriteria = 'Completed 10 Bookings in a Month'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Bookings b ON b.Member_ID = m.Member_ID
INNER JOIN Booking_Time_Slots bts ON b.Booking_ID = bts.Booking_ID
INNER JOIN Time_Slots ts ON bts.Time_Slot_ID = ts.Time_Slot_ID
WHERE ts.Slot_Date >= DATEADD(MONTH, -1, GETDATE())
GROUP BY m.Member_ID
HAVING COUNT(b.Booking_ID) >= 10;
END
ELSE IF @RewardCriteria = 'Made 20 Bookings in Last 3 Months'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Bookings b ON b.Member_ID = m.Member_ID
INNER JOIN Booking_Time_Slots bts ON b.Booking_ID = bts.Booking_ID
INNER JOIN Time_Slots ts ON bts.Time_Slot_ID = ts.Time_Slot_ID
WHERE ts.Slot_Date >= DATEADD(MONTH, -3, GETDATE())
GROUP BY m.Member_ID
HAVING COUNT(b.Booking_ID) >= 20;
END
-- Add more conditions based on other reward criteria as needed
ELSE IF @RewardCriteria = 'Placed First Order'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
WHERE EXISTS (
SELECT 1 FROM Orders o WHERE o.Member_ID = m.Member_ID AND o.Order_Date = (
SELECT MIN(Order_Date) FROM Orders o2 WHERE o2.Member_ID = m.Member_ID
)
);
END
ELSE IF @RewardCriteria = 'Made a Payment'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Payments p ON p.Member_ID = m.Member_ID;
END
ELSE IF @RewardCriteria = 'High-Value Order'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Orders o ON o.Member_ID = m.Member_ID
WHERE o.Total_Amount >= 1000; -- Example threshold, adjust as needed
END
ELSE IF @RewardCriteria = 'Large Quantity Order'
BEGIN
SELECT DISTINCT m.Member_ID
FROM Members m
INNER JOIN Order_Items oi ON oi.Order_ID = (
SELECT TOP 1 o.Order_ID
FROM Orders o
WHERE o.Member_ID = m.Member_ID
ORDER BY o.Order_Date DESC
)
WHERE oi.Quantity >= 10; -- Example threshold, adjust as needed
END
ELSE
BEGIN
-- Return an empty set if criteria do not match
SELECT * FROM Members WHERE 1 = 0;
END
END
//Service
public class QualifyingMembersService : IHostedService, IDisposable
{
private readonly IServiceProvider _serviceProvider;
private Timer _timer;
public QualifyingMembersService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(UpdateQualifyingMembers, null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); // Check every 1 minute
return Task.CompletedTask;
}
private async void UpdateQualifyingMembers(object state)
{
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var postedRewards = await context.Rewards
.Where(r => r.IsPosted)
.ToListAsync();
foreach (var reward in postedRewards)
{
var rewardType = await context.Reward_Types
.FindAsync(reward.Reward_Type_ID);
if (rewardType != null)
{
var qualifyingMembers = await GetQualifyingMembersAsync(rewardType.Reward_Criteria);
foreach (var member in qualifyingMembers)
{
var existingRewardMember = await context.Reward_Members
.FirstOrDefaultAsync(rm => rm.Member_ID == member.Member_ID && rm.Reward_ID == reward.Reward_ID);
if (existingRewardMember == null)
{
var rewardMember = new Reward_Member
{
Member_ID = member.Member_ID,
Reward_ID = reward.Reward_ID,
IsRedeemed = false
};
context.Reward_Members.Add(rewardMember);
}
}
}
}
await context.SaveChangesAsync();
}
}
public async Task<List<Member>> GetQualifyingMembersAsync(string criteria)
{
var criteriaParam = new SqlParameter("@Criteria", criteria);
return await _serviceProvider.GetRequiredService<AppDbContext>()
.Members
.FromSqlRaw("EXEC GetQualifyingMembers @Criteria", criteriaParam)
.ToListAsync();
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
//UpdateQualifyingMembersForReward
private async Task UpdateQualifyingMembersForReward(int rewardId)
{
// Fetch reward and reward type
var reward = await _appDbContext.Rewards.FindAsync(rewardId);
if (reward != null)
{
var rewardType = await _appDbContext.Reward_Types.FindAsync(reward.Reward_Type_ID);
if (rewardType != null)
{
// Use QualifyingMembersService to get qualifying members
var qualifyingMembers = await _qualifyingMembersService.GetQualifyingMembersAsync(rewardType.Reward_Criteria);
foreach (var member in qualifyingMembers)
{
var existingRewardMember = await _appDbContext.Reward_Members
.FirstOrDefaultAsync(rm => rm.Member_ID == member.Member_ID && rm.Reward_ID == reward.Reward_ID);
// Add qualifying members to the Reward_Member table
if (existingRewardMember == null)
{
var rewardMember = new Reward_Member
{
Member_ID = member.Member_ID,
Reward_ID = reward.Reward_ID,
IsRedeemed = false
};
_appDbContext.Reward_Members.Add(rewardMember);
}
}
await _appDbContext.SaveChangesAsync();
}
}
}
##python #coding #python #programming #database #sqllite3 #image
how to insert image into database sqlite3 and Python
import sqlite3
db = sqlite3.connect('mydb.db')
cur = db.cursor()
# create users table
cur.execute('CREATE TABLE IF NOT EXISTS users (name str, image blob)')
# insert new user in users table
cur.execute(
'INSERT INTO users (name, image) VALUES (?, ?)',
('USER-123', open('smile.png', 'rb').read())
)
db.commit()
import customtkinter as ctk
root = ctk.CTk()
root.geometry('200x200')
led_on = '#4cff66'
led_off = '#1e3c22'
led = ctk.CTkLabel(root, text='\t', width=50, bg_color=led_off)
led.place(x = 80, y = 80)
def off_on():
if led._bg_color == led_off:
led.configure(bg_color = led_on)
led.update()
return
if led._bg_color == led_on:
led.configure(bg_color = led_off)
led.update()
return
bt = ctk.CTkButton(root, text = 'OFF/ON', command=off_on, width=70)
bt.place(x = 80, y = 150)
root.mainloop()
Fri Aug 16 2024 20:08:36 GMT+0000 (Coordinated Universal Time) https://onecompiler.com/javascript
Fri Aug 16 2024 17:39:40 GMT+0000 (Coordinated Universal Time) https://github.com/SalesforceFoundation
Fri Aug 16 2024 17:39:05 GMT+0000 (Coordinated Universal Time) https://github.com/developerforce
Fri Aug 16 2024 17:38:25 GMT+0000 (Coordinated Universal Time) https://github.com/SalesforceLabs
Fri Aug 16 2024 16:54:01 GMT+0000 (Coordinated Universal Time) flow_action_components/DedupeRecordCollection/config/project-scratch-def.json
Fri Aug 16 2024 16:52:01 GMT+0000 (Coordinated Universal Time) flow_action_components/DedupeRecordCollection/config/project-scratch-def.json
Fri Aug 16 2024 15:50:01 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/
Fri Aug 16 2024 15:48:52 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/
Fri Aug 16 2024 15:48:19 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/
Fri Aug 16 2024 15:45:38 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/
Fri Aug 16 2024 08:00:42 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 08:00:27 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 07:59:42 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 07:59:32 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 07:59:29 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 07:59:26 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html
Fri Aug 16 2024 01:32:13 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/apex
Fri Aug 16 2024 01:30:04 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/lwc
Fri Aug 16 2024 01:27:37 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/salesforce
Fri Aug 16 2024 01:07:22 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/64194b2a0eab1e0013c9cf4e
Fri Aug 16 2024 01:03:12 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/5e03b21a12e79618db53832c
Fri Aug 16 2024 01:01:50 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/how-to-change-any-attribute-of-a-html-element-html-javascript-jsfunctions-dom-dommanipulation/5e2e022d77696f00148a2077
Thu Aug 15 2024 20:40:03 GMT+0000 (Coordinated Universal Time) https://docs.stripe.com/api/customers/update
Thu Aug 15 2024 06:18:05 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/new
Thu Aug 15 2024 03:18:53 GMT+0000 (Coordinated Universal Time) https://chatgpt.com/c/0b9ed55e-64f9-4269-8f50-9c1c7b7035e4
Wed Aug 14 2024 19:05:26 GMT+0000 (Coordinated Universal Time) https://medium.com/canucks-tech-tips/how-to-get-list-of-installed-programs-a14bbbbf519f
Wed Aug 14 2024 17:53:30 GMT+0000 (Coordinated Universal Time) https://www.askvg.com/windows-10-fix-too-many-svchost-exe-service-host-process-running-in-task-manager/
Wed Aug 14 2024 17:14:46 GMT+0000 (Coordinated Universal Time)
@freepythoncode ##python #coding #python #programming #database #sqllite3 #image #smileydb3
Wed Aug 14 2024 13:57:42 GMT+0000 (Coordinated Universal Time)
@freepythoncode ##python #coding #python #programming #database #sqllite3 #image
Wed Aug 14 2024 13:55:13 GMT+0000 (Coordinated Universal Time)
@freepythoncode ##python #coding #python #programming #tkinter


