MOON
Server: Apache
System: Linux server1.studioinfinity.com.br 2.6.32-954.3.5.lve1.4.90.el6.x86_64 #1 SMP Tue Feb 21 12:26:30 UTC 2023 x86_64
User: artinside (517)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //home/artinside/sites.artinside.com.br/paliar/source/App/Store.php
<?php

namespace Source\App;

use Anam\Phpcart\Cart;
use Source\Core\Controller;
use Source\Core\Session;
use Source\Core\View;
use Source\Models\Address;
use Source\Models\Ecommerce\Coupon;
use Source\Models\Ecommerce\CreditCard;
use Source\Models\Ecommerce\OrderItens;
use Source\Models\Ecommerce\Orders;
use Source\Models\Ecommerce\Product;
use Source\Models\Ecommerce\ProductVariations;
use Source\Models\Newsletter;
use Source\Models\User;
use Source\Support\Email;
use Source\Support\Frete;
use Source\Support\FreteFrenet;
use Source\Support\Pagarme;

/**
 * Store Controller
 * @package Source\App
 */
class Store extends Controller
{

    /**
     * Web constructor.
     */
    public function __construct()
    {
        parent::__construct(__DIR__ . "/../../themes/" . CONF_VIEW_THEME . "/");
    }


    public function topCart(array $data):void
    {
        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
        $data['quantity'] = filter_var($data['quantity'], FILTER_VALIDATE_INT);
        if(isset($data["multiplier"]) AND $data["multiplier"] != ""){
            $multiplier = $data["multiplier"];
        }else{
            $multiplier = 1;
        }

        if(isset($data)){
            $response = $this->addItem($data['id'], $data['quantity'], $multiplier);
            if($response->message != ""){
                $json["message"] = $response->message;
                $json["load"] = true;
                $json["path"] = theme("/views/shop-cart.php");
                $json["target"] = "#top-cart";
                echo json_encode($json);
                return;
            }
            $json["message"] = $this->message->error("Erro ao adicionar produto, consulte nosso suporte")->render();
            echo json_encode($json);
            return;
        }
    }

    public function mainCart(array $data) : void
    {

        $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
        $data['quantity'] = filter_var($data['quantity'], FILTER_VALIDATE_INT);


        if($data["delete"] == "delete"){
            $response = $this->removeItem($data['id'], $data['multiplier']);

            $json["message"] = $response->message;
            $json["quantity"] = $response->quantity;
            $json["value"] = $response->value;
            $json["subtotal"] = preco_real($response->total);
            $json["total"] = preco_real($response->total);

            $json["count"] = $response->count;
            $json["path"] = theme("/views/shop-cart.php");
            $json["target"] = "#top-cart";
            echo json_encode($json);
            return;
        }


        if($data["multiplier"] > 1){
            $cart = new \Anam\Phpcart\Cart(CARRINHO);

            $stock = 0;
            foreach ($cart->getItems() as $item) {
                if($item->idProd == $data["id"]){
                    $stock += $item->multiplier * ($item->id == $data["cartid"] ? $data['quantity'] : $item->quantity);
                }
            }

            $product = (new ProductVariations())->findById($data["id"]);
            if($product->stock < $stock){
                $json["alert"] = true;
                $json["quantity"] = $cart->get($data["cartid"])->quantity;
                $json["message"] = $this->message->info("Metragem Indisponível para este produto")->render();
                echo json_encode($json);
                return;
            }

        }


        $response = $this->updateItem($data['id'], $data['quantity'],$data['multiplier']);




        if($response->message != ""){
            $json["message"] = $response->message;
            $json["quantity"] = $response->quantity;
            $json["value"] = $response->value;
            $json["subtotal"] = preco_real($response->total);
            $json["total"] = preco_real($response->total);
            $json["count"] = $response->count;
            $json["path"] = theme("/views/shop-cart.php");
            $json["target"] = "#top-cart";
            echo json_encode($json);
            return;
        }
        $json["message"] = $this->message->error("Erro ao adicionar produto, consulte nosso suporte")->render();
        echo json_encode($json);
        return;



    }


    public function addItem(int $id, int $quantity, $multiplier = 1) : object
    {
        $response = new \stdClass();
        $response->message = "";
        $response->quantity = "";
        $response->value = "";
        $response->total = "";

        $itemId = $id."-".str_replace([".",","], "-", $multiplier);
        $product = (new ProductVariations())->findById($id);


        if($product){
            $cart = new \Anam\Phpcart\Cart(CARRINHO);

            if($multiplier > 1){

                $stock = 0;
                foreach ($cart->getItems() as $item) {
                    if($item->idProd == $product->id){
                        $stock += $item->multiplier * $item->quantity;
                    }
                }
                $newStock = $stock + ($quantity * $multiplier);

                if($product->stock == -1 OR $product->stock >= $newStock){
                    //DISCONTO EM ROLO INTEIRO
                    $largura = str_replace(["_", " ", "cm"], [".", "", ""], $product->first_variation_item)/100;
                    if($multiplier == 25 AND $largura == 1.23){
                        $realPrice = $product->price * CONF_FULL_SIZE_DISCOUNT;
                        $realPromoPrice = $product->promotional_price * CONF_FULL_SIZE_DISCOUNT;
                    }else{
                        $realPrice = $product->price;
                        $realPromoPrice = $product->promotional_price;
                    }

                    $cart->add([
                        'id' => $itemId,
                        'idProd'=> $product->id,
                        'name' => $product->product()->title,
                        'firstVariation' => $product->first_variation_item,
                        'quantity' => $quantity,
                        'multiplier' => $multiplier,
                        'price' => ($realPromoPrice > 0 ?  $realPromoPrice : $realPrice)*$multiplier,
                        'cover' => $product->product()->cover,
                        'uri' => $product->product()->uri,
                        'width' => $product->width,
                        'weight' => $product->weight * $multiplier + 1.6,
                        'height' => $product->height,
                        'depth' => $product->depth
                    ]);
                    $response->message = $this->message->success("Item adicionado com sucesso.")->render();
                    $response->quantity = $quantity;
                    $response->value = preco_real($quantity * $cart->get($product->id)->price);
                    $response->total = preco_real($cart->getTotal());

                    return $response;
                }else{
                    $response->message = $this->message->info("Não temos mais metragem para este produto")->render();
                    return $response;
                }
            }

            if($multiplier <= 1){
            $cart->get($itemId) ? $qty = $cart->get($itemId)->quantity + $quantity : $qty = $quantity;

            $cart->add([
                'id' => $itemId,
                'idProd'=> $product->id,
                'name' => $product->product()->title,
                'firstVariation' => $product->first_variation_item,
                'quantity' => $quantity,
                'multiplier' => $multiplier,
                'price' => ($product->promotional_price > 0 ? $product->promotional_price : $product->price)*$multiplier,
                'cover' => $product->product()->cover,
                'uri' => $product->product()->uri,
                'width' => $product->width,
                'weight' => $product->weight,
                'height' => $product->height,
                'depth' => $product->depth
            ]);

                if($product->stock == -1 OR $product->stock >= $qty){
                    $response->message = $this->message->success("Item adicionado com sucesso no carrinho, Obrigado!")->render();
                    $response->quantity = $quantity;
                    $response->value = preco_real($qty * $cart->get($itemId)->price);
                    $response->total = preco_real($cart->getTotal());

                    return $response;
                }else{

                    $response = $this->updateItem($id, $qty, $multiplier);
                    return $response;
                }
            }


        }
        return $response;
    }

    public function updateItem(int $id, int $quantity, $multiplier = 1) : object
    {


        $response = new \stdClass();
        $response->message = "";
        $response->quantity = "";
        $response->value = "";
        $response->total = "";
        $itemId = $id."-".str_replace([".",","], "-", $multiplier);

        $product = (new ProductVariations())->findById($id);
        if($product){
            $cart = new \Anam\Phpcart\Cart(CARRINHO);

            if($quantity == 0){
                $response = $this->removeItem($id, $multiplier);
                return $response;
            }
            if($product->stock == -1 OR $product->stock >= $quantity){
                $cart->updateQty($itemId, $quantity);
                $response->message = $this->message->success("Item atualizado com sucesso no carrinho, Obrigado!")->render();
                $response->quantity = $quantity;
                $response->value = preco_real($quantity * $cart->get($itemId)->price);
                $response->total = $cart->getTotal();
                return $response;
            }else{
                $cart->updateQty($itemId, $product->stock);
                $response->message = $this->message->warning("Só conseguimos adicionar {$product->stock} peça(s) ao carrinho. Não temos estoque suficiente para maiores quantidades.")->render();
                $response->quantity = $product->stock;
                $response->value = preco_real($product->stock * $cart->get($itemId)->price);
                $response->total = $cart->getTotal();

                return $response;
            }

        }
        return $response;
    }

    public function removeItem(int $id, $multiplier = 1) : object
    {
        $response = new \stdClass();
        $response->message = "";
        $response->total = "";
        $response->count = "";
        $itemId = $id."-".str_replace([".",","], "-", $multiplier);

        $cart = new \Anam\Phpcart\Cart(CARRINHO);
        $cart->remove($itemId);
        $response->message = $this->message->success("Item removido com sucesso do carrinho, Obrigado!")->render();
        $response->total = $cart->getTotal();
        $response->quantity = 0;
        $response->count = $cart->totalQuantity();
        return $response;

    }

    /**
     * SITE NEWSLETTER
     */
    public function newsletter(array $data): void
    {
        if(isset($data["action"]) AND $data["action"] == "newsletter"){
            $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
            if (request_limit("newsletter", 5, 60*3)) {
                $json['message'] = $this->message->error("Você já efetuou 5 tentativas de cadastro, esse é o limite. Por favor, aguarde 3 minutos para tentar novamente!")->render();
                echo json_encode($json);
                return;
            }

            if(in_array("", $data)){
                $json['message'] = $this->message->warning("Você deve preencher seu email")->render();
                echo json_encode($json);
                return;
            }

            if(!is_email($data['email'])){
                $json['message'] = $this->message->info("Formato de email inválido")->render();
                echo json_encode($json);
                return;
            }

            $newsletter = (new Newsletter())->findByEmail($data["email"]);
            $user = (new User())->findByEmail($data["email"]);
            if($user){
                if($user->data()->newsletter == 0){
                    $json['message'] = $this->message->success("Inscrição Efetuada com sucesso")->render();
                    $user->newsletter = 1;
                    $user->save();
                    echo json_encode($json);
                    return;
                }

                if($user->data()->newsletter == 1){
                    $json['message'] = $this->message->info("Seu email já está em nossa newsletter")->render();
                    echo json_encode($json);
                    return;
                }
            }
            if($newsletter){
                $json['message'] = $this->message->info("Seu email já está em nossa newsletter")->render();
                echo json_encode($json);
                return;
            }
            $newsCreate = new Newsletter();

            $newsCreate->email = $data["email"];
            $newsCreate->save();

            $json['message'] = $this->message->success("Inscrição Efetuada com sucesso {$newsletter->email}")->render();
            echo json_encode($json);
            return;

        }

    }

    public function zipcode(array $data) : void
    {
        if(isset($data) AND $data["action"] == "zipcode"){
            $session = new Session();
            $address = (new Address())->findById($data['id']);
            $address->data()->id;
            $session->set("cep",
                [   "cep"=>$data["zipcode"],
                    "endereco" => $address->data()->street,
                    "numero" => $address->data()->number,
                    "bairro"=>$address->neighborhood,
                    "complemento"=>$address->complement,
                    "cidade"=>$address->city,
                    "estado"=>$address->state
                ]);
            $json["message"] = $this->message->success("Cep Atualizado com Sucesso")->render();
            echo json_encode($json);
            return;
        }

    }

    public function shippingCost(array $data):void
    {

        $cart = new Cart(CARRINHO);


        if(isset($data["zipcode"])){
            $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
            $session = new Session();
            if($data["zipcode"] == ""){
                $session->unset("cep");
            }else{
                $session->set("cep", ["cep"=>$data["zipcode"]]);
                $session->regenerate();
            }
            $frenet = new FreteFrenet(CONF_SITE_ADDR_ZIPCODE, $data["zipcode"], $cart->getTotal());
            $frenetResult = $frenet->getServices();


            $html = "<table class=\"table table-bordered table-striped\">";
            $html .= "<thead><tr><th>Class</th><th>Description</th></tr></thead><tbody>";
            foreach ($frenetResult as $f){
                $f->getError() ? $value = "Serviço Indisponível" : $value = "R$ ". preco_real($f->getShippingPrice());
                $html .= "<tr><td><code>".$f->getServiceDescription()."</code></td>";
                $html .= "<td>". $value."</td></tr>";
            }
            $html .= "</tbody></table>";

            $json["message"] = $this->message->success("Frete calculado com sucesso")->render();
            $json["popup"] = true;
            $json["target"] = "#myModal1";
            $json["result"] = $html;

            echo json_encode($json);
            return;
        }
        return;

    }

    public function creditCard(array $data)
    {



        if(isset($data) AND $data["action"] == "delete"){
            $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
            $cardDelete = (new CreditCard())->findById($data["id"]);
            if (!$cardDelete) {
                $this->message->error("Você tentou excluir um Cartão que não existe ou já foi removido")->flash();
                echo json_encode(["reload" => true]);
                return;
            }
            $cardDelete->destroy();
            $json['message'] = $this->message->success("Cartão Deletado com Sucesso")->flash();
            echo json_encode(["redirect" => url("restrito/cartoes")]);
            return;
        }

        if(isset($data["number"])){
            $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
        }

        if(in_array("", $data)){
            if(isset($data["action"]) AND $data["action"] == "pay"){
                return "empty";
            }
            $json["message"] = $this->message->warning("Todos campos são obrigatórios")->render();
            echo json_encode($json);
            return;
        }
        $uid = user()->data()->id;
        $ld = card_last_digits($data["number"]);
        $fd = card_first_digits($data["number"]);
        $cc = new CreditCard();

        if($cc->find("user_id = :uid AND last_digits = :ld AND first_digits = :fd", "uid={$uid}&ld={$ld}&fd={$fd}")->fetch()){
            if(isset($data["action"]) AND $data["action"] == "pay"){
                return "exists";
            }
            $json["message"] = $this->message->info("Cartão já cadastrado, escolha como meio de pagamento ou delete em sua área pessoal")->render();
            echo json_encode($json);
            return;
        }

        $date = \DateTime::createFromFormat("m/Y", str_replace(" ", "", $data["expiry"]))->format("my");
        $card = new Pagarme();
        $cardHash = $card->createCreditCard($data["name"], $data["number"], $date , $data["cvv"], user()->data()->integration_pagarme);

        if(!$cardHash OR $card->getError()){
            $json["message"] = $this->message->error("Cartão Inválido ou com problema no processamento, por favor utilize outro meio de pagamento")->render();
            echo json_encode($json);
            return "invalid";
        }

        if($cardHash->valid === true){
            $cc->user_id = user()->data()->id;
            $cc->brand = $cardHash->brand;
            $cc->first_digits = $cardHash->first_digits;
            $cc->last_digits = $cardHash->last_digits;
            $cc->hash = $cardHash->id;
            $cc->cvv = $data["cvv"];

            $cc->save();

            if(isset($data["action"]) AND $data["action"] == "pay"){
                return $cardHash->id;
            }

            $json["message"] = $this->message->success("Cartão Criado com sucesso")->flash();
            $json["reload"] = true;
            echo json_encode($json);
            return;
        }
        return;
    }

    public function pay($data)
    {

        if(isset($data)){
            $data = filter_var_array($data, FILTER_SANITIZE_STRIPPED);
        }

        //VERIFICA CARRINHO

        $cart = new Cart(CARRINHO);
        $change = null;
        foreach ($cart->items() as $item) {
            $product = (new ProductVariations())->findById($item->id);
            if($product->stock == -1){
                $change = 0;
            }elseif($product->stock == 0){
                $change = 1;
                $cart->remove($item->id);
            }elseif($item->quantity > $product->stock){
                $change = 1;
                $cart->updateQty($item->id, $product->stock);
            }
        }
        if($change){
            $json["message"] = $this->message->error("Seu carrinho sofreu alterações devido ao estoque atual, confira o carrinho antes de continuar")->flash();
            $json["reload"] = true;
            echo json_encode($json);
            return;
        }

        //VERIFICA CUPOM
        if(isset($_SESSION[CONF_SITE_NAME."-coupon"]) AND $_SESSION[CONF_SITE_NAME."-coupon"]->code != ""):
            $cp = $_SESSION[CONF_SITE_NAME."-coupon"];
            if(coupon_validate($cp->code)){
                $desconto = ($cart->getTotal() * $cp->value)/100;
            }else{
                unset($_SESSION[CONF_SITE_NAME."-coupon"]);
                $desconto = 0.00;
                unset($cp);
                $json["message"] = $this->message->error("Seu Cupom esgotou, favor reveja seu total")->flash();
                $json["reload"] = true;
                echo json_encode($json);
                return;
            }
        else:
            unset($_SESSION[CONF_SITE_NAME."-coupon"]);
            $desconto = 0.00;
            unset($cp);
        endif;

        $Pagarme = new Pagarme();

        if($data["type"] == "creditNew"){

            $callback = $this->creditCard($data);
            if($callback == "empty"){
                $json["message"] = $this->message->warning("Todos campos são obrigatórios")->render();
                echo json_encode($json);
                return;
            }
            if($callback == "exists"){
                $json["message"] = $this->message->warning("Cartão já cadastrado, selecione na lista")->render();
                echo json_encode($json);
                return;
            }
            if($callback == "invalid"){
                $json["message"] = $this->message->error("Cartão inválido, favor usar outro meio de pagamento")->render();
                echo json_encode($json);
                return;
            }
            $Pagarme->getCustomer(user()->data()->integration_pagarme);
            $Pagarme->getCreditCard($callback);
            //$Pagarme->setItems(1, "Items Diversos", $data["total"] + $data["frete"], 1);
            $transaction = $Pagarme->payRequest($data["total"] - $desconto + $data["frete"],false, $data["installments"]);
            $type = "Cartão de Crédito";

        }
        if($data["type"] == "creditHash"){
            if(!isset($data["hash"])){
                $json["message"] = $this->message->error("Você precisa selecionar um cartão da sua lista")->render();
                echo json_encode($json);
                return;
            }
            $card = (new CreditCard())->findById($data["hash"]);

            $Pagarme->getCustomer(user()->data()->integration_pagarme);
            $Pagarme->getCreditCard($card->hash);
            //$Pagarme->setItems(1, "Items Diversos", $data["total"] + $data["frete"], 1);
            $transaction = $Pagarme->payRequest($data["total"] - $desconto + $data["frete"], false, $data["installments"]);
            $type = null;

            $type = "Cartão de Crédito";
        }


        if($data["type"] == "billet"){
            $Pagarme->billet("7", "");
            $Pagarme->getCustomer(user()->data()->integration_pagarme);
            $transaction = $Pagarme->payRequest($data["total"] + $data["frete"] - $desconto - $data["discountPayment"], false);

            $type = "Boleto";
        }


        if($transaction){

            $Order = new Orders();
            $Order->user_id = user()->data()->id;
            $Order->products_price = $data["total"];
            $Order->shipment_price = $data["frete"];
            $Order->shipment_type = $data["freteType"];
            $Order->integration_order = $transaction->id;
            $Order->payment_type = $type;
            $Order->discount_payment = $data["discountPayment"] ? $data["discountPayment"] : 0.00;
            $Order->status = $transaction->status;
            $Order->card_id = $transaction->card->id ? $transaction->card->id : null;
            $Order->billet_barcode = $transaction->boleto_barcode ? $transaction->boleto_barcode : null;
            $Order->billet_link = $transaction->boleto_url ? $transaction->boleto_url : null;
            $Order->billet_expiration = $transaction->boleto_expiration_date ? $transaction->boleto_expiration_date : null;
            $Order->installments = $data["installments"] ? $data["installments"] : 1;
            $Order->zipcode = verifyAddress(true)->cep;
            $Order->street = verifyAddress(true)->endereco;
            $Order->number = verifyAddress(true)->numero;
            $Order->complement = verifyAddress(true)->complemento;
            $Order->neighborhood = verifyAddress(true)->bairro;
            $Order->state = verifyAddress(true)->estado;
            $Order->city = verifyAddress(true)->cidade;
            $Order->discount = $desconto;
            $Order->coupon_id = ($cp->id ? $cp->id : null);
            $Order->partner_id = ($cp->partner ? $cp->partner : null);

            if($cp->id){
                $coupon = (new Coupon())->findById($cp->id);
                $coupon->uses = $coupon->uses +1;
                $coupon->save();
            }

            $id = $Order->saveId();
            if (!$id){
                $json["message"] = $this->message->error("Erro ao processar sua solicitação, favor contatar o suporte")->render();
                echo json_encode($json);
                return;
            }

            foreach ($cart->items() as $item) {
                $product = (new ProductVariations())->findById($item->idProd);
                $oItem = new OrderItens();
                if($product->stock != -1){
                        $product->stock = $product->stock - ($item->quantity * $item->multiplier);
                        $product->save();
                }

                $oItem->order_id = $id;
                $oItem->product_name = $item->name;
                $oItem->quantity = $item->quantity;
                $oItem->price = $item->price;
                $oItem->variation_id = $item->idProd;
                $oItem->variation_type = $product->type;
                $oItem->variation_feature = $product->feature;
                $oItem->first_variation = $item->firstVariation;
                $oItem->multiplier = $item->multiplier;
                $oItem->save();
            }

            $view = new View(__DIR__ . "/../../shared/views/email");
            $message = $view->render("order", [
                "user" => user(),
                "itens" => $cart->items(),
                "order" => $Order
            ]);

            (new Email())->bootstrap(
                "Sua compra na " . CONF_SITE_NAME,
                $message,
                user()->data()->email, user()->fullName()
            )->send();

            unset($_SESSION[CONF_SITE_NAME."-coupon"]);
            unset($cp);
            $json["message"] = $this->message->success("Compra efetuada com sucesso")->render();
            $json["redirect"] =  url("/finalizar/{$Order->integration_order}");
            echo json_encode($json);
            return;
        }
    }
}