Skip to content

Commit

Permalink
Merge branch 'feature/woocommerce-integration' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
lastofpudge authored Mar 16, 2024
2 parents af9846e + 9eb6cf5 commit 6742f0a
Show file tree
Hide file tree
Showing 162 changed files with 23,278 additions and 45 deletions.
3 changes: 3 additions & 0 deletions app/Admin/AdminOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ public function index(): void
'script',
'style'
]);

remove_theme_support('block-templates');
remove_theme_support('core-block-patterns');

add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support('custom-logo');
add_theme_support('responsive-embeds');

add_theme_support('woocommerce');
}

public function manageAdminAccess(): void
Expand Down
2 changes: 1 addition & 1 deletion app/Controllers/CategoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct()
public function index(): array
{
$this->data['term'] = Timber::get_term();
$this->data['posts'] = Timber::get_posts();
// $this->data['posts'] = Timber::get_posts();

return $this->data;
}
Expand Down
8 changes: 8 additions & 0 deletions app/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@ class Controller
{
public function __construct()
{
add_filter('timber/context', function ($context) {
$context['cart'] = WC()->cart;
$context['checkout_link'] = wc_get_checkout_url();
$context['cart_link'] = wc_get_cart_url();
$context['currency_symbol'] = get_woocommerce_currency_symbol();

return $context;
});
}
}
62 changes: 62 additions & 0 deletions app/Controllers/ProductController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace App\Controllers;

use Timber\Timber;

class ProductController extends Controller
{
/** @var array */
protected array $data;

public function __construct()
{
parent::__construct();

$this->data = Timber::context();
}

public function index(): array
{
$this->data['product'] = wc_get_product(get_the_ID());
$this->data['post'] = Timber::get_post();
$this->data['categories'] = get_the_terms(get_the_ID(), 'product_cat');

$related_limit = wc_get_loop_prop('columns');
$related_ids = wc_get_related_products(get_the_ID(), $related_limit);
$this->data['related_products'] = Timber::get_posts($related_ids);

return $this->data;
}

public function category(): array
{
$queried_object = get_queried_object();
$term_id = $queried_object->term_id;
$this->data['category'] = get_term($term_id, 'product_cat');
$this->data['title'] = single_term_title('', false);

return $this->data;
}

public function archive(): array
{
$this->data['attributes'] = array_map(fn ($taxonomy) => [
'label' => $taxonomy->attribute_label,
'name' => $taxonomy->attribute_name,
'terms' => get_terms([
'taxonomy' => 'pa_' . $taxonomy->attribute_name,
'hide_empty' => false,
]) ?? [],
], wc_get_attribute_taxonomies());

return $this->data;
}

public function cart(): array
{
$this->data['coupons_enabled'] = wc_coupons_enabled();

return $this->data;
}
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

wp_register_style(
'crb-my-shiny-gutenberg-block-stylesheet',
get_stylesheet_directory_uri() . '../app/CarbonFields/Blocks/example.css'
get_stylesheet_directory_uri() . '../app/CustomFields/Blocks/example.css'
);


Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions app/CustomFields/Fields/product.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use Carbon_Fields\Container;
use Carbon_Fields\Field;

// not works with woo new form
Container::make('post_meta', __('Products Data'))
->where('post_type', '=', 'product')
->add_fields([
Field::make('text', 'sub_title', 'Sub-title'),
]);
5 changes: 5 additions & 0 deletions app/CustomFields/Fields/product_variants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

use Core\CustomWooVariants;

CustomWooVariants::create('Name', 'name', 'text', []);
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
add_action('carbon_fields_register_fields', function () {
include __DIR__ . '/Fields/home.php';
include __DIR__ . '/Fields/about.php';
include __DIR__ . '/Fields/product.php';
// Container::make( 'comment_meta', 'Comment fields' )
// ->add_fields( array(
// Field::make( 'text', 'comment_rating', 'Rating' ),
// ) );
});

include __DIR__ . '/Fields/product_variants.php';
51 changes: 51 additions & 0 deletions app/Handlers/AjaxHandlers/addToCart.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

if (!wp_verify_nonce($_POST['nonce'], 'ajax-nonce')) {
wp_send_json(['type' => 'error', 'message' => 'nonce_error']);
}

$product_id = absint($_POST['product_id']);
$variation_id = $_POST['variation'] ? absint($_POST['variation']) : 0;

try {
$result = WC()->cart->add_to_cart($product_id, absint($_POST['quantity']), $variation_id);
if (!$result) {
wp_send_json(['type' => 'error', 'message' => 'Error adding to cart']);
}
} catch (Exception $e) {
wp_send_json(['type' => 'error', 'message' => $e->getMessage()]);
}

$cart = WC()->cart->get_cart();
$cart_data = [];

foreach ($cart as $cart_item_key => $cart_item) {
$_product = $cart_item['data'];
$sale_price = null;

if (!empty($_product->get_sale_price())) {
$sale_price = wc_price($_product->get_sale_price());
}

$item_data = [
'id' => $cart_item['product_id'],
'name' => $_product->get_name(),
'link' => get_permalink($cart_item['product_id']),
'thumbnail' => $_product->get_image(),
'quantity' => $cart_item['quantity'],
'cart_item_key' => $result,
'regular_price' => wc_price($_product->get_regular_price()),
'sale_price' => $sale_price,
];

$cart_data[] = $item_data;
}

wp_send_json([
'type' => 'success',
'message' => 'Product added to the cart.',
'cart' => $cart_data,
'total' => number_format(WC()->cart->get_cart_contents_total(), 2, '.', ''),
'subTotal' => WC()->cart->get_subtotal(),
'count' => WC()->cart->get_cart_contents_count(),
]);
5 changes: 5 additions & 0 deletions app/Handlers/AjaxHandlers/applyCoupon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

if (!wp_verify_nonce($_POST['nonce'], 'ajax-nonce')) {
wp_send_json(['type' => 'error', 'message' => 'nonce_error']);
}
25 changes: 25 additions & 0 deletions app/Handlers/AjaxHandlers/removeFromCart.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

if (!wp_verify_nonce($_POST['nonce'], 'ajax-nonce')) {
wp_send_json(['type' => 'error', 'message' => 'nonce_error']);
}

$key = sanitize_text_field($_POST['key']);

$response = WC()->cart->remove_cart_item($key);

$total = WC()->cart->get_cart_contents_total();
$subTotal = WC()->cart->get_subtotal();
$cartItemCount = WC()->cart->get_cart_contents_count();

if ($response) {
wp_send_json([
'type' => 'success',
'message' => 'Product removed from the cart.',
'total' => number_format($total, 2, '.', ''),
'subTotal' => $subTotal,
'count' => $cartItemCount
]);
} else {
wp_send_json(['type' => 'error', 'response' => $response]);
}
4 changes: 4 additions & 0 deletions app/Handlers/ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@

add_ajax_action('login');
add_ajax_action('contact');

add_ajax_action('removeFromCart');
add_ajax_action('addToCart');
add_ajax_action('applyCoupon');
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"htmlburger/carbon-fields": "^3.6",
"timber/timber": "^2.0.0",
"twig/twig": "^v3.8.0",
"wp-theme/core": "^1.0.4",
"wp-theme/core": "^1.1.4",
"wpackagist-plugin/all-in-one-wp-migration": "*",
"wpackagist-plugin/wordpress-seo": "*"
},
Expand All @@ -42,9 +42,9 @@
"bootstrap/app.php",
"app/helpers.php",
"app/Handlers/ajax.php",
"app/CarbonFields/OptionFields.php",
"app/CarbonFields/PostFields.php",
"app/CarbonFields/Blocks.php",
"app/CustomFields/OptionFields.php",
"app/CustomFields/PostFields.php",
"app/CustomFields/Blocks.php",
"routes/api.php"
]
},
Expand Down
8 changes: 8 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["resources/assets/src/scripts/*"]
}
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"devDependencies": {
"git-commit-msg-linter": "^5.0.0",
"laravel-mix": "^6.0.6",
"path": "^0.12.7",
"prettier": "^3.2.5",
"prettier-plugin-twig-melody": "^0.4.6",
"sass": "^1.70.0",
"sass-loader": "^14.0.0"
},
"dependencies": {
"axios": "^1.6.7",
"nouislider": "^15.7.1",
"sweetalert2": "^11.6.15"
}
}
1,432 changes: 1,431 additions & 1 deletion resources/assets/dist/css/bundle.min.css

Large diffs are not rendered by default.

13,883 changes: 13,881 additions & 2 deletions resources/assets/dist/js/app.min.js

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions resources/assets/src/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import axios from 'axios'

window.axios = axios

import { initContactForm } from './contact'
import { initLoginForm } from './login'
import { initContactForm } from '@/contact'
import { initLoginForm } from '@/login'
import { initCart } from '@/cart/cart'
import { initRangeSlider } from '@/rangeSlider'

document.addEventListener('DOMContentLoaded', () => {
initContactForm()
initLoginForm()
initCart()
initRangeSlider()
})
91 changes: 91 additions & 0 deletions resources/assets/src/scripts/cart/add.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import axios from 'axios'
import Toast from '@/libs/Toast'

export function addToCart() {
const preloader = document.querySelector('.js-preloader-main')
const addButtons = document.querySelectorAll('.js-add-to-cart')

const totals = document.querySelectorAll('.js-total')
const subTotals = document.querySelectorAll('.js-sub-total')
const cartCount = document.querySelector('.js-cart-total')

const cartList = document.querySelector('.js-cart-list')
const addedProduct = product => {
return `
<tr class="js-cart-item" data-ajax="true" data-key="${product.cart_item_key}">
<td class="text-center">
<a href="${product.link}" class="d-block thumb-sm">
${product.thumbnail}
</a>
</td>
<td class="text-start">
<a href="${product.link}">${product.name}</a>
</td>
<td>x${product.quantity}</td>
<td class="text-end">
${product.sale_price ? `${product.sale_price}` : `${product.regular_price}`}
</td>
<td class="text-end">
<button type="button" data-key="${product.cart_item_key}" title="Remove" class="btn btn-danger js-remove-from-cart">
<i class="fa-solid fa-circle-xmark"></i>
</button>
</td>
</tr>`
}
addButtons.forEach(addButton => {
addButton.addEventListener('click', async event => {
preloader.classList.add('js-preloading')

const formData = new FormData()
formData.append('action', 'addToCart')
formData.append('nonce', data.nonce)
formData.append('product_id', addButton.dataset.product_id)
formData.append('quantity', addButton.dataset.quantity)
if (addButton.dataset.variation) {
formData.append('variation', addButton.dataset.variation)
}

try {
const { data: response } = await axios.post(data.ajax_url, formData, {
params: { action: 'addToCart' }
})

if (response.type === 'success') {
// totals
totals.forEach(totalElement => {
totalElement.innerHTML = response.total
})

// sub-totals
subTotals.forEach(subTotalElement => {
subTotalElement.innerHTML = response.subTotal
})

cartCount.innerHTML = response.count

// cart items
if (response.cart) {
cartList.innerHTML = ''
response.cart.forEach(product => {
const newProduct = addedProduct(product) // Pass each product data to your addedProduct function
cartList.innerHTML += newProduct
})
}

Toast.fire({ icon: 'success', iconColor: '#007cba', title: response.message })
}

if (response.type === 'error') {
Toast.fire({ icon: 'error', iconColor: 'red', title: response.message })
}

preloader.classList.remove('js-preloading')
} catch (error) {
preloader.classList.remove('js-preloading')
console.error(error)
}
})
})
}
Loading

0 comments on commit 6742f0a

Please sign in to comment.