Giter Site home page Giter Site logo

setono / syliusgiftcardplugin Goto Github PK

View Code? Open in Web Editor NEW
43.0 7.0 35.0 2.03 MB

Sell gift cards on your Sylius store and let users use them in the checkout process

License: MIT License

PHP 85.59% JavaScript 0.89% Gherkin 3.31% Twig 10.21%
symfony sylius sylius-plugin php

syliusgiftcardplugin's Introduction

Sylius Gift Card Plugin

Latest Version on Packagist Software License Build Status

Add gift card functionality to your store:

  • Buy gift cards
  • Use gift cards to purchase products
  • See the balance of a gift card by looking up the gift card code

The administrator will have access to a dashboard showing the total outstanding balance of gift cards which can be used for auditing.

Screenshots

▶▶ Skip screenshots and go to installation

Screenshot showing admin menu and index

Screenshot showing gift card admin create page

Api platform support

Everything related to Gift Card can be done via API. Whether it is admin or shop actions

Installation

Require plugin with composer:

$ composer require setono/sylius-gift-card-plugin

Import configuration:

# config/packages/setono_sylius_gift_card.yaml
imports:
    # ...
    - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" }

(Optional) Import fixtures

If you wish to have some gift cards to play with in your application during development.

# config/packages/setono_sylius_gift_card.yaml
imports:
    # ...
    - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" }

Import routing:

# config/routes.yaml
setono_sylius_gift_card:
    resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes.yaml"

or if your app doesn't use locales:

# config/routes.yaml
setono_sylius_gift_card:
    resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes_no_locale.yaml"

Add plugin class to your bundles.php:

Make sure you add it before SyliusGridBundle, otherwise you'll get You have requested a non-existent parameter "setono_sylius_gift_card.model.gift_card.class". exception.

<?php
$bundles = [
    // ...
    Setono\SyliusGiftCardPlugin\SetonoSyliusGiftCardPlugin::class => ['all' => true],
    Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true],
    // ...
];

Copy templates

You will find the templates you need to override in the test application.

Extend entities

Extend Product

<?php

# src/Entity/Product/Product.php

declare(strict_types=1);

namespace App\Entity\Product;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusGiftCardPlugin\Model\ProductInterface as SetonoSyliusGiftCardProductInterface;
use Setono\SyliusGiftCardPlugin\Model\ProductTrait as SetonoSyliusGiftCardProductTrait;
use Sylius\Component\Core\Model\Product as BaseProduct;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_product")
 */
class Product extends BaseProduct implements SetonoSyliusGiftCardProductInterface
{
    use SetonoSyliusGiftCardProductTrait;
}

Extend Order

<?php

# src/Entity/Order/Order.php

declare(strict_types=1);

namespace App\Entity\Order;

use Setono\SyliusGiftCardPlugin\Model\OrderInterface as SetonoSyliusGiftCardPluginOrderInterface;
use Setono\SyliusGiftCardPlugin\Model\OrderTrait as SetonoSyliusGiftCardPluginOrderTrait;
use Sylius\Component\Core\Model\Order as BaseOrder;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_order")
 */
class Order extends BaseOrder implements SetonoSyliusGiftCardPluginOrderInterface
{
    use SetonoSyliusGiftCardPluginOrderTrait {
        SetonoSyliusGiftCardPluginOrderTrait::__construct as private __giftCardTraitConstruct;
    }
    
    public function __construct()
    {
        $this->__giftCardTraitConstruct();

        parent::__construct();
    }
}

Extend OrderItem

<?php

# src/Entity/Order/OrderItem.php

declare(strict_types=1);

namespace App\Entity\Order;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusGiftCardPlugin\Model\OrderItemTrait as SetonoSyliusGiftCardOrderItemTrait;
use Sylius\Component\Core\Model\OrderItem as BaseOrderItem;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_order_item")
 */
class OrderItem extends BaseOrderItem
{
    use SetonoSyliusGiftCardOrderItemTrait;
}

Extend OrderItemUnit

<?php

# src/Entity/Order/OrderItemUnit.php

declare(strict_types=1);

namespace App\Entity\Order;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface as SetonoSyliusGiftCardOrderItemUnitInterface;
use Setono\SyliusGiftCardPlugin\Model\OrderItemUnitTrait as SetonoSyliusGiftCardOrderItemUnitTrait;
use Sylius\Component\Core\Model\OrderItemUnit as BaseOrderItemUnit;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_order_item_unit")
 */
class OrderItemUnit extends BaseOrderItemUnit implements SetonoSyliusGiftCardOrderItemUnitInterface
{
    use SetonoSyliusGiftCardOrderItemUnitTrait;
}

Extend OrderRepository:

<?php

# src/Doctrine/ORM/OrderRepository.php

declare(strict_types=1);

namespace App\Doctrine\ORM;

use Setono\SyliusGiftCardPlugin\Repository\OrderRepositoryInterface as SetonoSyliusGiftCardPluginOrderRepositoryInterface;
use Setono\SyliusGiftCardPlugin\Doctrine\ORM\OrderRepositoryTrait as SetonoSyliusGiftCardPluginOrderRepositoryTrait;
use Sylius\Bundle\CoreBundle\Doctrine\ORM\OrderRepository as BaseOrderRepository;

class OrderRepository extends BaseOrderRepository implements SetonoSyliusGiftCardPluginOrderRepositoryInterface
{
    use SetonoSyliusGiftCardPluginOrderRepositoryTrait;
}

Extend CustomerRepository:

<?php

# src/Doctrine/ORM/CustomerRepository.php

declare(strict_types=1);

namespace App\Doctrine\ORM;

use Setono\SyliusGiftCardPlugin\Repository\CustomerRepositoryInterface as SetonoSyliusGiftCardPluginCustomerRepositoryInterface;
use Setono\SyliusGiftCardPlugin\Doctrine\ORM\CustomerRepositoryTrait as SetonoSyliusGiftCardPluginCustomerRepositoryTrait;
use Sylius\Bundle\CoreBundle\Doctrine\ORM\CustomerRepository as BaseCustomerRepository;

class CustomerRepository extends BaseCustomerRepository implements SetonoSyliusGiftCardPluginCustomerRepositoryInterface
{
    use SetonoSyliusGiftCardPluginCustomerRepositoryTrait;
}
  • Add configuration:
# config/services.yaml
sylius_customer:
    resources:
        customer:
            classes:
                repository: App\Doctrine\ORM\CustomerRepository

sylius_order:
    resources:
        order:
            classes:
                model: App\Entity\Order\Order
                repository: App\Doctrine\ORM\OrderRepository
        order_item:
            classes:
                model: App\Entity\Order\OrderItem
        order_item_unit:
            classes:
                model: App\Entity\Order\OrderItemUnit
                
sylius_product:
    resources:
        product:
            classes:
                model: App\Entity\Product\Product

Copy Api Resources

Resources declaration that need to be copied are:

If you already have them overriden, just change the following routes:

Order.xml

<itemOperation name="shop_add_item">
    <attribute name="method">PATCH</attribute>
    <attribute name="path">/shop/orders/{tokenValue}/items</attribute>
    <attribute name="messenger">input</attribute>
    <attribute name="input">Setono\SyliusGiftCardPlugin\Api\Command\AddItemToCart</attribute> <!-- This has been changed compared to the core -->
    <attribute name="normalization_context">
        <attribute name="groups">shop:cart:read</attribute>
    </attribute>
    <attribute name="denormalization_context">
        <attribute name="groups">shop:cart:add_item</attribute>
    </attribute>
    <attribute name="openapi_context">
        <attribute name="summary">Adds Item to cart</attribute>
    </attribute>
</itemOperation>

Update your database:

$ bin/console doctrine:migrations:diff
$ bin/console doctrine:migrations:migrate

Install assets:

$ php bin/console assets:install

Clear cache:

$ php bin/console cache:clear

Configuration

Change redirect routes on add/remove gift card to/from order

You can customize where you will be redirected after adding or removing a gift card. To do so, you can simply change the route configuration :

setono_sylius_gift_card_shop_remove_gift_card_from_order:
    path: /gift-card/{giftCard}/remove-from-order
    methods: GET
    defaults:
        _controller: setono_sylius_gift_card.controller.action.remove_gift_card_from_order
        redirect:
            route: sylius_shop_cart_summary
            parameters: []

The same applies for the setono_sylius_gift_card_shop_partial_add_gift_card_to_order route

You can also override or decorate the service setono_sylius_gift_card.resolver.redirect_url to define a more custom way of redirecting

Usage

In order to find out how to use the GiftCard plugin, please refer to the usage.

Development

Testing

$ composer tests

Playing

To run built-in application showing plugin at work, just run:

$ composer try

Contribution

Learn more about our contribution workflow on http://docs.sylius.org/en/latest/contributing/.

Please, run composer all to run all checks and tests before making pull request.

syliusgiftcardplugin's People

Contributors

bitbager avatar chadyred avatar dependabot-preview[bot] avatar florian-merle avatar igormukhingmailcom avatar julienloison avatar jum4 avatar loevgaard avatar lruozzi9 avatar mbugla avatar patrick477 avatar roshyo avatar sabrineferchichi avatar sophiebb avatar techbech avatar thedevilonline avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

syliusgiftcardplugin's Issues

Don't use Semantic JS

I am using the default JS which uses the api() method of the Semantic JS. It shouldn't use this. Instead just use the normal jQuery.ajax

image

[RFC] Security questions

I wasn't right at #25 that csrf protects from brute force attack, so to protect from it, we probably should add some actual protection. Like https://www.google.com/recaptcha/intro/v3.html

From other side, even with captcha protection here, attacker can brute force cart (by checking response for terms that means gift card applied) and we can't add something like captcha to cart.

So, I guess, the only way is:

  • Add some min code length rule at configuration and not allow to generate codes with length < 16 chars for example (at the same time, admin created codes allowed to be not long - so admins can create gift cards with codes like "GIFT4BESTCLIENT")

Easier grid configuration

Suggest:

  • putting default grid configuration to config/app/config.yaml to just include it
  • OR prepend it via $container->prependExtensionConfig

rather than copy-paste.

Installation is not possible. Folders missing.

I can't install plugin from readme file because:
cp -r vendor/setono/sylius-gift-card-plugin/tests/Application/templates/bundles/SyliusShopBundle/ templates/bundles/SyliusShopBundle/ cp: can't stat 'vendor/setono/sylius-gift-card-plugin/tests/Application/templates/bundles/SyliusShopBundle': No such file or directory

image

Some folders are excluded in .gitattributes

Please fix this

Think about renaming `findByEmailPart`

As AdminOrderCreation plugin have the same name at its CustomerRepositoryTrait.

Something like findByEmailPartForGiftCard (append context) or setonoFindByEmailPart (prepend vendor name).

Reasons:

  • Interfaces the same right now, but implementations still a bit different
  • Something can change at future

Related:

Unrecognized field: default

Hey. I've just installed your plugin (version 0.8.1) on Sylius 1.6 and have an issue with printing giftcard to PDF.

Steps:

  1. Install fixtures
  2. Create simple giftcard
  3. Try to print giftcard into pdf

Result:
image

Create compiler pass that clears gift card adjustment

Somethiing like this:

final class AddAdjustmentsToOrderAdjustmentClearerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if (!$container->has('sylius.order_processing.order_adjustments_clearer')) {
            return;
        }
        $clearerDefinition = $container->getDefinition('sylius.order_processing.order_adjustments_clearer');
        /** @var array $adjustmentsToRemove */
        $adjustmentsToRemove = $clearerDefinition->getArgument(0);
        $adjustmentsToRemove[] = AdjustmentInterface::ORDER_GIFT_CARD;
        $clearerDefinition->setArgument(0, $adjustmentsToRemove);
    }
}

List of Orders payed with GiftCard

If balances not equal (so gift card used) - ability to click on Used at orders link/button and see page with Orders list where this GiftCard was used.

  • For admin
  • For customer?

Order fixtures issue

Hello! :)

I'm using your plugin (0.8.1) on Sylius 1.6.

As you recommend, I'm using your order trait:

class Order extends BaseOrder implements SetonoSyliusGiftCardPluginOrderInterface
{
    use SetonoSyliusGiftCardPluginOrderTrait {
        SetonoSyliusGiftCardPluginOrderTrait::__construct as private __giftCardTraitConstruct;
    }
}

When I do this, my fixtures installation command tells me:

image

But when I do it this way:

class Order extends BaseOrder implements SetonoSyliusGiftCardPluginOrderInterface
{
    use SetonoSyliusGiftCardPluginOrderTrait;

    public function __construct()
    {
        parent::__construct();
        $this->giftCards = new ArrayCollection();
    }
}

It works correctly.

Creation of gift card

When I create a gift card in the backend the option Is shipping required should be set to false by default (since a gift card will be delivered by email).

Invalid card shouldn't break cart

If we put invalid or empty card number at /cart/ - something like json representation of form will be returned rather than just error message at cart

Link to templates rather than copying them

We have instruction to copy templates at installation steps.
Suggest copying/creating one-line-templates which just include desired ones.
Like this:

# app/Resources/SomeBundle/views/someView.html.twig
{% extends '@SyliusGiftCard/someView.html.twig' %}

Includable templates

So small updates at gift card plugin templates can be automatically updated in apps

Fixtures

We need fixtures

PS: README.md have instruction to include fixtures.

List orders should show only completed orders

  • List orders page should show only completed orders (as we have Impossible to access an attribute ("firstName") on a null variable. exception if gift card attached to cart and order not completed yet)
  • List orders button should not be shown only if gift card used on completed order

JS file never included - Invalid gift card renders JSON

Obviously a JS problem, same as #44, so I checked which JS files are loaded... And the only one, setono-sylius-gift-card-add-gift-card-to-order.js, isn't.
I checked in the vendor files, and apparently it's never included anywhere ! And surprisingly I didn't find any issue here about this.
I also tried to manually include it, but that doesn't seem to fix the problem.
I even tried to copy this block from test cart summary file (only file I found using this js here) :

    <script src="{{ asset('bundles/setonosyliusgiftcardplugin/setono-sylius-gift-card-add-gift-card-to-order.js') }}"></script>
    <script>
        $('#setono-sylius-gift-card-add-gift-card-to-order').addGiftCardToOrder();
    </script>

But again, that didn't fix the problem.

Release plugin once finished

... as it required at another plugins (and we usually have prefer-stable flag).
Or at least release, say, version 'v0.1.0' until it become stable.

Allow to enter GiftCard code in the same input as coupon

It would be useful to allow users to enter the Gift card code in the same input as regular coupon. It should also be a possibility, not the unique behavior. So we could add in admin panel a new configuration for GiftCard that would be like "Have 2 separate inputs in cart ?"

If yes : keep behavior like now
If no : Hook on "coupon application" and check whether it's a coupon (default behavior) or a Gift Card code.

We would also need to add a validator to GiftCardCode so they are never the same as coupon

unable to install >> don't install thecodingmachine/safe v0.1.16

Hello,

When trying to install (composer require setono/sylius-gift-card-plugin), I have the following issue:

Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for setono/sylius-gift-card-plugin ^0.7.0 -> satisfiable by setono/sylius-gift-card-plugin[v0.7.0].
- Conclusion: remove thecodingmachine/safe v0.1.16
- Conclusion: don't install thecodingmachine/safe v0.1.16
- setono/sylius-gift-card-plugin v0.7.0 requires thecodingmachine/safe ^1.0 -> satisfiable by thecodingmachine/safe[v1.0.0, v1.0.1, v1.0.2, v1.0.3, v1.1, v1.1.1, v1.1.2, v1.1.3].
- Can only install one of: thecodingmachine/safe[v1.0.0, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.0.1, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.0.2, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.0.3, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.1, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.1.1, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.1.2, v0.1.16].
- Can only install one of: thecodingmachine/safe[v1.1.3, v0.1.16].
- Installation request for thecodingmachine/safe (locked at v0.1.16) -> satisfiable by thecodingmachine/safe[v0.1.16].

Installation failed, reverting ./composer.json to its original content.

Could you please help me? I'd love to try this extension but I am stuck at installation stage for now.

Thanks,

Jon

how does coupon activation work?

Hello,

Thank you for this plug-in!
I have a question about how it works.

I created a product and turned it into a gift card.
Capture d’écran 2020-04-23 à 17 52 22

It works for the purchase and I find my new coupon.
Capture d’écran 2020-04-23 à 17 53 48

But I don't understand why sometimes he's Enabled other times Disabled.

Can you tell me the logic behind this process please?

Thank you very much for your help!

Wrong message when I search for gift cards

When I search for a gift card on this page: http://127.0.0.1:8000/app_dev.php/en_US/gift-card/search for a gift card that doesn't exist I get this message: Your gift card will only be charged if you complete your order. The message should probably be The gift card does not exist.

If I search for a gift card with balance $0 I get the same message. I should instead see a balance of $0.

Customer should see all bought gift cards

For Customer, at account area, some page with list of all gift cards (balances and links to view it) will be great I guess

As security option, probably Customer shouldn't see full codes, just have a buttons to send code to own email.

Allow to change the redirect URL when adding or deleting gift cards

I had to allow the customer to add and remove gift card on the payment step of the checkout process. I needed the customer to be redirected to the payment step and not to the cart summary page.
I had to override AddGiftCardToOrderAction, RemoveGiftCardFromOrderAction and addGiftCardToOrder.html.twig to achieve that (replacing sylius_shop_cart_summary by the route I wanted to redirect to)

May be it could be done with the referrer from the request, this way no matter where your user decides to implement the plugin, the customer will be redirected to the page the request came from ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.