Aller au contenu

omnibase/marketplace Référence de l’API

Étage
Structure préparée · Omnibase
Version
main
Vérifié en réel
Son README ne le dit pas
Licence
MIT
composer require omnibase/marketplace:dev-main

Lue dans les fichiers PHP du paquet au commit f058ad62b5f4 : ses espaces de noms, classes, interfaces et énumérations, leurs constantes, propriétés et méthodes publiques avec leur PHPDoc, et les options que prennent ses fabriques. Rien n’en est exécuté.

App\Controller

  • DemoController class

    The demonstrator's one page: it seeds a small shop, signs a visitor in, fills a cart and pays two orders - then hands over to the shop itself.

    2 methods

App\Entity

  • User class

    The demo's member. base-bundle's User identifies people by email and has no username; the forum and the mailbox address members by username (an @mention, a recipient typed by hand), so the application's User carries one - as every base-bundle application's User does.

    3 methods

App\Payment

  • DemoGateway class

    An application's own gateway, as small as one gets: it accepts every order at once. A real one would call its payment service and answer paid(), pending(), redirect($url) or refused('reason.key').

    3 methods

App\Repository

Base\Marketplace

Base\Marketplace\Attribute

  • OrderReference class

    A human order reference, generated once on the first flush:

    5 methods

Base\Marketplace\Catalogue

  • CatalogueNotificationListener class

    A platform's product or stock webhook (through PaymentController's /marketplace/{gateway}/webhook, checked by the omnitrade gateway): the product brought in again, taken off sale when deleted, its stock counted - when the catalogue is read from that gateway (marketplace.catalogue.source).

    2 methods

  • InventorySynchronizer class

    The stock levels alone, more often than the whole catalogue: every linked variant's count read from the platform (FetchInventory) and written here.

    3 methods

  • PlatformSynchronizer class

    The catalogue kept on a platform, copied here: every product an omnitrade gateway reads (Stripe's Products, a Shopify shop, a WooCommerce site) becomes a Product of the store - its variants Variants -, its vendor a Brand, its key/value attributes the attributes of the same code, its tags Features, its SKU and barcode identifiers. Payment stays wherever the shop pays (omnitrade/stripe), whatever the source of the catalogue.

    10 methods · 1 constant

Base\Marketplace\Console

  • CatalogueSyncCommand class

    marketplace:catalogue:sync [gateway]: the catalogue of a platform read in (marketplace.catalogue.source when no gateway is named). Incremental by default - what changed there since the last change read -, --full reads everything and takes off sale what the platform no longer has, --inventory reads the stock levels only. Run it from the cron container.

    1 method

  • InvoiceIssueCommand class

    marketplace:invoice:issue <order>...: the invoices of paid orders, by their reference - what the back office's "Issue the invoice" does, for a script or a catch-up. An order that has its invoice is said and skipped.

    1 method

  • ReferralsCommand class

    marketplace:referrals: every night from the cron container - the referrers whose referee's order held are rewarded.

    1 method

  • StripeWebhookCommand class

    Makes sure Stripe knows where to send the marketplace's events: for every payment method on an omnitrade gateway whose provider is Stripe, the webhook endpoint on marketplace_payment_webhook, listening to the Checkout events PaymentController handles. Safe to run again and again - on every deploy, from the container's entrypoint:

    1 method · 1 constant

  • SubscriptionsCommand class

    marketplace:subscriptions: every night from the cron container. Announces the rights that ended (EntitlementEndedEvent) and those about to (EntitlementEndingEvent), once each; --sync first asks the providers where each running subscription stands, for the events a webhook missed.

    1 method

  • WishlistRefreshCommand class

    marketplace:wishlist:refresh-prices: every night from the cron container.

    1 method

Base\Marketplace\Controller\Admin

  • AbstractMarketplaceCrudController class

    Every marketplace screen of the back office: products, stores, orders, taxes, exchange rates... For the creators (`marketplace.admin_role`, by default ROLE_SUPERADMIN; ROLE_EDITOR inherits it), and for a shop's owners to read (MarketplaceVoter): an application's other staff keep their own screens (a kitchen, a till) without the catalogue, the prices or the money.

  • MarketplaceAdminTrait trait

    The marketplace screens' permissions (MarketplaceVoter), for every marketplace CRUD - used by AbstractMarketplaceCrudController, and directly by a CRUD controller that already extends another admin base (taxons, adapters):

    2 methods

  • QuotePipelineController class

    The quotes as a pipeline, in the back office (it opens in the nest, like every admin page): one column per status - asked, being written, sent, accepted, paid, declined -, each card its client, company, terms, total and how long it has waited, a click away from its form.

    2 methods

Base\Marketplace\Controller\Admin\Crud

  • AttributeSetCrudController class

    The typed sheets: for a kind of product (a taxon), its attributes in order, which are required, which the list filters on. The attributes themselves (their label in each language, their type, their unit) are omnibase's adapters.

    3 methods

  • BarcodeStandardCrudController class

    The barcode standards products can be identified with (EAN-13, UPC...): one per standard, used by the product identifiers and the feeds.

    2 methods

  • BrandCrudController class

    The brands: the estates and houses, the makers - their story, logo, place and pictures.

    3 methods

  • ChannelCrudController class

    The sales channels a product is published on (the storefront, a product feed, an export): a product appears where its channels say.

    3 methods

  • CouponCrudController class

    Coupons: a code members type in their cart. A quota caps how many orders may use it (per member too), an owner reserves it to one member, and "individual use" keeps it from mixing with anything else.

    3 methods

  • ExchangeRateCrudController class

    The exchange rates (Forex) prices and promotions are converted with: one row per currency pair, set by hand or refreshed on demand - the refresh is the only way the shop reaches a rate provider (ExchangeRates: one request for every pair, Fixer's counted against its monthly quota), and only the creators may run it.

    7 methods

  • FeatureCrudController class

    The product features shown as badges (washable, made in France...): an icon or a picture, a label and a description per language. A feature products still carry cannot be deleted.

    4 methods

  • FeeCrudController class

    Additional fees on an order (handling, small-order surcharge...): where they apply (scopes), when (rules) and how much (actions).

    3 methods

  • InvoiceCrudController class

    The shop's invoices and credit notes: read, never edited - an issued invoice does not change. Its actions: its PDF, sending it to its buyer, marking it paid, cancelling it by a credit note. An order's invoice is issued from the order (OrderCrudController's "Issue the invoice"), or by itself when the order is paid (marketplace.invoice.auto_issue).

    14 methods

  • OptionGroupCrudController class

    The options of the products: a group per choice the buyer makes (a cooking, extras, a finish) - one option or several, how many at least and at most - and its options, each with what it adds to the price.

    3 methods

  • OrderCrudController class

    Admin view of the orders: a list and a detail page. Their state moves through the shop (cart, checkout, payment), so nothing here edits them.

    10 methods

  • PaymentMethodCrudController class

    Admin CRUD for the payment methods offered at checkout. The gateway is the name() of a service tagged marketplace.payment_gateway ("manual" ships with the bundle; an application adds its own).

    6 methods

  • ProductCrudController class

    Admin CRUD for the products. Prices are integers in the currency's smallest unit (cents, or one pepette); an empty stock means unlimited.

    4 methods

  • ProductIdentifierCrudController class

    A product's codes (EAN, UPC...): what the marketplaces and feeds match it by. One identifier per product or variant, one barcode per standard.

    4 methods

  • ProductTaxonCrudController class

    The product categories of a store: base-bundle's taxonomy, with the store they belong to.

    1 method

  • PromotionCrudController class

    Promotions run by themselves between two dates, highest priority first: an event, a sale. Rules say when they hold (a minimum total...), scopes which lines they touch (a store, a product...), actions what comes off.

    3 methods

  • QuoteCrudController class

    The quotes asked from the site: price the lines (a product of the catalogue or a free line, by the lot), the terms (which way, the Incoterm and its place, the country), a discount and a date, then "Send" mails the client their link. The pipeline (QuotePipelineController) shows them by status.

    10 methods

  • RegionCrudController class

    The regions a store sells to: their countries, currency and priority (the first region covering a visitor's country wins). A disabled region is kept but no longer offered. A region orders were placed in stays.

    5 methods

  • ReviewCrudController class

    Customer reviews: the product and store they are about, their rating and pictures, and when they show (a review is a Thread: published or not).

    4 methods

  • ReviewTaxonCrudController class

    The review categories of a store: base-bundle's taxonomy, with the store they belong to.

    1 method

  • ShipmentCrudController class

    The parcels sent for an order: their tracking number, method and the items they hold. Kept once sent - a shipment is not deleted.

    5 methods

  • ShippingMethodCrudController class

    Shipping methods offered at checkout for physical goods. Rate type RATE_FLAT costs the unit price once, RATE_PRIORITY per shipping unit; the tracking URL may hold {number}.

    5 methods

  • StoreCrudController class

    Admin CRUD for the stores: a name, the currency it trades in, open or shut.

    5 methods

  • TaxRateCrudController class

    Every tax, VAT rates included: a rate, and the scopes it applies to - a region, a store, a taxon, a product. One created here is an additional tax; VAT rates are created on their own screen (VatCrudController), the ones Pricing adds to each line.

    3 methods

  • TransactionCrudController class

    The payments recorded against orders, as the gateways reported them. A record of what happened: read, never written or deleted from here.

    5 methods

  • VatCrudController class

    The VAT rates, the taxes Pricing charges on each line (Service/Pricing.php reads Vat rows only): a rate and the scopes it applies to - the buyer's region, a product, a taxon. A rate created under "Taxes" is a plain Tax, which Pricing never reads: VAT is created here.

    2 methods

Base\Marketplace\Controller\Client

  • AgeGateController class

    The age gate's answer (@Marketplace/client/_age_gate.html.twig): yes keeps the age confirmed in a cookie and goes back to the page; no leaves for the page the application names (marketplace.age_gate: its home without the restricted products, or elsewhere).

    1 method

  • AttachmentController class

    Downloading a file given with a quote request or an order line (Entity\Attachment). The files are private: the back office reads them (whoever may see the shop's screens), anybody else needs the signed link Service\Attachments::url() hands out.

    1 method

  • CartController class

    The carts and the checkout. Every change is a POST with a CSRF token; nothing needs JavaScript.

    6 methods

  • CompanyController class

    What the forms ask as a SIRET is typed: the company it names, to fill its name and show whether it trades - from the State's register (CompanyRegistry, through Omnistate), the answer kept a day.

    1 method

  • CompanySearchController class

    Omnistate's company search, GET /omnistate/company/search?q=: routed here so every shop has it without importing Omnistate's controllers (the Store form's company field asks it). Its route is the parent's.

  • CouponController class

    A coupon code entered in the cart, or taken back out.

    3 methods

  • InvoiceController class

    An invoice, as its PDF (its Factur-X XML attached): for its buyer signed in, the back office (InvoiceVoter), or whoever holds its signed link (Invoices::signedUrl(), the one its e-mail carries).

    2 methods

  • InvoiceWebhookController class

    An approved platform's callback about an invoice it carries (glitchr/omnibill, omnibill.gateways.<gateway>: a gateway that takes webhooks): its signature checked by the gateway, the invoice's lifecycle status updated. Without glitchr/omnibill there is no transmission: 404.

    2 methods

  • OrderController class

    The member's orders - carts excluded - and one order's receipt.

    3 methods

  • PaymentController class

    Where a payment provider sends people and events back, for every omnitrade gateway: the buyer's return page and the webhook both settle the same transaction, found by the provider's reference; Checkout::confirm() is idempotent, so both may arrive.

    3 methods

  • PickupController class

    Following a hand-over (Entity\Order\Pickup) through its link, without an account: the token is the key. The orders made together share it and show on the same page.

    1 method

  • QuickOrderController class

    A product bought in one step (Service\QuickOrder): the form of @Marketplace/client/_quick_order.html.twig (Form\QuickOrderType, guarded as glitchr/omnibase guards a form) posts an e-mail address here, the payment follows, and the buyer ends on the order's own page - a signed link, no account. The provider sends the buyer back to marketplace_payment_return, which expects its customer signed in: QuickOrderReturnListener hands the return of a quick order to back() here instead.

    4 methods · 1 constant

  • QuoteController class

    Business quotes on the site: the form asking for one (from a product's page, from a cart that cannot go where it should, from a trade page), the quote read through its own link (/cotation/<token>), accepted - it becomes an order waiting in the client's carts (Service\QuoteToOrder) - or declined, and the client's quotes in their account.

    8 methods

  • ShipmentController class

    The staff side of posting goods: the orders waiting to leave, each with its address, and the two steps - shipped (with the tracking number) and delivered. The member follows both on their order page.

    5 methods

  • StoreController class

    Browsing: the stores, a store's shelf, a product. Route names are marketplace_*; the paths are French, as the Chapaland site is - an application wanting others overrides the routes, not the controller.

    4 methods

  • SupplyController class

    The suppliers' side: the page a partner workshop reaches from its brief's signed link - what to make, and a form to accept, say where it stands and give the tracking -, and the webhook of the suppliers that have one.

    3 methods

Base\Marketplace\DependencyInjection

Base\Marketplace\Entity

  • Attachment class

    A file somebody gave the shop: with a quote request (a logo, a photo of the shopfront, a plan), or for an order line (the artwork of a printed item). Kept outside the public directory (marketplace.attachments.directory) under a name nobody chose; read through the back office, or through a signed link (Service\Attachments).

    13 methods

  • Brand class

    Who makes a product: a wine estate or a négociant house, a brewery, a maker. A thread - its title the name, its content the story (translated like any thread) - with a logo, where it is (country, region), a gallery, its own site, and its products (Product::$brand).

    15 methods

  • Credit class

    A line of somebody's credit ledger, of one kind ("ai": answers of an assistant, "stationery": cents of print, "hour": hours of work...): a positive quantity credits (a pack bought, a plan's allowance, a gift), a negative one spends. The balance is the sum (Service\Credits); a credit with an expiry stops counting then, what was spent before stays spent.

    14 methods

  • Entitlement class

    A right somebody holds: what a plan bought gives (its grants: limits, switches, rates), from when until when, and where it comes from (the product, the order's reference, the subscription that carries it).

    31 methods

  • Invoice class

    An invoice of the shop, or a credit note (avoir): what was sold, to whom, by whom, for how much - written once, when it is issued (Service\Invoices::issue(), ::credit()), and never again.

    33 methods · 7 constants

  • Order class

    116 methods

  • Product class

    118 methods · 1 constant

  • Quote class

    A business quote: a professional buyer asks (the quote form), the seller prices lines - a product of the catalogue or a free line, by the lot - with the terms of the trade (which way, which Incoterm, to which country and place, for when), sends it, the buyer accepts it in their account, and it becomes an order paid like any other (Service\QuoteToOrder). An export's order carries no VAT (Pricing\ExportExemption).

    33 methods

  • Review class

    22 methods

  • Store class

    30 methods

  • Usage class

    A counted grant used: one of the "events.major": 1 of a plan taken by this event, 3 of its 5 exports made. Releasing it (the event deleted) gives the unit back. What used it is named the way an Entitlement names its resource.

    11 methods

Base\Marketplace\Entity\Catalogue

  • PlatformLink class

    A product of this site and its original on a platform (an omnitrade gateway reading a catalogue: Stripe, Shopify, WooCommerce): which gateway, the product's and the variant's ids there, the stock item counted there, and a fingerprint of what was last written - a product that did not change there is not written again.

    16 methods

Base\Marketplace\Entity\Order

  • OrderItem class

    39 methods

  • Pickup class

    How an order is handed over, when it is not simply posted: collected at the shop on a slot, brought nearby by the shop (a list of postcodes), or sent - and for when, to whom, how far along the shop is. The Order keeps the lines, the prices and the payment; this keeps the rest, one row per order, and a token: /…/{token} follows it without an account.

    41 methods

  • Shipment class

    17 methods

  • Subscription class

    A plan paid by subscription: who subscribes, to which plan, through which omnitrade gateway, and the provider's own ids (the subscription, the customer its portal opens for). Its state and the end of the period paid follow the provider's events (Service\Subscriptions); the Entitlements it carries last as long as it runs.

    22 methods

  • SupplyJob class

    Part of a paid order handed to a supplier to be made and sent: the lines for one recipient at one supplier, the supplier's reference for it, where it stands and, once it left, its parcel's tracking.

    17 methods

  • Transaction class

    35 methods

Base\Marketplace\Entity\Order\Address

Base\Marketplace\Entity\Order\Method

Base\Marketplace\Entity\Product

  • Association class

    One product leading to another on its page: what goes with it (a pairing), what is bought with it (cross-sell), what is better than it (upsell), with a word on why, in each language ("Sur un comté de 24 mois").

    15 methods

  • Attribute class

    3 methods

  • AttributeSet class

    The typed sheet of a kind of product, without code: which attributes a product of this taxon has (glitchr/omnibase's attribute adapters: a text, a number with its unit, a choice, a colour...), in which order, which are required and which the list filters on.

    12 methods

  • Feature class

    7 methods

  • Identifier class

    10 methods

  • Image class

    4 methods

  • Option class

    One option of a group: "Bien cuit", "Œuf mollet (+1,50 €)". Its price is what it adds to the product's unit price, in the product's currency and like it before VAT; the product's VAT rate applies to it.

    17 methods

  • OptionGroup class

    A choice the buyer makes on a product, which is not another product: how it is cooked, what is added, how it is finished. One option of the group (a cooking) or several (extras), between a minimum and a maximum; each option may add to the price. The choices are copied onto the cart line and the order line (OrderItem::$options), their price in the line's.

    23 methods

  • Taxon class

    7 methods

  • Variant class

    22 methods

Base\Marketplace\Entity\Product\Attribute

Base\Marketplace\Entity\Product\AttributeSet

  • Field class

    One attribute of a set: the adapter (its code, its translated label, its type, from glitchr/omnibase), its unit, where it comes, whether a product must have it, whether the list filters on it and how (a choice among the values met, or a range for a number).

    20 methods · 2 constants

Base\Marketplace\Entity\Product\Attribute\Adapter

Base\Marketplace\Entity\Quote

  • AbstractQuote class

    What every quote is, whatever it sells: a client (an account, or an e-mail and a name), their company checked against the State's register, what they asked for, the seller's answer, a status, a discount, a date it holds until, a link only they have (the token).

    46 methods

  • QuoteLine class

    One line of a quote: a product of the catalogue or a free line (the transport, a label printed for the importer), a number of lots, how many units a lot holds and the price of one lot - "20 cases of 6 at 162 € the case". A line sold by the unit has lots of 1.

    20 methods

Base\Marketplace\Entity\Review

Base\Marketplace\Entity\Sales

Base\Marketplace\Entity\Sales\Attribute

Base\Marketplace\Entity\Sales\Attribute\Action

Base\Marketplace\Entity\Sales\Attribute\Rule

Base\Marketplace\Entity\Sales\Attribute\Scope

Base\Marketplace\Entity\Sales\Discount

Base\Marketplace\Entity\Sales\Referral

  • Referral class

    Somebody who came through a member's code: the referee (one referral each, for good), where it stands, the order that qualified it, and why it was refused when it was.

    15 methods

  • ReferralCode class

    A member's referral code: one each, the part of the link they share (an application route: /p/{code}).

    10 methods

  • Reward class

    What a referral gave: the referee's welcome coupon, the referrer's coupon or credits once the referee's first order held.

    11 methods · 2 constants

Base\Marketplace\Entity\Sales\Tax

  • Vat class

    2 methods

Base\Marketplace\Entity\Wishlist

  • Contribution class

    Money given to a pot or towards a shared object: the gift (`amount`), the platform's fee on it (`fee`), and what the giver is charged - the gift, plus the fee when they chose to cover it. Paid to the list's payout account as a destination charge; the provider's reference is kept to recognise its webhook.

    30 methods

  • Item class

    A wish: an object from any shop - its page's address, what an omnitrade gateway read there (title, picture, price, merchant, the day the price was read), the affiliate link when the shop has a programme -, a product of this shop, or a pot. `quantity` of an object may be reserved in all; a SHARE's price (times its quantity) is what contributions add up to; a FUND's price, when set, is a goal shown, not a ceiling.

    43 methods

  • PayoutAccount class

    Where the money given to somebody's lists goes: their connected account at the provider (a Stripe Express account), opened through Wishlist\PayoutAccounts. The contributions are paid to it directly (destination charges): the platform never holds them.

    15 methods

  • Reservation class

    Somebody promises an object of a list: it leaves the list for the others, so nothing is given twice. Held until it expires (30 days by default) - unless confirmed as bought - or cancelled with the link sent to its author (only the link's hash is kept).

    16 methods

  • Wishlist class

    A list of wishes: a wedding's or a birthday's gifts, a birth list, a fund. Its owner keeps it; it may belong to something of the application's (an event: Model\WishlistHolderInterface). Its items are objects from any shop (read through glitchr/omnitrade from their page), products of this shop, or pots; those who give reserve an object or contribute money, paid straight to the owner's payout account.

    32 methods

Base\Marketplace\Enum

  • AssociationType enum

    How one product leads to another on its page.

    3 cases

  • Barcode class

    2 methods · 14 constants

  • ContributionStatus enum

    4 cases

  • Incoterm enum

    Who pays the transport and bears the risk, and up to where (Incoterms® 2020) - the six a trade quote meets most. The quote names the place after it: "FOB Le Havre", "DAP Tokyo".

    1 method · 6 cases

  • OrderState class

    4 methods · 16 constants

  • PaymentState class

    2 methods · 8 constants

  • PickupMode enum

    How an order is handed over: collected at the shop on a slot, brought nearby by the shop itself, or sent by a carrier.

    2 methods · 3 cases

  • PickupStatus enum

    Where a hand-over stands, in the order the shop moves it along:

    3 methods · 10 cases

  • ProductAvailability class

    2 methods · 10 constants

  • ProductKind enum

    What a product is, for what happens once it is paid:

    3 cases

  • QuoteStatus enum

    A quote's life, the same for every trade (a négociant's export offer, a studio's hours):

    3 methods · 6 cases

  • ReferralStatus enum

    4 cases

  • ReservationStatus enum

    1 method · 4 cases

  • ShippingRate class

    How a shipping method prices a parcel: one flat rate, priority, or international.

    2 methods · 3 constants

  • SubscriptionStatus enum

    Where a subscription stands; the values are glitchr/omnitrade's (Model\Subscription).

    1 method · 7 cases

  • SupplyStatus enum

    Where something made to order stands at its supplier.

    1 method · 8 cases

  • TradeDirection enum

    Which way the goods of a trade quote travel, seen from the seller.

    3 cases

  • WishlistItemKind enum

    How a wish is fulfilled:

    1 method · 3 cases

  • WishlistKind enum

    What a list is for: gifts wished for (a wedding, a birthday), a birth list, or a fund alone (a honeymoon).

    3 cases

Base\Marketplace\Event

  • CatalogueNotificationEvent class

    A platform said a product or a stock level changed (its webhook, read by the omnitrade gateway): Catalogue\CatalogueNotificationListener brings it in when the catalogue is read from that gateway. The outcome is what the webhook answers.

    3 methods · 2 properties

  • ContributionPaidEvent class

    A contribution has just been paid: dispatched once. The application thanks, notes the gift, tells the owner.

    1 method · 1 property

  • ContributionPreparingEvent class

    A contribution is about to be paid: the platform's fee on it is marketplace.wishlist.fee_rate of the gift plus fee_fixed, unless a listener says otherwise ($fee, in minor units) - a rate that depends on the owner's plan, say. $metadata goes to the provider and comes back on its webhooks.

    1 method · 4 properties

  • EntitlementEndedEvent class

    A right has ended - a pass run out, a subscription stopped: dispatched once per entitlement by `marketplace:subscriptions`. The application closes what it had opened (an archive in read-only, an export offered).

    1 method · 1 property

  • EntitlementEndingEvent class

    A right ends within marketplace.plans.reminder_days: dispatched once, for the application to tell its holder.

    1 method · 1 property

  • EntitlementGrantedEvent class

    A right has just been granted - a plan paid, a gift made: the application opens what it opens.

    1 method · 2 properties

  • OrderPaidEvent class

    An order has just been paid in full. The place for an application to deliver what does not ship: unlock a download, credit an account, put an item in a wardrobe. Dispatched once, after the flush that marked it paid.

    1 method · 1 property

  • PaymentCancelledEvent class

    A payment did not happen - the member turned back on the provider's page, or the provider let it expire - and the order is back to being a cart.

    3 methods · 2 properties

  • PaymentNotificationEvent class

    A provider's webhook that is not about an order's payment nor the catalogue: a connected account updated, a subscription renewed or ended, a payment the marketplace's orders do not know (a contribution to a list, an application's own). Whoever it concerns says so (setOutcome), which ends the round.

    3 methods · 2 properties

  • PaymentPreparingEvent class

    An order is about to be handed to a glitchr/omnitrade gateway: the last moment to say how. A listener may

    2 methods · 14 properties

  • PickupChangedEvent class

    A hand-over moved (Service\Pickups::move()): received once its order is paid, accepted, ready, done... The application tells the customer, the kitchen, the driver. $previous is null when it was just opened.

    1 method · 2 properties

  • QuickOrderDoneEvent class

    The page of a quick order is about to be shown to the holder of its link (Service\QuickOrder::doneUrl()). An application that delivers something there - files to download, a ticket - sets its own response; without one, the bundle shows the order (@Marketplace/client/quick_done.html.twig).

    3 methods · 1 property

  • ReferralQualifyingEvent class

    A referee's first order is paid: before the referral qualifies, a listener may refuse it ($rejection: a reason of its own) or tell what the order was paid with ($fingerprint: the card's, as the provider gives it) so the same card as the referrer's is refused.

    1 method · 4 properties

  • ReferralRewardedEvent class

    A reward was granted (the referee's welcome, the referrer's thanks): the application tells its beneficiary.

    1 method · 1 property

  • SubscriptionChangedEvent class

    A subscription's state moved (renewed, past due, set to stop, ended), as the provider told.

    1 method · 2 properties

  • SupplyJobChangedEvent class

    A supplier's job moved (accepted, in production, shipped with its tracking, failed): the application tells the buyer.

    1 method · 2 properties

Base\Marketplace\EventListener

  • InvoiceOnPaymentListener class

    marketplace.invoice.auto_issue: an order's invoice issued as soon as it is paid. An invoice that cannot be issued (the seller not configured, a database that fails) does not undo the payment: it is said in the log, and the back office issues it.

    2 methods

  • PickupPaidListener class

    An order with a hand-over is paid: the shop has received it (saved with the confirmation's own flush).

    2 methods

  • PlanPurchaseListener class

    An order is paid: each plan in it becomes an Entitlement of its buyer (its grants, until its months run out - or, bought by subscription, as long as the Subscription created here runs), its credits are credited, and each credit pack credits its kinds, times the quantity bought.

    3 methods

  • QuickOrderReturnListener class

    A buyer back from the payment provider lands on marketplace_payment_return, which sends anyone who is not the signed-in customer to the basket. A quick order has nobody signed in: when the order is one this visitor made (its id is in their session), the request goes to QuickOrderController::Back() instead - same URL, its own ending.

    1 method

  • QuotePaidListener class

    A quote's order is paid: the quote is marked paid, the order named on it.

    2 methods

  • ReferralListener class

    An order is paid: a referee's first one qualifies their referral.

    2 methods

  • SubscriptionNotificationListener class

    A subscription's event from a provider's webhook: applied to the Subscription kept here.

    2 methods

  • SupplyListener class

    An order is paid: what in it is made to order goes to its suppliers.

    2 methods

  • WishlistNotificationListener class

    The lists' share of a provider's webhooks: a payout account updated (its holder finished the onboarding, the provider asks for more), a contribution's payment completed or expired.

    2 methods

Base\Marketplace\Form

  • AssociationType class

    One pairing, cross-sell or upsell of a product in the back office, with its note in each language of the site.

    2 methods

  • AttributeSetFieldType class

    One attribute of a set in the back office: which, required, filtered on and how, shown.

    2 methods

  • ProductOptionType class

    One option of a group in the back office: its label, what it adds to the price (cents, before VAT), preselected, available.

    2 methods

  • QuickOrderType class

    A product bought in one step (Service\QuickOrder): the buyer's e-mail address - none for a member signed in, the order is theirs - and where to come back to. Public, with no account: guarded as glitchr/omnibase guards a form (its option `guard`, action "quick_order": a trap, the time it takes, the lists, the captcha when the site has glitchr/omnishield); a form's own trap only where the host's core is from before the guard.

    3 methods · 1 constant

  • QuoteLineType class

    One line of a quote in the back office: a product or a free label, lots, units per lot, the price of a lot (cents).

    2 methods

  • QuoteRequestType class

    What a professional fills in to ask for a quote: who, which company (checked: a SIRET at the State's register, an EU VAT number at VIES), what, which way, on which terms, where, how much, for when. The trade fields are left out with `trade: false` (a studio's quote needs none).

    2 methods

Base\Marketplace\Invoice

  • FacturX class

    An invoice's Factur-X: its data as the structured XML of EN 16931 (UN/CEFACT CII, Factur-X 1.0's profile EN 16931 - "COMFORT"), and the PDF that carries it, as horstoeko/zugferd writes them (PDF/A-3, the XML attached as factur-x.xml).

    5 methods · 1 constant

  • InvoiceComposer class

    What an invoice says, written from an order the day it is issued: the seller (marketplace.invoice.seller, the store's VAT number over it), the buyer (the customer, the order's billing and delivery addresses), the lines, the totals, the mentions - copied, so that the invoice no longer depends on them.

    6 methods

  • InvoiceNumbering class

    The numbers of the invoices: a sequence without a gap per series and year - F-2026-000001, F-2026-000002... - as the law asks (a chronological and continuous sequence, CGI ann. II art. 242 nonies A; series are allowed).

    3 methods

Base\Marketplace\Invoice\Transmission

  • InvoiceStatusCommand class

    marketplace:invoice:status [<number>...]: asks the gateway the invoices went through (glitchr/omnibill) where they stand, and keeps it on them - every invoice transmitted whose status is not final (paid, refused, rejected) when none is named. For a platform without webhooks, from a cron. Registered only with glitchr/omnibill.

    1 method

  • InvoiceStatusStore class

    Where omnibill/email keeps the statuses of the invoices it sent - nobody else tells them: beside the invoices (Entity\InvoiceFlow), found by the message's reference. A status recorded before the invoice knows its reference (the e-mail being sent) is held until it does.

    1 method

  • InvoiceTransmission class

    The shop's invoices through glitchr/omnibill: an invoice sent is submitted to a gateway - omnibill/email by default, an approved platform (omnibill/afnor) the day the shop must issue through one -, and where it stands there (sent, deposited, refused, paid...) is kept beside it (Entity\InvoiceFlow).

    12 methods

  • TransmissionException class

    A gateway of glitchr/omnibill refused, did not answer, or is not set up: told to the back office as any refusal (a LogicException), its cause kept as the previous exception.

Base\Marketplace\Invoice\Transmission\Entity

  • InvoiceFlow class

    Where an invoice stands on the glitchr/omnibill gateway it went through: the gateway, its reference of the transmission, the lifecycle statuses known (sent, deposited, refused, paid...). One per invoice, beside it - the invoice itself does not change once issued.

    10 methods

Base\Marketplace\Model

  • CompanyRecord class

    A French company as the State's register knows it (API Recherche d'entreprises, fed by INSEE's Sirene and the RNE): kept with a quote or a request, as it was when checked.

    3 methods · 9 properties

  • MerchantInterface interface

    Whoever sells the thing.

    1 method

  • OptionSelection class

    The options chosen for one line, checked against the product's groups (Service\ProductOptions::select()): what they add to the unit price, how they read, and what the line keeps of them - a copy, since the product's options may change after the order.

    6 methods · 1 property

  • PlanTerms class

    What a PLAN or a CREDIT_PACK product gives once paid, kept as JSON on the product (Product::$plan), so plans are data: made and priced in the back office, never in code.

    6 methods · 6 properties · 2 constants

  • QuickPayment class

    What QuickOrder::buy() hands back: the order made, and where its payment stands.

    1 method · 2 properties

  • QuoteRequest class

    What the quote form collects. A DTO, not the Quote itself: omnibase's form factory refuses an entity as form data (a half-filled entity in the unit of work is a flush waiting to happen); the controller turns it into a Quote once it is valid.

    17 properties

  • ShippingUnitInterface interface

    1 method

  • VatCustomerInterface interface

    A customer who may buy as a business: its intra-EU VAT number, and whether VIES confirmed it (Service\VatNumbers). A confirmed number from another EU country than the store's makes an order a reverse charge (Pricing\ReverseCharge): no VAT on it, the buyer accounts for it.

    7 methods

  • VatCustomerTrait trait

    VatCustomerInterface on an app's User entity: the number, when VIES confirmed it and its consultation number.

    7 methods

  • WishlistHolderInterface interface

    What a list belongs to besides its owner: an event, a household, a project - anything of the application's. The list keeps its type and id (not a relation: the marketplace knows nothing of the application), and Repository\Wishlist\WishlistRepository::findForHolder() finds it again.

    2 methods

Base\Marketplace\Payment

  • DevGateway class

    Paid by nobody, at once: an order walked all the way through in development without a Stripe key - and in a demonstration, where no money may move. Registered only when the kernel runs in debug or in the `demo` environment (MarketplaceExtension), and supports() says no anywhere else all the same, so a method on the "dev" gateway never shows in production.

    4 methods · 1 constant

  • ManualGateway class

    Paid outside the site - a bank transfer, a cheque, cash on collection. The order waits (pending) until someone in the admin marks it paid. The instructions shown to the buyer are the method's settings:

    3 methods

  • PaymentGatewayInterface interface

    One way of taking money for an order.

    3 methods

  • PaymentGatewayRegistry class

    Every gateway of the application, by name(): its own first (manual, and whatever it wrote), then - when glitchr/omnitrade is installed - a bridge to each gateway configured under omnitrade.gateways, by that name. A PaymentMethod's gatewayFactory is one of these names.

    5 methods

  • PaymentResult class

    What a gateway's pay() came to - see PaymentGatewayInterface.

    8 methods · 4 constants

Base\Marketplace\Payment\Omnitrade

  • OmnitradeGateway class

    A payment method that names a glitchr/omnitrade gateway: the shop's PaymentMethod is a proxy, its `gatewayFactory` the name of a gateway configured under omnitrade.gateways (stripe, paypal, a Shopify shop...), and this bridge takes the order there.

    14 methods

  • OmnitradeGateways class

    The bridges to glitchr/omnitrade's configured gateways, one per name.

    5 methods · 1 constant

  • TrialGatewayFactoryInterface interface

    A glitchr/omnitrade gateway factory of the application's own whose gateways move no money and reach no provider: accounts ready at once, a payment paid on the spot by nobody, a product read from nowhere.

Base\Marketplace\Pricing

  • ExportExemption class

    Goods leaving the European Union carry no VAT: an order delivered outside it (its shipping address - a quote's order has its quote's) by a seller inside it is invoiced without, and the invoice says why - article 262 I of the French CGI for a French seller, article 146 of the VAT directive otherwise. The customs side (the export declaration, the excise document for alcohol) stays the seller's, off the site.

    3 methods · 3 constants

  • ReverseCharge class

    The buyer's side: a business from another EU country than the store's, whose VAT number VIES confirmed (Service\VatNumbers), is invoiced without VAT and accounts for it itself (article 196 of Directive 2006/112/EC). A business of the store's own country, a customer without a confirmed number, pays VAT.

    1 method · 3 constants

  • StoreVatRegime class

    The seller's side: a store whose owner does not charge VAT (Store:: chargesVat(), a small business under the franchise en base) sells without it, whoever buys. Asked before the buyer's side (a reverse charge only matters when the store charges VAT).

    1 method · 1 constant

  • VatExemptionInterface interface

    Whether an order is sold without VAT - an EU business buying from another member state (reverse charge), an export... Each service implementing it is asked once per repricing (tagged marketplace.vat_exemption, autoconfigured); the first that exempts wins.

    1 method

Base\Marketplace\Quote

  • QuoteRepositoryTrait trait

    What every quote table answers, for a ServiceEntityRepository of quotes: numbered when saved, a client's quotes, the pipeline's columns. A trait rather than a parent class: omnibase registers every class of a bundle's src/Repository as a repository service of its own, an abstract one too.

    3 methods

Base\Marketplace\Quote\Signature

  • QuoteSignatures class

    A priced quote accepted by signing it in the site's page, through glitchr/omnisign (glitchr/omnibase's Base\Service\Signatures): its PDF (@Marketplace/quote/quote.pdf.twig) sent as an envelope about the quote, the client signing where they are, the quote accepted - its order, its payment, as an acceptance without a signature - once the provider says it is completed (the way back, or its webhook: SignatureEvent::COMPLETED).

    8 methods · 1 constant

Base\Marketplace\Repository

Base\Marketplace\Repository\Catalogue

Base\Marketplace\Repository\Order

Base\Marketplace\Repository\Order\Address

Base\Marketplace\Repository\Order\Method

Base\Marketplace\Repository\Product

Base\Marketplace\Repository\Product\Attribute

Base\Marketplace\Repository\Product\Attribute\Adapter

Base\Marketplace\Repository\Review

Base\Marketplace\Repository\Sales

Base\Marketplace\Repository\Sales\Attribute

Base\Marketplace\Repository\Sales\Attribute\Action

Base\Marketplace\Repository\Sales\Attribute\Rule

Base\Marketplace\Repository\Sales\Attribute\Scope

Base\Marketplace\Repository\Sales\Discount

Base\Marketplace\Repository\Sales\Referral

Base\Marketplace\Repository\Sales\Tax

Base\Marketplace\Repository\Wishlist

Base\Marketplace\Security

  • InvoiceVoter class

    Who reads an invoice: its buyer (the customer of its order, signed in), and whoever runs the shop's back office (MarketplaceVoter::VIEW).

    1 method · 1 constant

  • MarketplaceVoter class

    Who reaches the marketplace in the back office:

    2 methods · 3 constants

Base\Marketplace\Service

  • AgeGate class

    The age a visitor must have reached to see what is sold to adults only (a wine, a sake: Product::isAgeRestricted()), and whether they said so.

    8 methods · 1 constant

  • Attachments class

    The files given with a quote request or for an order line (Entity\Attachment): stored outside the public directory under a random name, limited in number, weight and kind, served as downloads only - to the back office, or to whoever holds a signed link (url(): what a supplier is given to fetch an artwork).

    11 methods

  • AttributeFilters class

    The list's filters, built from the attributes a set marks filterable: for a choice, the values met among the products and how many have each (a wine's colour, appellation, grapes); for a range, the lowest and the highest (its alcohol, its keeping). The visitor's choice comes in the query string - ?f[colour][]=rouge&f[alcohol][min]=12 - and narrows the products, every filter at once, a value of a list among its items ("Merlot" in "Merlot, Cabernet franc").

    4 methods

  • Cart class

    The signed-in member's carts: one open Order (state CART) per store, since two stores may not share a currency, a region or a way of being paid.

    9 methods

  • CartException class

    Something the buyer should read; the message is a key in the "marketplace" domain.

    2 methods

  • Checkout class

    From a cart to an order: check it can still be bought, open a transaction, hand it to the payment method's gateway, and act on the answer.

    6 methods

  • CompanyRegistry class

    Who a French company is, from its SIREN (9 digits) or SIRET (14), through Omnistate (glitchr/omnistate): the State's free register, API Recherche d'entreprises (omnistate/annuaire-entreprises: no key; INSEE's Sirene and the RNE - the same companies as Infogreffe's, without its fee). The number is checked here first (its length, its Luhn key), then looked up; Omnistate keeps the answer (omnistate.ttl, a day by default).

    5 methods · 4 constants

  • CreditException class

    Not enough credit of that kind for what is asked.

    1 method · 3 properties

  • Credits class

    Somebody's credits of one kind (Entity\Credit): credited by a pack bought or a plan's allowance, spent one use at a time. The balance is what the grants still valid gave, less everything spent - never below zero: what an expired grant had left is lost, what was spent stays spent.

    6 methods

  • EntitlementException class

    What was asked is not granted, or none is left: the application offers an upgrade.

    1 method · 1 property

  • Entitlements class

    What somebody may do, from the rights they hold (Entity\Entitlement).

    12 methods

  • ExchangeRates class

    The exchange rates the shop converts with: the Forex table ("Taux de change" in the back office), one row per pair from the store's currency.

    9 methods · 3 constants

  • ExchangeRatesException class

    Why the exchange rates were not refreshed: no key, too soon, the provider's refusal.

  • Invoices class

    The shop's invoices: issued for a paid order (issue()), cancelled by a credit note (credit()), sent by e-mail (send()), marked paid; and their documents - the PDF (@Marketplace/invoice/invoice.pdf.twig, a site's templates/bundles/MarketplaceBundle/invoice/invoice.pdf.twig over it) carrying its Factur-X XML.

    15 methods

  • Pickups class

    Handing an order over without the post, or beside it (Entity\Order\Pickup): which ways the shop offers (marketplace.pickup.modes), where it brings things itself (zip_codes: "67000", or "67*" for all that start so), the days and the slots it gives, then the hand-over opened on an order and moved along until it is done.

    11 methods

  • Pricing class

    Prices a cart: the promotions running now, then the coupons the member entered, through the discounts' own rules, scopes and actions.

    8 methods

  • ProductOptions class

    Checks what a buyer chose among a product's options (Product\OptionGroup): each option is one of the product's and can be had, a single-choice group holds one, every group holds between its minimum and its maximum. A group left untouched takes its preselected options.

    1 method

  • QuickOrder class

    An order in one step, with no account to open and no basket to fill: products, an e-mail address, the payment.

    4 methods

  • QuoteStatusGuard class

    Small predicates on a quote's life the controllers and the voter share.

    1 method

  • QuoteToOrder class

    The client accepts a quote: it becomes an order of its own, at the quote's prices - each line a product of the catalogue (or a one-off product for a free line), its lots counted in units, the quote's discount in each price - delivered where the quote says (an export's order carries no VAT: Pricing\ExportExemption), waiting in the client's carts to be paid like any other (a transfer, a card).

    4 methods

  • ReferralException class

    A referral that cannot be: its own code, an unknown one, a member already referred. The reason is its message.

  • Referrals class

    Referrals, for any shop: each member has a code; somebody who signs up through it is their referee and gets a welcome coupon; once the referee's first order is paid and has held for the cooling-off period, the referrer is rewarded - a coupon, or credits.

    12 methods

  • RegionResolver class

    Every order belongs to a sales region (taxes, shipping and currency rules hang off it). A store that sells everywhere in one currency has no reason to configure one, so: the store's first region, else one region per currency, created the first time it is needed.

    2 methods

  • Shipping class

    Posting physical goods: whether an order needs it, the methods that can carry it and what each costs, the address it goes to, and the shipment staff record when it leaves.

    17 methods · 1 constant

  • Subscriptions class

    The subscriptions' life: what the provider tells (a renewal, a payment that failed, an end) is applied to the Subscription kept here, a subscriber stops theirs or opens the provider's portal, and `marketplace:subscriptions` announces the rights that end - a pass run out or a subscription stopped alike.

    7 methods

  • Supply class

    What is made to order, handed to who makes it. Once an order is paid, its lines whose product names a supplier are grouped by supplier and by recipient - each line may have its own (OrderItem::$recipient: a card sent to each guest), else the order's shipping address - and each group is one SupplyJob submitted to its supplier. The jobs then follow what the suppliers say (their webhook, a workshop's page, `sync()`).

    9 methods

  • VatNumbers class

    Intra-EU VAT numbers - a customer's, a store's - checked with the European Commission's VIES through Omnistate (glitchr/omnistate, omnistate/vies) when they are given, never while a page is built. A SIREN or a SIRET is enough for a French business: its VAT number is its SIREN with a key.

    3 methods · 5 constants

Base\Marketplace\Settings

  • PaymentKeysSection class

    The shop's keys on omnibase/admin's API keys page: Stripe's, when the "stripe" gateway of glitchr/omnitrade is there. Typed there, they win over the configuration (api.payment_method.<gateway>.<option>, read by Payment\Omnitrade\OmnitradeGateways) - the applications no longer list them in a SystemController of their own.

    3 methods

Base\Marketplace\Supply

  • GelatoSupplier class

    Gelato, print on demand: cards, mugs, tote bags, textile, photo books, made near their recipient. Its Order API v4 (https://order.gelatoapis.com, the key in X-API-KEY): an order has one shipping address, items naming a productUid and the files to print (public addresses Gelato fetches), and is sent launched ("order") or as a "draft" confirmed later.

    12 methods · 3 constants

  • OfflineSupplier class

    A supplier without an API: the shop's partner workshop, a local printer.

    11 methods

  • SupplierInterface interface

    Somebody who makes what the shop sells and sends it to the buyer - a print-on-demand service, a local workshop. A Product names its supplier (Product::$supplier) and its reference there; once an order is paid, Service\Supply hands its lines to their suppliers.

    9 methods

  • SupplierRegistry class

    The suppliers, by name: the bundle's (gelato, offline) and the application's.

    4 methods

  • SupplyException class

    A supplier refused, did not answer, or does not do what was asked.

    1 method · 1 property

Base\Marketplace\Supply\Model

  • SupplyLine class

    One thing to make: the supplier's own product (a Gelato productUid, a partner's reference), how many, and the files it is printed from - one per printable side, as public addresses the supplier fetches.

    1 method · 6 properties

  • SupplyOrder class

    What a supplier is asked: lines, for one recipient.

    1 method · 7 properties

  • SupplyProduct class

    Something a supplier makes: its reference there (what a Product's supplierReference holds) and its name.

    1 method · 3 properties

  • SupplyQuote class

    What a supply order would cost the shop, in minor units: the making, the posting.

    2 methods · 7 properties

  • SupplyRecipient class

    Who receives what is made: one address per supply order (a batch for the buyer, or each guest's own).

    7 methods · 9 properties

  • SupplyResult class

    Where a supply order stands, as its supplier says: its reference there, its state, its parcel.

    1 method · 9 properties

Base\Marketplace\Twig

  • CatalogueTwigExtension class

    The catalogue's pages from any template:

    5 methods

  • InvoiceTwigExtension class

    What an invoice's page prints its amounts with: an integer in the currency's smallest unit, written as the seller's language writes money.

    6 methods

  • MarketplaceTwigExtension class

    What the shop's pages need from any template: the number of lines waiting in the visitor's carts, for the badge next to the cart link; and prices as a buyer is shown them, VAT included (prices are stored before VAT).

    3 methods

  • QuickOrderTwigExtension class

    The quick order's form (Form\QuickOrderType), for a product, wherever a template shows one: {% set form = marketplace_quick_order_form(product) %} {% set form = marketplace_quick_order_form(product, '/carte') %} where a refusal brings the buyer back @Marketplace/client/_quick_order.html.twig prints it.

    4 methods

  • ShippingTwigExtension class

    `marketplace_tracking_url(method, number)`: where a parcel can be followed.

    1 method

Base\Marketplace\Validator

  • CompanyNumber class

    A SIREN or SIRET that exists: well formed, and known to the State's register (Service\CompanyRegistry). A register that does not answer lets it through - the request is then marked unchecked, not refused.

    2 properties

  • CompanyNumberValidator class

    2 methods

  • VatNumber class

    An intra-EU VAT number VIES knows (Service\VatNumbers): well formed - a French one with its key - and valid at the European Commission. VIES that does not answer lets a well-formed number through rather than refuse it.

    2 properties

  • VatNumberValidator class

    2 methods

Base\Marketplace\Wishlist

  • Contributions class

    Money given to a list. The giver pays on the provider's page; the payment is a destination charge to the owner's payout account (Stripe Connect), the platform keeping its fee: the gift is never the platform's money, and so is no order of its shop.

    7 methods

  • PayoutAccounts class

    The connected accounts contributions are paid to: one per owner, opened at the provider named by marketplace.wishlist.payout_gateway (an Express account at Stripe), completed by its holder on the provider's own page, kept up to date from its webhook (account.updated) or on demand.

    7 methods

  • ProductLookup class

    An address pasted into a list, read: the omnitrade gateways named in marketplace.wishlist.lookup are asked in order (amazon before web: the shop's own API before its page's markup), the first that knows the product answers. The affiliate link is asked the same way - a gateway may write it without being able to read the product (Amazon with its tag alone).

    3 methods

  • Reservations class

    An object promised leaves the list for the others. The item's row is locked while what is left is counted - from the database, not from memory -, so two givers cannot both take the last one. A reservation is cancelled with the token handed to its author (only its hash is kept), and lapses after marketplace.wishlist.reservation_days unless confirmed.

    6 methods

  • WishlistException class

    Something a giver or an owner asked cannot be done; the message is a key of the marketplace translations (wishlist.error.*).

    1 method · 1 property

  • Wishlists class

    Lists and their wishes: made, filled from a pasted address (read through glitchr/omnitrade when it is installed), from this shop's catalogue or by hand, and their prices read again when they are old.

    7 methods

App\Controller

DemoController class

class DemoController extends AbstractController DemoController.php:29

The demonstrator's one page: it seeds a small shop, signs a visitor in, fills a cart and pays two orders - then hands over to the shop itself.

Everything here is demo scaffolding. A real application seeds stores from a fixture or the admin, and members shop through the bundle's pages; nothing in this file is a pattern to copy.

DemoController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Security $security, readonly Cart $cart, readonly Checkout $checkout, readonly PaymentGatewayRegistry $gateways, EventDispatcherInterface $dispatcher)

DemoController::index()

public function index(): Response

App\Entity

User class

class User extends User User.php:15

The demo's member. base-bundle's User identifies people by email and has no username; the forum and the mailbox address members by username (an @mention, a recipient typed by hand), so the application's User carries one - as every base-bundle application's User does.

User::getUsername()

public function getUsername(): ?string

User::setUsername()

public function setUsername(string $username): self

User::__toString()

public function __toString(): string

App\Payment

DemoGateway class

final class DemoGateway implements PaymentGatewayInterface DemoGateway.php:16

An application's own gateway, as small as one gets: it accepts every order at once. A real one would call its payment service and answer paid(), pending(), redirect($url) or refused('reason.key').

DemoGateway::name()

public static function name(): string

DemoGateway::supports()

public function supports(Order $order, PaymentMethod $method): bool

DemoGateway::pay()

public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResult

App\Repository

UserRepository class

class UserRepository extends UserRepository UserRepository.php:5

Base\Marketplace

MarketplaceBundle class

class MarketplaceBundle extends AbstractBaseBundle MarketplaceBundle.php:9

MarketplaceBundle::__construct()

public function __construct()

MarketplaceBundle::getPath()

public function getPath(): string

Modern bundle layout: the class lives in src/, the bundle root is the package root - so TwigBundle picks up ./templates as @Marketplace.

MarketplaceBundle::build()

public function build(ContainerBuilder $container): void

Base\Marketplace\Attribute

OrderReference class

class OrderReference extends AbstractAttribute OrderReference.php:23

A human order reference, generated once on the first flush:

#[OrderReference(format: 'CCC-XXXX-YYY')]

C the buyer's country (from their cookie), as digits X random digits Y the date, down to the minute

Found by base-bundle's AttributeReader because MarketplaceExtension adds this directory to base.attributes.paths.

OrderReference::__construct()

public function __construct(protected string $format = 'CCC-XXXX-YYY')

OrderReference::supports()

public function supports(string $target, ?string $targetValue = null, $object = null): bool

OrderReference::generate()

public function generate(): string

OrderReference::unique()

public function unique(OnFlushEventArgs $event, mixed $entity, string $property): string

A reference no other order holds, neither stored nor flushed with this one. The format leaves only its X digits to chance within a second (the country and the date are the same for every order of that second): two orders made in the same second drew the same reference once in 9 000 pairs, and the column being unique, the second flush failed. Seen in the suite (SupplyTest, which makes orders a few milliseconds apart), and as likely for two buyers paying in the same second.

OrderReference::onFlush()

public function onFlush(OnFlushEventArgs $event, ClassMetadata $classMetadata, mixed $entity, ?string $property = null)

Base\Marketplace\Catalogue

CatalogueNotificationListener class

final class CatalogueNotificationListener CatalogueNotificationListener.php:16

A platform's product or stock webhook (through PaymentController's /marketplace/{gateway}/webhook, checked by the omnitrade gateway): the product brought in again, taken off sale when deleted, its stock counted - when the catalogue is read from that gateway (marketplace.catalogue.source).

CatalogueNotificationListener::__construct()

public function __construct(readonly PlatformSynchronizer $synchronizer, readonly ?string $source = null)

CatalogueNotificationListener::__invoke()

public function __invoke(CatalogueNotificationEvent $event): void

InventorySynchronizer class

class InventorySynchronizer InventorySynchronizer.php:15

The stock levels alone, more often than the whole catalogue: every linked variant's count read from the platform (FetchInventory) and written here.

A platform that counts nothing (Stripe) is left alone: the stock stays the site's.

InventorySynchronizer::__construct()

public function __construct(readonly PlatformSynchronizer $products, readonly PlatformLinkRepository $links, readonly bool $enabled = true)

InventorySynchronizer::reads()

public function reads(string $gatewayName): bool

Whether this gateway's stock is read at all.

InventorySynchronizer::sync()

public function sync(string $gatewayName, bool $dryRun = false): int
Returns

how many products got a new count

PlatformSynchronizer class

class PlatformSynchronizer PlatformSynchronizer.php:49

The catalogue kept on a platform, copied here: every product an omnitrade gateway reads (Stripe's Products, a Shopify shop, a WooCommerce site) becomes a Product of the store - its variants Variants -, its vendor a Brand, its key/value attributes the attributes of the same code, its tags Features, its SKU and barcode identifiers. Payment stays wherever the shop pays (omnitrade/stripe), whatever the source of the catalogue.

One way only, the platform to the site, and gently:

1. only the fields of marketplace.catalogue.owned_fields are written: the taxa, the pairings, the age gate, the lots, an image chosen here - never listed, never touched; 2. a variant whose owned fields hash the same as last time is not written at all (no updatedAt bump, no cache invalidated); 3. nothing is deleted: a product gone from the platform (or no longer active) is taken off sale (DISCONTINUED, no stock), its order history intact, its link kept as orphaned.

A first import finds what the shop already sells by SKU and links it rather than making a duplicate.

const UNMANAGED_TAG = 'platform-unmanaged'

A product carrying this feature (a tag) is never written by the sync.

PlatformSynchronizer::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PlatformLinkRepository $links, readonly ?Registry $registry = null, readonly ?string $storeSlug = null, readonly array $ownedFields = [], readonly string $defaultCurrency = 'EUR', readonly string $environment = 'prod')

PlatformSynchronizer::stats()

public function stats(): array

PlatformSynchronizer::resetStats()

public function resetStats(): void

PlatformSynchronizer::gateway()

public function gateway(string $name): GatewayInterface
Throws

LogicException without glitchr/omnitrade, and in a demonstration (glitchr/omnibase's demo environment): its catalogue is its fixtures', no platform is read there

PlatformSynchronizer::sync()

public function sync(string $gatewayName, ?\DateTimeInterface $since = null, bool $full = false, bool $dryRun = false, ?callable $progress = null, ?string $query = null): array

Every product of the platform, page by page - only what changed since $since when given. With $full, what the platform no longer has is taken off sale here.

$progress

told of each product and what became of it

Returns

the counters

PlatformSynchronizer::synchronize()

public function synchronize(string $gatewayName, RemoteProduct $remote, bool $dryRun = false): string

One platform product into the catalogue: its first variant is the Product, the others its Variants.

Returns

created, updated, unchanged, skipped or discontinued (the first variant's)

PlatformSynchronizer::discontinue()

public function discontinue(string $gatewayName, string $remoteProduct, bool $dryRun = false): int

The product is gone from the platform: taken off sale, never deleted.

PlatformSynchronizer::updateStock()

public function updateStock(string $gatewayName, Stock $stock): bool

A stock level the platform counted: by the variant's id there, or its counted item's.

PlatformSynchronizer::flush()

public function flush(): void

PlatformSynchronizer::fingerprint()

public function fingerprint(RemoteProduct $remote, RemoteVariant $variant): string

What a variant's owned fields hash to: the same as last time, nothing is written.

Base\Marketplace\Console

CatalogueSyncCommand class

class CatalogueSyncCommand extends Command CatalogueSyncCommand.php:25

marketplace:catalogue:sync [gateway]: the catalogue of a platform read in (marketplace.catalogue.source when no gateway is named). Incremental by default - what changed there since the last change read -, --full reads everything and takes off sale what the platform no longer has, --inventory reads the stock levels only. Run it from the cron container.

CatalogueSyncCommand::__construct()

public function __construct(readonly PlatformSynchronizer $products, readonly InventorySynchronizer $inventory, readonly PlatformLinkRepository $links, readonly ?string $source = null)

InvoiceIssueCommand class

class InvoiceIssueCommand extends Command InvoiceIssueCommand.php:21

marketplace:invoice:issue <order>...: the invoices of paid orders, by their reference - what the back office's "Issue the invoice" does, for a script or a catch-up. An order that has its invoice is said and skipped.

--paid-without-invoice issues every paid order's that has none.

InvoiceIssueCommand::__construct()

public function __construct(readonly Invoices $invoices, readonly EntityManagerInterface $entityManager)

ReferralsCommand class

class ReferralsCommand extends Command ReferralsCommand.php:13

marketplace:referrals: every night from the cron container - the referrers whose referee's order held are rewarded.

ReferralsCommand::__construct()

public function __construct(readonly Referrals $referrals)

StripeWebhookCommand class

final class StripeWebhookCommand extends Command StripeWebhookCommand.php:47

Makes sure Stripe knows where to send the marketplace's events: for every payment method on an omnitrade gateway whose provider is Stripe, the webhook endpoint on marketplace_payment_webhook, listening to the Checkout events PaymentController handles. Safe to run again and again - on every deploy, from the container's entrypoint:

  • no API key yet, or an address Stripe cannot reach (localhost: use stripe listen there): nothing to do, said so, success;
  • the endpoint exists: its events are completed if some are missing;
  • it does not: it is created, and the signing secret Stripe returns - ONLY at creation - is stored in the back office's setting api.payment_method.<gateway>.webhook_secret, which the omnitrade gateway runs on from then on: every event's signature is checked against it. No secret to copy.

The API key: the one the omnitrade gateway runs on - typed in the back office (api.payment_method.<gateway>.api_key) or configured (omnitrade.gateways.<gateway>.options.api_key, STRIPE_API_KEY). The address: --url, else the method's webhook_url setting, else the route's absolute URL under the router's default URI.

An endpoint that exists but whose secret is known nowhere (created by hand, or the settings lost) cannot be read back from the API: reveal it in the Dashboard into webhook_secret, or run with --recreate for a new one.

const EVENTS = ['checkout.session.completed', 'checkout.session.async_payment_succeeded', 'checkout.session.expired', 'checkout.session.async_payment_failed']

StripeWebhookCommand::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly UrlGeneratorInterface $urls, readonly HttpClientInterface $http, readonly SettingBagInterface $settings, readonly PaymentGatewayRegistry $gateways)

SubscriptionsCommand class

class SubscriptionsCommand extends Command SubscriptionsCommand.php:21

marketplace:subscriptions: every night from the cron container. Announces the rights that ended (EntitlementEndedEvent) and those about to (EntitlementEndingEvent), once each; --sync first asks the providers where each running subscription stands, for the events a webhook missed.

SubscriptionsCommand::__construct()

public function __construct(readonly Subscriptions $subscriptions, readonly EntityManagerInterface $entityManager)

WishlistRefreshCommand class

class WishlistRefreshCommand extends Command WishlistRefreshCommand.php:19

marketplace:wishlist:refresh-prices: every night from the cron container.

Reads again the prices of the open lists' objects that are older than marketplace.wishlist.price_ttl, and lets the lapsed reservations go.

WishlistRefreshCommand::__construct()

public function __construct(readonly Wishlists $wishlists, readonly Reservations $reservations)

Base\Marketplace\Controller\Admin

AbstractMarketplaceCrudController class

abstract class AbstractMarketplaceCrudController extends AbstractCrudController AbstractMarketplaceCrudController.php:17

Every marketplace screen of the back office: products, stores, orders, taxes, exchange rates... For the creators (marketplace.admin_role, by default ROLE_SUPERADMIN; ROLE_EDITOR inherits it), and for a shop's owners to read (MarketplaceVoter): an application's other staff keep their own screens (a kitchen, a till) without the catalogue, the prices or the money.

The admin bundle checks this permission on every action of the CRUD and hides the menu entries and dashboard cards that lead to it.

MarketplaceAdminTrait trait

trait MarketplaceAdminTrait MarketplaceAdminTrait.php:20

The marketplace screens' permissions (MarketplaceVoter), for every marketplace CRUD - used by AbstractMarketplaceCrudController, and directly by a CRUD controller that already extends another admin base (taxons, adapters):

reading MARKETPLACE_VIEW: the creators, and the shops' owners; changing the creators (the admin's default for new, edit, delete) - or, on a screen of VAT and prices (isPricing()), the shops' owners too: MARKETPLACE_PRICING.

MarketplaceAdminTrait::configureCrud()

public function configureCrud(Crud $crud): Crud

MarketplaceAdminTrait::configureActions()

public function configureActions(Actions $actions): Actions

QuotePipelineController class

class QuotePipelineController extends AbstractController QuotePipelineController.php:23

The quotes as a pipeline, in the back office (it opens in the nest, like every admin page): one column per status - asked, being written, sent, accepted, paid, declined -, each card its client, company, terms, total and how long it has waited, a click away from its form.

QuotePipelineController::__construct()

public function __construct(readonly QuoteRepository $quotes, readonly AdminContext $adminContext, readonly MenuBuilder $menuBuilder, readonly AdminUrlGenerator $adminUrlGenerator)

QuotePipelineController::index()

public function index(): Response

Base\Marketplace\Controller\Admin\Crud

AttributeSetCrudController class

class AttributeSetCrudController extends AbstractMarketplaceCrudController AttributeSetCrudController.php:20

The typed sheets: for a kind of product (a taxon), its attributes in order, which are required, which the list filters on. The attributes themselves (their label in each language, their type, their unit) are omnibase's adapters.

AttributeSetCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

AttributeSetCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

AttributeSetCrudController::configureFields()

public function configureFields(string $pageName): iterable

BarcodeStandardCrudController class

class BarcodeStandardCrudController extends AdapterCrudController BarcodeStandardCrudController.php:14

The barcode standards products can be identified with (EAN-13, UPC...): one per standard, used by the product identifiers and the feeds.

BarcodeStandardCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

BarcodeStandardCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

BrandCrudController class

class BrandCrudController extends AbstractMarketplaceCrudController BrandCrudController.php:17

The brands: the estates and houses, the makers - their story, logo, place and pictures.

BrandCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

BrandCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

BrandCrudController::configureFields()

public function configureFields(string $pageName): iterable

ChannelCrudController class

class ChannelCrudController extends AbstractMarketplaceCrudController ChannelCrudController.php:19

The sales channels a product is published on (the storefront, a product feed, an export): a product appears where its channels say.

ChannelCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ChannelCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ChannelCrudController::configureFields()

public function configureFields(string $pageName): iterable

CouponCrudController class

class CouponCrudController extends AbstractMarketplaceCrudController CouponCrudController.php:23

Coupons: a code members type in their cart. A quota caps how many orders may use it (per member too), an owner reserves it to one member, and "individual use" keeps it from mixing with anything else.

CouponCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

CouponCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

CouponCrudController::configureFields()

public function configureFields(string $pageName): iterable

ExchangeRateCrudController class

class ExchangeRateCrudController extends AbstractMarketplaceCrudController ExchangeRateCrudController.php:28

The exchange rates (Forex) prices and promotions are converted with: one row per currency pair, set by hand or refreshed on demand - the refresh is the only way the shop reaches a rate provider (ExchangeRates: one request for every pair, Fixer's counted against its monthly quota), and only the creators may run it.

ExchangeRateCrudController::__construct()

public function __construct(readonly ExchangeRates $rates)

ExchangeRateCrudController::configureActions()

public function configureActions(Actions $actions): Actions

ExchangeRateCrudController::refreshRates()

public function refreshRates(): Response

One request for every pair; at most once an hour (ExchangeRates::MIN_INTERVAL).

ExchangeRateCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ExchangeRateCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ExchangeRateCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

ExchangeRateCrudController::configureFields()

public function configureFields(string $pageName): iterable

FeatureCrudController class

class FeatureCrudController extends AbstractMarketplaceCrudController FeatureCrudController.php:21

The product features shown as badges (washable, made in France...): an icon or a picture, a label and a description per language. A feature products still carry cannot be deleted.

FeatureCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

FeatureCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

FeatureCrudController::isDeletable()

public function isDeletable(object $entity): bool

FeatureCrudController::configureFields()

public function configureFields(string $pageName): iterable

FeeCrudController class

class FeeCrudController extends AbstractMarketplaceCrudController FeeCrudController.php:18

Additional fees on an order (handling, small-order surcharge...): where they apply (scopes), when (rules) and how much (actions).

FeeCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

FeeCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

FeeCrudController::configureFields()

public function configureFields(string $pageName): iterable

InvoiceCrudController class

class InvoiceCrudController extends AbstractMarketplaceCrudController InvoiceCrudController.php:31

The shop's invoices and credit notes: read, never edited - an issued invoice does not change. Its actions: its PDF, sending it to its buyer, marking it paid, cancelling it by a credit note. An order's invoice is issued from the order (OrderCrudController's "Issue the invoice"), or by itself when the order is paid (marketplace.invoice.auto_issue).

With glitchr/omnibill, sending goes through its gateway: the screen shows where the invoice stands there (its lifecycle status), and asks again.

InvoiceCrudController::setInvoiceServices()

public function setInvoiceServices(Invoices $invoices, TranslatorInterface $translator): void

InvoiceCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

InvoiceCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

InvoiceCrudController::isDeletable()

public function isDeletable(object $entity): bool

InvoiceCrudController::configureCrud()

public function configureCrud(Crud $crud): Crud

InvoiceCrudController::configureActions()

public function configureActions(Actions $actions): Actions

InvoiceCrudController::new()

public function new(Request $request): Response

InvoiceCrudController::edit()

public function edit(Request $request, string $entityId): Response

InvoiceCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

InvoiceCrudController::configureFields()

public function configureFields(string $pageName): iterable

InvoiceCrudController::send()

public function send(string $entityId): Response

InvoiceCrudController::refresh()

public function refresh(string $entityId): Response

InvoiceCrudController::markPaid()

public function markPaid(string $entityId): Response

InvoiceCrudController::credit()

public function credit(string $entityId): Response

OptionGroupCrudController class

class OptionGroupCrudController extends AbstractMarketplaceCrudController OptionGroupCrudController.php:21

The options of the products: a group per choice the buyer makes (a cooking, extras, a finish) - one option or several, how many at least and at most - and its options, each with what it adds to the price.

OptionGroupCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

OptionGroupCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

OptionGroupCrudController::configureFields()

public function configureFields(string $pageName): iterable

OrderCrudController class

class OrderCrudController extends AbstractMarketplaceCrudController OrderCrudController.php:28

Admin view of the orders: a list and a detail page. Their state moves through the shop (cart, checkout, payment), so nothing here edits them.

OrderCrudController::setInvoiceServices()

public function setInvoiceServices(Invoices $invoices, TranslatorInterface $translator): void

OrderCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

OrderCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

OrderCrudController::configureActions()

public function configureActions(Actions $actions): Actions

Orders are born at checkout and move through it: the admin reads them.

Shipping, refunds and the like belong in dedicated actions, not in a form over the order's columns.

OrderCrudController::issueInvoice()

public function issueInvoice(string $entityId): Response

OrderCrudController::new()

public function new(Request $request): Response

A disabled action only loses its button in base-bundle-admin; the route itself still answers. Close both here.

OrderCrudController::edit()

public function edit(Request $request, string $entityId): Response

OrderCrudController::configureRecordNote()

public function configureRecordNote(object $entity): ?string

OrderCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

OrderCrudController::configureFields()

public function configureFields(string $pageName): iterable

PaymentMethodCrudController class

class PaymentMethodCrudController extends AbstractMarketplaceCrudController PaymentMethodCrudController.php:22

Admin CRUD for the payment methods offered at checkout. The gateway is the name() of a service tagged marketplace.payment_gateway ("manual" ships with the bundle; an application adds its own).

PaymentMethodCrudController::__construct()

public function __construct(readonly PaymentGatewayRegistry $gateways)

PaymentMethodCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

PaymentMethodCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

PaymentMethodCrudController::isDeletable()

public function isDeletable(object $entity): bool

A method orders were paid with stays: they point to it.

PaymentMethodCrudController::configureRecordNote()

public function configureRecordNote(object $entity): ?string

Whether its gateway is installed, and how many of its settings are filled (marketplace.gateways.<slug>).

PaymentMethodCrudController::configureFields()

public function configureFields(string $pageName): iterable

ProductCrudController class

class ProductCrudController extends AbstractMarketplaceCrudController ProductCrudController.php:23

Admin CRUD for the products. Prices are integers in the currency's smallest unit (cents, or one pepette); an empty stock means unlimited.

ProductCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ProductCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ProductCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

ProductCrudController::configureFields()

public function configureFields(string $pageName): iterable

ProductIdentifierCrudController class

class ProductIdentifierCrudController extends AbstractMarketplaceCrudController ProductIdentifierCrudController.php:18

A product's codes (EAN, UPC...): what the marketplaces and feeds match it by. One identifier per product or variant, one barcode per standard.

ProductIdentifierCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ProductIdentifierCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ProductIdentifierCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

ProductIdentifierCrudController::configureFields()

public function configureFields(string $pageName): iterable

ProductTaxonCrudController class

class ProductTaxonCrudController extends TaxonCrudController ProductTaxonCrudController.php:12

The product categories of a store: base-bundle's taxonomy, with the store they belong to.

ProductTaxonCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

PromotionCrudController class

class PromotionCrudController extends AbstractMarketplaceCrudController PromotionCrudController.php:21

Promotions run by themselves between two dates, highest priority first: an event, a sale. Rules say when they hold (a minimum total...), scopes which lines they touch (a store, a product...), actions what comes off.

PromotionCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

PromotionCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

PromotionCrudController::configureFields()

public function configureFields(string $pageName): iterable

QuoteCrudController class

class QuoteCrudController extends AbstractMarketplaceCrudController QuoteCrudController.php:43

The quotes asked from the site: price the lines (a product of the catalogue or a free line, by the lot), the terms (which way, the Incoterm and its place, the country), a discount and a date, then "Send" mails the client their link. The pipeline (QuotePipelineController) shows them by status.

QuoteCrudController::setQuoteSignatures()

public function setQuoteSignatures(?\Base\Marketplace\Quote\Signature\QuoteSignatures $signatures = null): void

The quotes signed in the page: with glitchr/omnisign only (the service does not exist without it).

QuoteCrudController::setQuoteServices()

public function setQuoteServices(MailerInterface $mailer, TranslatorInterface $translator, int $validity = 30): void

QuoteCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

QuoteCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

QuoteCrudController::configureCrud()

public function configureCrud(Crud $crud): Crud

QuoteCrudController::configureActions()

public function configureActions(Actions $actions): Actions

QuoteCrudController::configureFields()

public function configureFields(string $pageName): iterable

QuoteCrudController::createEntity()

public function createEntity(string $entityFqcn): object

QuoteCrudController::persistEntity()

public function persistEntity(EntityManagerInterface $entityManager, object $entity): void

Numbered when saved, not when the form opens: two forms open took the same number.

QuoteCrudController::send()

public function send(string $entityId): Response

Sent: the client gets their link by mail, and may accept it until its date.

RegionCrudController class

class RegionCrudController extends AbstractMarketplaceCrudController RegionCrudController.php:23

The regions a store sells to: their countries, currency and priority (the first region covering a visitor's country wins). A disabled region is kept but no longer offered. A region orders were placed in stays.

RegionCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

RegionCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

RegionCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

RegionCrudController::isDeletable()

public function isDeletable(object $entity): bool

RegionCrudController::configureFields()

public function configureFields(string $pageName): iterable

ReviewCrudController class

class ReviewCrudController extends AbstractMarketplaceCrudController ReviewCrudController.php:24

Customer reviews: the product and store they are about, their rating and pictures, and when they show (a review is a Thread: published or not).

ReviewCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ReviewCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ReviewCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

ReviewCrudController::configureFields()

public function configureFields(string $pageName): iterable

ReviewTaxonCrudController class

class ReviewTaxonCrudController extends TaxonCrudController ReviewTaxonCrudController.php:12

The review categories of a store: base-bundle's taxonomy, with the store they belong to.

ReviewTaxonCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ShipmentCrudController class

class ShipmentCrudController extends AbstractMarketplaceCrudController ShipmentCrudController.php:20

The parcels sent for an order: their tracking number, method and the items they hold. Kept once sent - a shipment is not deleted.

ShipmentCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ShipmentCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ShipmentCrudController::isDeletable()

public function isDeletable(object $entity): bool

ShipmentCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

ShipmentCrudController::configureFields()

public function configureFields(string $pageName): iterable

ShippingMethodCrudController class

class ShippingMethodCrudController extends AbstractMarketplaceCrudController ShippingMethodCrudController.php:22

Shipping methods offered at checkout for physical goods. Rate type RATE_FLAT costs the unit price once, RATE_PRIORITY per shipping unit; the tracking URL may hold {number}.

ShippingMethodCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

ShippingMethodCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

ShippingMethodCrudController::isDeletable()

public function isDeletable(object $entity): bool

A method orders were shipped with stays: they point to it.

ShippingMethodCrudController::configureRecordNote()

public function configureRecordNote(object $entity): ?string

The carrier behind it and how many of its settings are filled (omnibus.<slug>).

ShippingMethodCrudController::configureFields()

public function configureFields(string $pageName): iterable

StoreCrudController class

class StoreCrudController extends AbstractMarketplaceCrudController StoreCrudController.php:21

Admin CRUD for the stores: a name, the currency it trades in, open or shut.

StoreCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

StoreCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

StoreCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

StoreCrudController::isDeletable()

public function isDeletable(object $entity): bool

A store orders were placed in stays: they point to it.

StoreCrudController::configureFields()

public function configureFields(string $pageName): iterable

TaxRateCrudController class

class TaxRateCrudController extends AbstractMarketplaceCrudController TaxRateCrudController.php:19

Every tax, VAT rates included: a rate, and the scopes it applies to - a region, a store, a taxon, a product. One created here is an additional tax; VAT rates are created on their own screen (VatCrudController), the ones Pricing adds to each line.

TaxRateCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

TaxRateCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

TaxRateCrudController::configureFields()

public function configureFields(string $pageName): iterable

TransactionCrudController class

class TransactionCrudController extends AbstractMarketplaceCrudController TransactionCrudController.php:20

The payments recorded against orders, as the gateways reported them. A record of what happened: read, never written or deleted from here.

TransactionCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

TransactionCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

TransactionCrudController::configureActions()

public function configureActions(Actions $actions): Actions

TransactionCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

TransactionCrudController::configureFields()

public function configureFields(string $pageName): iterable

VatCrudController class

class VatCrudController extends TaxRateCrudController VatCrudController.php:13

The VAT rates, the taxes Pricing charges on each line (Service/Pricing.php reads Vat rows only): a rate and the scopes it applies to - the buyer's region, a product, a taxon. A rate created under "Taxes" is a plain Tax, which Pricing never reads: VAT is created here.

VatCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

VatCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

Base\Marketplace\Controller\Client

AgeGateController class

class AgeGateController extends AbstractController AgeGateController.php:17

The age gate's answer (@Marketplace/client/_age_gate.html.twig): yes keeps the age confirmed in a cookie and goes back to the page; no leaves for the page the application names (marketplace.age_gate: its home without the restricted products, or elsewhere).

AgeGateController::Answer()

public function Answer(Request $request, AgeGate $gate): RedirectResponse

AttachmentController class

class AttachmentController extends AbstractController AttachmentController.php:21

Downloading a file given with a quote request or an order line (Entity\Attachment). The files are private: the back office reads them (whoever may see the shop's screens), anybody else needs the signed link Service\Attachments::url() hands out.

AttachmentController::Download()

public function Download(Request $request, int $id, EntityManagerInterface $entityManager, Attachments $attachments, UriSigner $signer): Response

CartController class

class CartController extends AbstractController CartController.php:24

The carts and the checkout. Every change is a POST with a CSRF token; nothing needs JavaScript.

CartController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Cart $cart, readonly Checkout $checkout, readonly TranslatorInterface $translator)

CartController::Index()

public function Index(Pricing $pricing): Response

CartController::Add()

public function Add(Request $request, int $id): Response

CartController::Update()

public function Update(Request $request, int $order, int $item): Response

CartController::Checkout()

public function Checkout(Request $request, int $order, Pricing $pricing, Shipping $shipping): Response

CartController::Files()

public function Files(Request $request, int $order, int $item, \Base\Marketplace\Service\Attachments $attachments): Response

The buyer's files for a line of their cart - the artwork of a printed item (Service\Attachments).

CompanyController class

class CompanyController extends AbstractController CompanyController.php:15

What the forms ask as a SIRET is typed: the company it names, to fill its name and show whether it trades - from the State's register (CompanyRegistry, through Omnistate), the answer kept a day.

CompanyController::lookup()

public function lookup(string $number, CompanyRegistry $registry): JsonResponse

CompanySearchController class

final class CompanySearchController extends CompanySearchController CompanySearchController.php:17

Omnistate's company search, GET /omnistate/company/search?q=: routed here so every shop has it without importing Omnistate's controllers (the Store form's company field asks it). Its route is the parent's.

For the back office only (MARKETPLACE_VIEW: creators and store owners): open, any visitor could search the State's register through the shop and spend its rate limit (about seven calls a second, per server).

CouponController class

class CouponController extends AbstractController CouponController.php:19

A coupon code entered in the cart, or taken back out.

CouponController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Cart $cart, readonly Pricing $pricing, readonly TranslatorInterface $translator)

CouponController::Apply()

public function Apply(Request $request, int $order): Response

CouponController::Remove()

public function Remove(Request $request, int $order, int $coupon): Response

InvoiceController class

class InvoiceController extends AbstractController InvoiceController.php:20

An invoice, as its PDF (its Factur-X XML attached): for its buyer signed in, the back office (InvoiceVoter), or whoever holds its signed link (Invoices::signedUrl(), the one its e-mail carries).

InvoiceController::__construct()

public function __construct(readonly Invoices $invoices)

InvoiceController::Download()

public function Download(Request $request, string $number, UriSigner $signer): Response

InvoiceWebhookController class

class InvoiceWebhookController extends AbstractController InvoiceWebhookController.php:17

An approved platform's callback about an invoice it carries (glitchr/omnibill, omnibill.gateways.<gateway>: a gateway that takes webhooks): its signature checked by the gateway, the invoice's lifecycle status updated. Without glitchr/omnibill there is no transmission: 404.

InvoiceWebhookController::__construct()

public function __construct(readonly ?InvoiceTransmission $transmission = null)

InvoiceWebhookController::Webhook()

public function Webhook(Request $request, string $gateway): JsonResponse

OrderController class

class OrderController extends AbstractController OrderController.php:17

The member's orders - carts excluded - and one order's receipt.

OrderController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PaginatorInterface $paginator, readonly int $perPage = 20)

OrderController::Index()

public function Index(Request $request): Response

OrderController::Show()

public function Show(string $reference): Response

PaymentController class

class PaymentController extends AbstractController PaymentController.php:31

Where a payment provider sends people and events back, for every omnitrade gateway: the buyer's return page and the webhook both settle the same transaction, found by the provider's reference; Checkout::confirm() is idempotent, so both may arrive.

PaymentController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Checkout $checkout, readonly PaymentGatewayRegistry $gateways, readonly TranslatorInterface $translator, readonly ?EventDispatcherInterface $dispatcher = null)

PaymentController::Return()

public function Return(Request $request, int $order, string $gateway): Response

PaymentController::Webhook()

public function Webhook(Request $request, string $gateway): JsonResponse

PickupController class

class PickupController extends AbstractController PickupController.php:15

Following a hand-over (Entity\Order\Pickup) through its link, without an account: the token is the key. The orders made together share it and show on the same page.

PickupController::Track()

public function Track(string $token, PickupRepository $pickups): Response

QuickOrderController class

class QuickOrderController extends AbstractController QuickOrderController.php:37

A product bought in one step (Service\QuickOrder): the form of @Marketplace/client/_quick_order.html.twig (Form\QuickOrderType, guarded as glitchr/omnibase guards a form) posts an e-mail address here, the payment follows, and the buyer ends on the order's own page - a signed link, no account. The provider sends the buyer back to marketplace_payment_return, which expects its customer signed in: QuickOrderReturnListener hands the return of a quick order to back() here instead.

const SESSION = 'marketplace/quick_orders'

Session: the ids of the quick orders this visitor made.

QuickOrderController::__construct()

public function __construct(readonly QuickOrder $quickOrder, readonly EntityManagerInterface $entityManager, readonly TranslatorInterface $translator)

QuickOrderController::Buy()

public function Buy(Request $request, int $id, QuickOrderTwigExtension $forms): Response

QuickOrderController::Back()

public function Back(Request $request, int $order, string $gateway, PaymentGatewayRegistry $gateways, Checkout $checkout): Response

Back from the payment provider (QuickOrderReturnListener routes marketplace_payment_return here for a quick order).

QuickOrderController::Done()

public function Done(Request $request, string $reference, UriSigner $signer, EventDispatcherInterface $dispatcher): Response

QuoteController class

class QuoteController extends AbstractController QuoteController.php:54

Business quotes on the site: the form asking for one (from a product's page, from a cart that cannot go where it should, from a trade page), the quote read through its own link (/cotation/<token>), accepted - it becomes an order waiting in the client's carts (Service\QuoteToOrder) - or declined, and the client's quotes in their account.

With glitchr/omnisign and marketplace.quotes.signature, accepting a priced quote is signing it in the page (Quote\Signature\QuoteSignatures): the client goes to the provider's signing page and comes back to /cotation/<token>/signee, the quote accepted once the signature is completed; the signed quote and its evidence are downloaded from its page.

Under /cotation by default ("cotation", not "devis": omnibase/forge keeps /devis for a studio's); marketplace.quotes.path moves it - "devis" on a site without the forge.

QuoteController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly QuoteRepository $quotes, readonly TranslatorInterface $translator, readonly bool $enabled = true, readonly ?string $recipient = null, readonly bool $phone = true, readonly bool $attachments = true, readonly bool $consent = false, readonly ?QuoteSignatures $signatures = null)

QuoteController::Request()

public function Request(Request $request, MailerInterface $mailer, CompanyRegistry $registry, VatNumbers $vatNumbers, Attachments $files): Response

QuoteController::Show()

public function Show(string $token, QuoteToOrder $quoteToOrder): Response

QuoteController::Accept()

public function Accept(Request $request, string $token, QuoteToOrder $quoteToOrder): Response

QuoteController::Signed()

public function Signed(string $token): Response

Back from the provider's signing page: the quote accepted once signed, open again when declined or expired.

QuoteController::SignatureFile()

public function SignatureFile(string $token, string $kind): Response

The signed quote ("document") or its evidence ("preuve"): for its client and the shop's staff.

QuoteController::Decline()

public function Decline(Request $request, string $token): Response

QuoteController::Mine()

public function Mine(): Response

ShipmentController class

class ShipmentController extends AbstractController ShipmentController.php:27

The staff side of posting goods: the orders waiting to leave, each with its address, and the two steps - shipped (with the tracking number) and delivered. The member follows both on their order page.

A screen of the back office: under /admin, in its layout with its menus, and nestable (X-Transparent-Nest) like every admin page - not a page of the shop. Its first address, /commandes/a-expedier, leads there.

ShipmentController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Shipping $shipping, readonly TranslatorInterface $translator, readonly AdminContext $adminContext, readonly MenuBuilder $menuBuilder)

ShipmentController::Queue()

public function Queue(): Response

ShipmentController::LegacyQueue()

public function LegacyQueue(): Response

The queue's address before it moved into the back office: bookmarks and old links still land.

ShipmentController::Ship()

public function Ship(Request $request, string $reference): Response

ShipmentController::Deliver()

public function Deliver(Request $request, string $reference): Response

StoreController class

class StoreController extends AbstractController StoreController.php:21

Browsing: the stores, a store's shelf, a product. Route names are marketplace_*; the paths are French, as the Chapaland site is - an application wanting others overrides the routes, not the controller.

StoreController::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PaginatorInterface $paginator, readonly Cart $cart, readonly int $perPage = 24)

StoreController::Stores()

public function Stores(): Response

StoreController::Store()

public function Store(Request $request, string $slug): Response

StoreController::Product()

public function Product(string $store, string $slug): Response

SupplyController class

class SupplyController extends AbstractController SupplyController.php:22

The suppliers' side: the page a partner workshop reaches from its brief's signed link - what to make, and a form to accept, say where it stands and give the tracking -, and the webhook of the suppliers that have one.

SupplyController::__construct()

public function __construct(readonly Supply $supply)

SupplyController::Offline()

public function Offline(Request $request, UriSigner $signer, string $reference): Response

SupplyController::Webhook()

public function Webhook(Request $request, SupplierRegistry $suppliers, string $supplier): JsonResponse

Base\Marketplace\DependencyInjection

MarketplaceConfiguration class

class MarketplaceConfiguration extends AbstractBaseConfiguration MarketplaceConfiguration.php:8

MarketplaceConfiguration::getConfigTreeBuilder()

public function getConfigTreeBuilder(): TreeBuilder

MarketplaceExtension class

class MarketplaceExtension extends AbstractBaseExtension implements PrependExtensionInterface MarketplaceExtension.php:18

const ENUMS = [OrderState::class, PaymentState::class, ProductAvailability::class, ShippingRate::class, Barcode::class]

The bundle's enums, registered as the Doctrine column types its entities name.

MarketplaceExtension::getConfiguration()

public function getConfiguration(array $config, ContainerBuilder $container): MarketplaceConfiguration

MarketplaceExtension::prepend()

public function prepend(ContainerBuilder $container): void

Two things the host would otherwise have to declare by hand:

  • the enum column types, registered with DBAL the way base-bundle registers its own (a type discovered late is a column missing from the schema);
  • this bundle's attribute directory (#[OrderReference]), added to the paths base-bundle's AttributeReader scans.

MarketplaceExtension::load()

public function load(array $configs, ContainerBuilder $container): void

Base\Marketplace\Entity

Attachment class

class Attachment implements Stringable Attachment.php:16

A file somebody gave the shop: with a quote request (a logo, a photo of the shopfront, a plan), or for an order line (the artwork of a printed item). Kept outside the public directory (marketplace.attachments.directory) under a name nobody chose; read through the back office, or through a signed link (Service\Attachments).

Attachment::__construct()

public function __construct(string $path, string $name, string $mimeType = 'application/octet-stream', int $size = 0)

Attachment::__toString()

public function __toString(): string

Attachment::getId()

public function getId(): ?int

Attachment::getQuote()

public function getQuote(): ?Quote

Attachment::setQuote()

public function setQuote(?Quote $quote): self

Attachment::getOrderItem()

public function getOrderItem(): ?OrderItem

Attachment::setOrderItem()

public function setOrderItem(?OrderItem $orderItem): self

Attachment::getPath()

public function getPath(): string

Attachment::getName()

public function getName(): string

Attachment::getMimeType()

public function getMimeType(): string

Attachment::getSize()

public function getSize(): int

Attachment::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Attachment::isImage()

public function isImage(): bool

Brand class

class Brand extends Thread implements TranslatableInterface, LinkableInterface Brand.php:26

Who makes a product: a wine estate or a négociant house, a brewery, a maker. A thread - its title the name, its content the story (translated like any thread) - with a logo, where it is (country, region), a gallery, its own site, and its products (Product::$brand).

It is what Shopify calls a product's vendor and WooCommerce its brand: the catalogue synchronisation (Catalogue\PlatformSynchronizer) files a platform's product under the brand of that name.

Brand::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

The application names the page of a brand: marketplace.brand_route (none: no link).

Brand::__construct()

public function __construct(?string $name = null)

Brand::getProducts()

public function getProducts(): Collection
public function getLogo()

Brand::getLogoFile()

public function getLogoFile()
public function setLogo($logo): self

Brand::getGallery()

public function getGallery(): array

The pictures of the place: the vineyard, the cellar, the people.

Brand::setGallery()

public function setGallery($gallery): self

Brand::getCountry()

public function getCountry(): ?string

Brand::setCountry()

public function setCountry(?string $country): self

Brand::getRegion()

public function getRegion(): ?string

Brand::setRegion()

public function setRegion(?string $region): self

Brand::getWebsite()

public function getWebsite(): ?string

Brand::setWebsite()

public function setWebsite(?string $website): self

Credit class

class Credit Credit.php:19

A line of somebody's credit ledger, of one kind ("ai": answers of an assistant, "stationery": cents of print, "hour": hours of work...): a positive quantity credits (a pack bought, a plan's allowance, a gift), a negative one spends. The balance is the sum (Service\Credits); a credit with an expiry stops counting then, what was spent before stays spent.

Generic on purpose: a bundle keeps its units here under its own kind rather than in a ledger of its own.

Credit::__construct()

public function __construct(User $holder, string $kind, int $quantity, ?string $reason = null, ?\DateTimeImmutable $expiresAt = null)

Credit::getId()

public function getId(): ?int

Credit::getHolder()

public function getHolder(): ?User

Credit::getKind()

public function getKind(): string

Credit::getQuantity()

public function getQuantity(): int

Credit::isGrant()

public function isGrant(): bool

Credit::getReason()

public function getReason(): ?string

Credit::getOrderReference()

public function getOrderReference(): ?string

Credit::setOrderReference()

public function setOrderReference(?string $orderReference): self

Credit::getResourceType()

public function getResourceType(): ?string

Credit::getResourceId()

public function getResourceId(): ?string

Credit::setResource()

public function setResource(?string $type, int|string|null $id): self

Credit::getExpiresAt()

public function getExpiresAt(): ?\DateTimeImmutable

Credit::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Entitlement class

class Entitlement implements Stringable Entitlement.php:28

A right somebody holds: what a plan bought gives (its grants: limits, switches, rates), from when until when, and where it comes from (the product, the order's reference, the subscription that carries it).

Generic on purpose - any bundle hangs its own rights here rather than keeping a table of its own:

  • a plan of a platform: code "plan-b", grants {"events.major": 1, "guests": 150, "list": true}, no resource;
  • an access to one thing (a course, a download): code "course", the resource named (resourceType "classroom_course", resourceId "42"), no grants needed - holding it is the right;
  • anything granted by hand (a gift, a partner): no product, no order.

Counted grants are consumed through Entity\Usage; Service\Entitlements answers "may they?" and "how many are left?".

Entitlement::__construct()

public function __construct(User $holder, string $code, array $grants = [], ?\DateTimeImmutable $expiresAt = null, ?\DateTimeImmutable $startsAt = null)

Entitlement::__toString()

public function __toString(): string

Entitlement::getId()

public function getId(): ?int

Entitlement::getHolder()

public function getHolder(): ?User

Entitlement::getCode()

public function getCode(): string

Entitlement::getGrants()

public function getGrants(): array

Entitlement::setGrants()

public function setGrants(array $grants): self

Entitlement::getGrant()

public function getGrant(string $key, mixed $default = null): mixed

Entitlement::getLevel()

public function getLevel(): int

Entitlement::setLevel()

public function setLevel(int $level): self

Entitlement::getResourceType()

public function getResourceType(): ?string

Entitlement::getResourceId()

public function getResourceId(): ?string

Entitlement::setResource()

public function setResource(?string $type, int|string|null $id): self

Entitlement::isFor()

public function isFor(?string $type, int|string|null $id): bool

Entitlement::getProduct()

public function getProduct(): ?Product

Entitlement::setProduct()

public function setProduct(?Product $product): self

Entitlement::getOrderReference()

public function getOrderReference(): ?string

Entitlement::setOrderReference()

public function setOrderReference(?string $orderReference): self

Entitlement::getSubscription()

public function getSubscription(): ?Subscription

Entitlement::setSubscription()

public function setSubscription(?Subscription $subscription): self

Entitlement::getStartsAt()

public function getStartsAt(): \DateTimeImmutable

Entitlement::getExpiresAt()

public function getExpiresAt(): ?\DateTimeImmutable

Entitlement::setExpiresAt()

public function setExpiresAt(?\DateTimeImmutable $expiresAt): self

Entitlement::getRevokedAt()

public function getRevokedAt(): ?\DateTimeImmutable

Entitlement::revoke()

public function revoke(?\DateTimeImmutable $at = null): self

Entitlement::getEndedAt()

public function getEndedAt(): ?\DateTimeImmutable

Entitlement::markEnded()

public function markEnded(): self

Entitlement::getRemindedAt()

public function getRemindedAt(): ?\DateTimeImmutable

Entitlement::markReminded()

public function markReminded(): self

Entitlement::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Entitlement::isActive()

public function isActive(?\DateTimeImmutable $at = null): bool

Held at that moment: started, not revoked, not expired, its subscription (if any) running.

Invoice class

class Invoice Invoice.php:25

An invoice of the shop, or a credit note (avoir): what was sold, to whom, by whom, for how much - written once, when it is issued (Service\Invoices::issue(), ::credit()), and never again.

Its number is the next of a sequence without a gap, one per series and year (F-2026-000041; A-2026-000003 for a credit note). The seller and the buyer are copied onto it as they are that day (name, address, SIREN, SIRET, VAT number), and so are its lines and amounts, taken from the order (its VAT included: the order computed it). What follows - sent, paid, cancelled by a credit note - is its state; nothing else of it changes: Doctrine refuses the update. A correction is a credit note, then a new invoice.

Amounts are integers in the currency's smallest unit, as the order's.

const TYPE_INVOICE = 'invoice'
const TYPE_CREDIT_NOTE = 'credit_note'
const STATE_ISSUED = 'issued'
const STATE_SENT = 'sent'
const STATE_PAID = 'paid'
const STATE_CANCELLED = 'cancelled'
const MUTABLE = ['state', 'sentAt', 'paidAt', 'cancelledAt', 'creditNote']

What may still change once issued: where it stands.

Invoice::__construct()

public function __construct(string $type, string $series, int $year, int $sequence, string $number, \DateTimeImmutable $issuedAt, ?Order $order, string $currency, array $seller, array $buyer, array $lines, array $totals, array $mentions = [], ?\DateTimeImmutable $soldAt = null, ?\DateTimeImmutable $dueAt = null, ?Invoice $credited = null)

Invoice::__toString()

public function __toString(): string

Invoice::refuseChanges()

public function refuseChanges(PreUpdateEventArgs $event): void

Issued, nothing but its state changes: an update of anything else is refused.

Invoice::getId()

public function getId(): ?int

Invoice::getType()

public function getType(): string

Invoice::isCreditNote()

public function isCreditNote(): bool

Invoice::getSeries()

public function getSeries(): string

Invoice::getYear()

public function getYear(): int

Invoice::getSequence()

public function getSequence(): int

Invoice::getNumber()

public function getNumber(): string

Invoice::getIssuedAt()

public function getIssuedAt(): \DateTimeImmutable

Invoice::getSoldAt()

public function getSoldAt(): ?\DateTimeImmutable

Invoice::getDueAt()

public function getDueAt(): ?\DateTimeImmutable

Invoice::getOrder()

public function getOrder(): ?Order

Invoice::getOrderReference()

public function getOrderReference(): ?string

Invoice::getCredited()

public function getCredited(): ?Invoice

Invoice::getCreditNote()

public function getCreditNote(): ?Invoice

Invoice::getCurrency()

public function getCurrency(): string

Invoice::getSeller()

public function getSeller(): array

Invoice::getBuyer()

public function getBuyer(): array

Invoice::getLines()

public function getLines(): array

Invoice::getTotals()

public function getTotals(): array

Invoice::getTotal()

public function getTotal(): int

Invoice::getMentions()

public function getMentions(): array

Invoice::getState()

public function getState(): string

Invoice::isCancelled()

public function isCancelled(): bool

Invoice::isPaid()

public function isPaid(): bool

Invoice::getSentAt()

public function getSentAt(): ?\DateTimeImmutable

Invoice::getPaidAt()

public function getPaidAt(): ?\DateTimeImmutable

Invoice::getCancelledAt()

public function getCancelledAt(): ?\DateTimeImmutable

Invoice::markSent()

public function markSent(\DateTimeImmutable $at = new \DateTimeImmutable()): static

Invoice::markPaid()

public function markPaid(\DateTimeImmutable $at = new \DateTimeImmutable()): static

Invoice::cancelBy()

public function cancelBy(Invoice $creditNote, \DateTimeImmutable $at = new \DateTimeImmutable()): static

Cancelled by that credit note: Service\Invoices::credit().

Order class

class Order implements IconizeInterface, LinkableInterface Order.php:33

public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

Order::__iconize()

public function __iconize(): ?array

Order::__iconizeStatic()

public static function __iconizeStatic(): ?array

Order::__toString()

public function __toString(): string

Order::__construct()

public function __construct(?Store $store = null)

Order::getId()

public function getId()

Order::getManager()

public function getManager(): ?MerchantInterface

Order::getManagers()

public function getManagers(): Collection

Order::addManager()

public function addManager(MerchantInterface $manager): self

Order::removeManager()

public function removeManager(MerchantInterface $manager): self

Order::getReference()

public function getReference()

Order::getStore()

public function getStore(): ?Store

Order::setStore()

public function setStore(?Store $store): self

Order::getCustomer()

public function getCustomer(): ?User

Order::isCustomer()

public function isCustomer(mixed $user): bool

Whether $user is this order's customer. Compared by id, never by instance: the order and the logged-in member can come out of the second-level cache as two objects for the same row.

Order::setCustomer()

public function setCustomer(?User $customer): self

Order::getState()

public function getState(): string

Order::setState()

public function setState(string $state): self

Order::markAsConfirmed()

public function markAsConfirmed(): self

Order::markAsBeingProcessed()

public function markAsBeingProcessed(): self

Order::markAsPending()

public function markAsPending(): self

Order::markAsShipped()

public function markAsShipped(): self

Order::markAsCompleted()

public function markAsCompleted(): self

Order::markAsCancelled()

public function markAsCancelled(): self

Order::markAsRefunded()

public function markAsRefunded(): self

Order::markAsCart()

public function markAsCart(): self

Order::markAsAbandoned()

public function markAsAbandoned(): self

Order::getShipments()

public function getShipments(): Collection

Order::addShipment()

public function addShipment(Shipment $shipment): self

Order::removeShipment()

public function removeShipment(Shipment $shipment): self

Order::isEmpty()

public function isEmpty(): bool

Order::getUniqueProducts()

public function getUniqueProducts(): array

Every distinct product in this order.

Generic again, as the commented-out original beside it always was: the filter that had been added here kept only Wallpapers, which made the name a lie everywhere except one shop and was the reason Order could not move into a bundle. Callers that really do want one kind say so, with getUniqueProductsOf() below.

Order::getUniqueProductsOf()

public function getUniqueProductsOf(string $class): array

Order::getItem()

public function getItem(int $i): ?OrderItem

Order::getItems()

public function getItems(): Collection

Order::getAttachments()

public function getAttachments(): array
Returns

the files the buyer gave for its lines

Order::addItem()

public function addItem(OrderItem $item): self

Order::removeItem()

public function removeItem(OrderItem $item): self

Order::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Order::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

Order::getPaidAt()

public function getPaidAt(): ?\DateTimeInterface

Order::getRegion()

public function getRegion(): ?Region

Order::setRegion()

public function setRegion(?Region $region): self

Order::getPaymentMethod()

public function getPaymentMethod(): ?PaymentMethod

Order::setPaymentMethod()

public function setPaymentMethod(?PaymentMethod $paymentMethod): self

Order::getShippingMethod()

public function getShippingMethod(): ?ShippingMethod

Order::setShippingMethod()

public function setShippingMethod(?ShippingMethod $shippingMethod): self

Order::getShippingUnits()

public function getShippingUnits(): int

Order::notify()

public function notify(): ?bool

Order::setNotify()

public function setNotify(bool $notify): self

Order::getDiscounts()

public function getDiscounts(): Collection

Order::getCoupons()

public function getCoupons(): array

Order::getPromotions()

public function getPromotions(): array

Order::addDiscount()

public function addDiscount(Discount $discount): self

Order::removeDiscount()

public function removeDiscount(Discount $discount): self

Order::getAdditionalFees()

public function getAdditionalFees(): Collection

Order::addAdditionalFee()

public function addAdditionalFee(Fee $additionalFee): self

Order::removeAdditionalFee()

public function removeAdditionalFee(Fee $additionalFee): self

Order::getAdditionalTaxes()

public function getAdditionalTaxes(): Collection

Order::addAdditionalTax()

public function addAdditionalTax(Tax $additionalTax): self

Order::removeAdditionalTax()

public function removeAdditionalTax(Tax $additionalTax): self

Order::isPaid()

public function isPaid()

Order::isCompleted()

public function isCompleted()

Order::isReviewed()

public function isReviewed()

Order::isAbandoned()

public function isAbandoned()

Order::isConfirmed()

public function isConfirmed()

Order::isBeingProcessed()

public function isBeingProcessed()

Order::isCancelled()

public function isCancelled()

Order::isRefunded()

public function isRefunded()

Order::isBeingShipped()

public function isBeingShipped()

Order::isPending()

public function isPending()

Order::isDelayed()

public function isDelayed()

Order::isBeingReturned()

public function isBeingReturned()

Order::isReturned()

public function isReturned()

Order::getArrivingTime()

public function getArrivingTime()

Order::getCurrency()

public function getCurrency(): string

Order::setCurrency()

public function setCurrency(string $currency)

Order::getGrossPrice()

public function getGrossPrice(): int

Order::getSalePrice()

public function getSalePrice(): int

Order::getVatCharge()

public function getVatCharge(): int

Order::getVatExemption()

public function getVatExemption(): ?string

Order::setVatExemption()

public function setVatExemption(?string $vatExemption): self

Order::isVatExempt()

public function isVatExempt(): bool

Order::getQuoteReference()

public function getQuoteReference(): ?string

Order::setQuoteReference()

public function setQuoteReference(?string $quoteReference): self

Order::isQuoted()

public function isQuoted(): bool

Order::getNetPrice()

public function getNetPrice(): int

Order::getTotalPaid()

public function getTotalPaid(): int

Order::getBalanceDue()

public function getBalanceDue(): int

Order::getAdditionalTaxCharge()

public function getAdditionalTaxCharge(): int

Order::setAdditionalTaxCharge()

public function setAdditionalTaxCharge(float|int $additionalTaxCharge, ?string $currency = null): self

Order::getShippingCharge()

public function getShippingCharge(): int

Order::setShippingCharge()

public function setShippingCharge(float|int $shippingCharge, ?string $currency = null): self

Order::getServiceCharge()

public function getServiceCharge(): int

Order::setServiceCharge()

public function setServiceCharge(float|int $serviceCharge, ?string $currency = null): self

Order::getDiscountCharge()

public function getDiscountCharge(): int

Order::setDiscountCharge()

public function setDiscountCharge(float|int $discountCharge, ?string $currency = null): self

Order::getBillingAddress()

public function getBillingAddress(): ?BillingAddress

Order::setBillingAddress()

public function setBillingAddress(?BillingAddress $billingAddress): self

Order::getShippingAddress()

public function getShippingAddress(): ?ShippingAddress

Order::setShippingAddress()

public function setShippingAddress(?ShippingAddress $shippingAddress): self

Order::getReviews()

public function getReviews(): Collection

Order::addReview()

public function addReview(Review $review): self

Order::removeReview()

public function removeReview(Review $review): self

Order::isAbandonable()

public function isAbandonable(): bool

Order::getAbandonDelay()

public static function getAbandonDelay(): int

Order::getAbandonTime()

public function getAbandonTime(): ?int

Order::getAbandonTimeStr()

public function getAbandonTimeStr(): ?string

Order::isDeletable()

public function isDeletable(): bool

Order::getDeleteDelay()

public static function getDeleteDelay(): int

Order::getDeleteTime()

public function getDeleteTime(): ?int

Order::getDeleteTimeStr()

public function getDeleteTimeStr(): ?string

Order::getTransactions()

public function getTransactions(): Collection

Order::addTransaction()

public function addTransaction(Transaction $transaction): self

Order::markAsPaidAt()

public function markAsPaidAt(?\DateTimeInterface $at = null): self

When the money came in. Set by the checkout once a gateway says so - attaching a transaction is not being paid: a bank transfer is attached the day it is announced and paid the day it arrives.

Order::removeTransaction()

public function removeTransaction(Transaction $transaction): self

Product class

class Product extends Thread implements TranslatableInterface, AutocompleteInterface, LinkableInterface, ShippingUnitInterface Product.php:48

const INHERITS_FROM = true

Product::__toKey()

public function __toKey(mixed ...$variadic): string

Product::__typesense()

public function __typesense(): ?string

Product::__iconize()

public function __iconize(): ?array

Product::__iconizeStatic()

public static function __iconizeStatic(): ?array

Product::__autocomplete()

public function __autocomplete(): string

Product::__autocompleteData()

public function __autocompleteData(): array
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

Product::getRouteIdentifierClass()

public function getRouteIdentifierClass(): string

Which class this product is ROUTED as, which is not always the class it is.

A product whose route is its own (a wallpaper, a book) answers with itself and needs nothing here. One that is a satellite of another - a free sample, a bundle, a made-to-measure cut - overrides this to name the class whose route it should appear under, so it does not need a route of its own.

Exists so Review (and anything else building a product route) can stop switching on concrete product classes. That switch is what tied the marketplace to one shop's catalogue and kept it out of a bundle.

Product::__toString()

public function __toString()

Product::__construct()

public function __construct(?MerchantInterface $merchant = null, ?Store $store = null, int $unitPrice = 0, ?string $currency = null)

Product::getHeadline()

public function getHeadline(?string $locale = null, int $inheritanceDepthIfNotSet = 0): ?string

Product::getCategories()

public function getCategories(): ?array

Product::getBrands()

public function getBrands(): ?array

Product::getReference()

public function getReference(int $chrLength = 3, int $numLength = 4): ?string

Product::setStore()

public function setStore(?Store $store)

Product::getStore()

public function getStore(): ?Store

Product::isShippable()

public function isShippable(): bool

Something to send: goods. A plan or a pack of credits is delivered as a right, with no address asked.

Product::getMaxQuantity()

public function getMaxQuantity(): ?int

Product::isVariant()

public static function isVariant()

Product::getVariants()

public function getVariants(): Collection

Product::addVariant()

public function addVariant(Product $variant): self

Product::removeVariant()

public function removeVariant(Product $variant): self

Product::removeAllVariants()

public function removeAllVariants(): self

Product::getPriceRange()

public function getPriceRange(): array

The lowest and the highest price it sells at: its variants' still for sale when it has some (a banner by the square metre, a print by the hundred), its own otherwise. Smallest unit, before VAT.

Product::getPriceFrom()

public function getPriceFrom(): ?int

Product::setPriceFrom()

public function setPriceFrom(?int $priceFrom): self

Product::getStartingPrice()

public function getStartingPrice(): ?int

The price a list shows: the one typed (priceFrom), else the lowest of its range. Null when there is none to show: no price was ever written (nor on a variant), or a product of its own kind has an empty range - a list says "on request" then, never a price of zero.

Product::isPricedFrom()

public function isPricedFrom(): bool

Whether that price is a "from": typed as one, or the lowest of several.

Product::getPrice()

public function getPrice()

Product::getUnitPrice()

public function getUnitPrice(): ?int

Product::setUnitPrice()

public function setUnitPrice(?int $unitPrice): self

A form sent with its price left empty gives null: taken as it is, for the validation to say so (NotNull) rather than a type error to stop the page.

Product::getCurrency()

public function getCurrency(): ?string

Product::setCurrency()

public function setCurrency(string $currency): self

Product::getColors()

public function getColors(): array

Product::getWeight()

public function getWeight(): ?int

Product::getWeightUnit()

public function getWeightUnit(): ?string

Product::getWidth()

public function getWidth(): ?int

Product::getWidthUnit()

public function getWidthUnit(): ?string

Product::getHeight()

public function getHeight(): ?int

Product::getHeightUnit()

public function getHeightUnit(): ?string

Product::getLength()

public function getLength(): ?int

Product::getLengthUnit()

public function getLengthUnit(): ?string

Product::getDimensions()

public function getDimensions(): array

Product::getShippingUnits()

public function getShippingUnits(): float

Product::getStock()

public function getStock(): ?int

Product::setStock()

public function setStock(?int $stock): self

Product::isForSell()

public function isForSell()

Product::getAvailability()

public function getAvailability()

Product::setAvailability()

public function setAvailability($availability): self

An availability is never nothing (the column refuses null): given none, the product keeps the one it had - in stock for a new one. The back office's select is filled by a script; a form sent without it carries no value, and the insertion stopped on "Column 'availability' cannot be null".

Product::getAttributes()

public function getAttributes(?string $code = null, ?string $abstractAttributeClassName = null): Collection

Product::getAttribute()

public function getAttribute(string $code, ?string $abstractAttributeClassName = null): ?Attribute

Product::addAttribute()

public function addAttribute(Attribute $attribute): self

Product::removeAttribute()

public function removeAttribute(Attribute $attribute): self

Product::getExports()

public function getExports(?string $code = null): Collection

Product::getExport()

public function getExport(string $code): mixed

Product::addExport()

public function addExport(Hyperlink $attribute): self

Product::removeExport()

public function removeExport(Hyperlink $attribute): self

Product::getFeatures()

public function getFeatures(): Collection

Product::addFeature()

public function addFeature(Feature $feature): self

Product::removeFeature()

public function removeFeature(Feature $feature): self

Product::getOrderItems()

public function getOrderItems(): Collection

Product::addOrderItem()

public function addOrderItem(OrderItem $orderItem): self

Product::removeOrderItem()

public function removeOrderItem(OrderItem $orderItem): self

Product::getIdentifiers()

public function getIdentifiers(): Collection

Product::getSku()

public function getSku(): ?string

Its stock keeping unit: the SKU among its identifiers' barcodes, or null. What a payment provider's line item names (Payment\Omnitrade\OmnitradeGateway) - a product sold without one (a licence, an hour pack) has none.

Product::addIdentifier()

public function addIdentifier(Identifier $identifier): self

Product::getAuthor()

public function getAuthor(int $i = 0)

Product::getAuthors()

public function getAuthors(): Collection

The owners that count as authors of this product.

Not every owner is one - a product is owned by the merchant selling it as well as by whoever created it - so this filters, and getAuthorClass() below decides on what. It used to filter on instanceof Artist, a class belonging to one shop, which is what kept Product out of a bundle.

Product::getOwnersOf()

public function getOwnersOf(string $class): Collection

Product::getEAN()

public function getEAN(): ?string

Product::getBarcodes()

public function getBarcodes(string $std): Collection

Product::removeIdentifier()

public function removeIdentifier(Identifier $identifier): self

Product::getImage()

public function getImage(?int $i = null): ?Image

Product::getImages()

public function getImages(): Collection

Product::getImageCrop()

public function getImageCrop(string $slug, ?int $i = null): ?ImageCrop

Product::addImage()

public function addImage(Image $image): self

Product::removeImage()

public function removeImage(Image $image): self

Product::getImageMarketplaces()

public function getImageMarketplaces()

Product::getImageMarketplaceFiles()

public function getImageMarketplaceFiles()

Product::setImageMarketplaces()

public function setImageMarketplaces($imageMarketplaces)

Product::getReviews()

public function getReviews(): Collection

Product::addReview()

public function addReview(Review $review): self

Product::removeReview()

public function removeReview(Review $review): self

Product::getChannels()

public function getChannels(): Collection

Product::addChannel()

public function addChannel(Channel $channel): self

Product::removeChannel()

public function removeChannel(Channel $channel): self

Product::getBrand()

public function getBrand(): ?Brand

Product::setBrand()

public function setBrand(?Brand $brand): self

Product::getPackSize()

public function getPackSize(): int

Product::getOwnPackSize()

public function getOwnPackSize(): ?int

Product::setPackSize()

public function setPackSize(?int $packSize): self

Product::getMinimumQuantity()

public function getMinimumQuantity(): int

Product::getOwnMinimumQuantity()

public function getOwnMinimumQuantity(): ?int

Product::setMinimumQuantity()

public function setMinimumQuantity(?int $minimumQuantity): self

Product::boundQuantity()

public function boundQuantity(int $wanted, ?int $max = null): int

A quantity a cart may hold of it: at least the minimum, a whole number of lots, at most $max (the shop's cart_max_quantity, the stock) rounded down to the lot. 0 when not even the minimum fits under $max.

Product::getKind()

public function getKind(): \Base\Marketplace\Enum\ProductKind

Product::setKind()

public function setKind(\Base\Marketplace\Enum\ProductKind|string $kind): self

Product::isPlan()

public function isPlan(): bool

Product::isCreditPack()

public function isCreditPack(): bool

Product::getPlan()

public function getPlan(): ?array

Product::setPlan()

public function setPlan(\Base\Marketplace\Model\PlanTerms|array|null $plan): self

Product::getPlanTerms()

public function getPlanTerms(): \Base\Marketplace\Model\PlanTerms

Product::getSupplier()

public function getSupplier(): ?string

Product::setSupplier()

public function setSupplier(?string $supplier): self

Product::getSupplierReference()

public function getSupplierReference(): ?string

Product::setSupplierReference()

public function setSupplierReference(?string $supplierReference): self

Product::isAgeRestricted()

public function isAgeRestricted(): bool

Product::getAgeRestricted()

public function getAgeRestricted(): bool

Product::setAgeRestricted()

public function setAgeRestricted(bool $ageRestricted): self

Product::getAssociations()

public function getAssociations(?AssociationType $type = null): Collection

Product::addAssociation()

public function addAssociation(Association $association): self

Product::removeAssociation()

public function removeAssociation(Association $association): self

Product::associate()

public function associate(Product $target, AssociationType $type = AssociationType::PAIRING, array $notes = []): Association

A pairing, a cross-sell or an upsell to another product, with its note by language.

Product::getOptionGroups()

public function getOptionGroups(): Collection
Returns

its own; a variant without any offers its principal's

Product::hasOptions()

public function hasOptions(): bool

Product::addOptionGroup()

public function addOptionGroup(OptionGroup $group): self

Product::removeOptionGroup()

public function removeOptionGroup(OptionGroup $group): self

Product::getAttributeValue()

public function getAttributeValue(string $code, ?string $locale = null): mixed

Its attribute of this code (an AttributeSet's field), resolved in a language: "Margaux", 13.5, ["Merlot", "Cabernet sauvignon"]. A variant without it reads its principal's.

Quote class

class Quote extends AbstractQuote Quote.php:23

A business quote: a professional buyer asks (the quote form), the seller prices lines - a product of the catalogue or a free line, by the lot - with the terms of the trade (which way, which Incoterm, to which country and place, for when), sends it, the buyer accepts it in their account, and it becomes an order paid like any other (Service\QuoteToOrder). An export's order carries no VAT (Pricing\ExportExemption).

Quote::__construct()

public function __construct(string $reference = '')

Quote::getCompanyName()

public function getCompanyName(): ?string

Quote::setCompanyName()

public function setCompanyName(?string $companyName): static

Quote::getPhone()

public function getPhone(): ?string

Quote::setPhone()

public function setPhone(?string $phone): static

Quote::getAttachments()

public function getAttachments(): Collection

Quote::addAttachment()

public function addAttachment(Attachment $attachment): static

Quote::getVatNumber()

public function getVatNumber(): ?string

Quote::setVatNumber()

public function setVatNumber(?string $vatNumber): static

Quote::getDirection()

public function getDirection(): ?TradeDirection

Quote::setDirection()

public function setDirection(?TradeDirection $direction): static

Quote::getIncoterm()

public function getIncoterm(): ?Incoterm

Quote::setIncoterm()

public function setIncoterm(?Incoterm $incoterm): static

Quote::getPlace()

public function getPlace(): ?string

Quote::setPlace()

public function setPlace(?string $place): static

Quote::getTerms()

public function getTerms(): ?string

"FOB Le Havre", "DAP Tokyo": the Incoterm and its place, as a contract writes them.

Quote::getCountry()

public function getCountry(): ?string

Quote::setCountry()

public function setCountry(?string $country): static

Quote::getDeliveryAddress()

public function getDeliveryAddress(): ?string

Quote::setDeliveryAddress()

public function setDeliveryAddress(?string $deliveryAddress): static

Quote::getVolume()

public function getVolume(): ?string

Quote::setVolume()

public function setVolume(?string $volume): static

Quote::getTargetDate()

public function getTargetDate(): ?\DateTimeImmutable

Quote::setTargetDate()

public function setTargetDate(?\DateTimeImmutable $targetDate): static

Quote::getStore()

public function getStore(): ?Store

Quote::setStore()

public function setStore(?Store $store): static

Quote::getOrder()

public function getOrder(): ?Order

Quote::setOrder()

public function setOrder(?Order $order): static

Quote::getLines()

public function getLines(): Collection

Quote::addLine()

public function addLine(QuoteLine $line): static

Quote::removeLine()

public function removeLine(QuoteLine $line): static

Quote::getSubtotal()

public function getSubtotal(): int

Quote::getUnits()

public function getUnits(): int

How many units (bottles) the lines hold together.

Review class

class Review extends Thread implements IconizeInterface, AutocompleteInterface, LinkableInterface Review.php:22

Review::__toKey()

public function __toKey(mixed ...$variadic): string

Review::__iconizeStatic()

public static function __iconizeStatic(): ?array

Review::__typesense()

public function __typesense(): ?string

Review::__autocompleteData()

public function __autocompleteData(): array

Review::__autocomplete()

public function __autocomplete(): string
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

Review::__construct()

public function __construct(?User $reviewer = null, $rating = 1.0, array $pictures = [])

Review::getRating()

public function getRating(): ?float

Review::setRating()

public function setRating(float $rating): self

Review::getPicture()

public function getPicture(int $i = 0)

Review::getPictures()

public function getPictures()

Review::getPictureFiles()

public function getPictureFiles()

Review::setPictures()

public function setPictures(array $pictures)

Review::getProduct()

public function getProduct(): ?Product

Review::setProduct()

public function setProduct(?Product $product): self

Review::getColors()

public function getColors(): array

Review::getAuthor()

public function getAuthor(int $i = 0)

Review::getAuthors()

public function getAuthors(): Collection

Review::getStore()

public function getStore(): ?Store

Review::setStore()

public function setStore(?Store $store): self

Review::getOrder()

public function getOrder(): ?Order

Review::setOrder()

public function setOrder(?Order $order): self

Store class

class Store extends Thread implements TranslatableInterface, LinkableInterface Store.php:27

Store::__iconizeStatic()

public static function __iconizeStatic(): ?array
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

Store::__construct()

public function __construct(?MerchantInterface $merchant = null)

Store::getProducts()

public function getProducts(): Collection

Store::addProduct()

public function addProduct(Product $product): self

Store::removeProduct()

public function removeProduct(Product $product): self

Store::getRegions()

public function getRegions(): Collection

Store::addRegion()

public function addRegion(Region $region): self

Store::removeRegion()

public function removeRegion(Region $region): self

Store::getOrders()

public function getOrders(): Collection

Store::addOrder()

public function addOrder(Order $order): self

Store::removeOrder()

public function removeOrder(Order $order): self

Store::getReviews()

public function getReviews(): Collection

Store::addReview()

public function addReview(Review $review): self

Store::removeReview()

public function removeReview(Review $review): self

Store::getCurrency()

public function getCurrency(): ?string

Store::setCurrency()

public function setCurrency(string $currency): self

Store::chargesVat()

public function chargesVat(): bool

Store::setChargesVat()

public function setChargesVat(bool $chargesVat): self

Store::getVatNumber()

public function getVatNumber(): ?string

Store::setVatNumber()

public function setVatNumber(?string $vatNumber): self

Store::validateVat()

public function validateVat(ExecutionContextInterface $context): void

Store::getProductTaxa()

public function getProductTaxa(): Collection

Store::addProductTaxon()

public function addProductTaxon(ProductTaxon $productTaxon): self

Store::removeProductTaxon()

public function removeProductTaxon(ProductTaxon $productTaxon): self

Store::getReviewTaxa()

public function getReviewTaxa(): Collection

Store::addReviewTaxon()

public function addReviewTaxon(ReviewTaxon $reviewTaxon): self

Store::removeReviewTaxon()

public function removeReviewTaxon(ReviewTaxon $reviewTaxon): self

Store::isOpen()

public function isOpen(): ?bool

Store::setOpen()

public function setOpen(bool $open): self

Usage class

class Usage Usage.php:14

A counted grant used: one of the "events.major": 1 of a plan taken by this event, 3 of its 5 exports made. Releasing it (the event deleted) gives the unit back. What used it is named the way an Entitlement names its resource.

Usage::__construct()

public function __construct(Entitlement $entitlement, string $key, int $quantity = 1, ?string $resourceType = null, int|string|null $resourceId = null)

Usage::getId()

public function getId(): ?int

Usage::getEntitlement()

public function getEntitlement(): Entitlement

Usage::getKey()

public function getKey(): string

Usage::getQuantity()

public function getQuantity(): int

Usage::getResourceType()

public function getResourceType(): ?string

Usage::getResourceId()

public function getResourceId(): ?string

Usage::getUsedAt()

public function getUsedAt(): \DateTimeImmutable

Usage::getReleasedAt()

public function getReleasedAt(): ?\DateTimeImmutable

Usage::isReleased()

public function isReleased(): bool

Usage::release()

public function release(): self

Base\Marketplace\Entity\Catalogue

class PlatformLink PlatformLink.php:20

A product of this site and its original on a platform (an omnitrade gateway reading a catalogue: Stripe, Shopify, WooCommerce): which gateway, the product's and the variant's ids there, the stock item counted there, and a fingerprint of what was last written - a product that did not change there is not written again.

One row per variant: a platform product with three variants is a Product and two Variants here, three links. It replaces the Shopify-only ProductLink of the former src/Shopify module (table marketplace_shopify_link).

public function __construct(Product $product, string $gateway, string $remoteProduct, string $remoteVariant)
public function getId(): ?int
public function getProduct(): Product
public function getGateway(): string
public function getRemoteProduct(): string
public function getRemoteVariant(): string
public function getRemoteItem(): ?string
public function setRemoteItem(?string $remoteItem): self
public function getSku(): ?string
public function setSku(?string $sku): self
public function getFingerprint(): string
public function isOrphaned(): bool
public function setOrphaned(bool $orphaned): self
public function getRemoteUpdatedAt(): ?\DateTimeImmutable
public function getSyncedAt(): \DateTimeImmutable
public function synced(string $fingerprint, ?\DateTimeImmutable $remoteUpdatedAt = null): self

Written now from what the platform said.

Base\Marketplace\Entity\Order

OrderItem class

class OrderItem OrderItem.php:16

OrderItem::__toString()

public function __toString()

OrderItem::__construct()

public function __construct(Product $product, int $quantity = 1)

OrderItem::getId()

public function getId()

OrderItem::getRegion()

public function getRegion(): ?Region

OrderItem::getCustomer()

public function getCustomer(): ?User

OrderItem::getOrder()

public function getOrder(): ?Order

OrderItem::setOrder()

public function setOrder(?Order $order): self

OrderItem::getProduct()

public function getProduct(): ?Product

OrderItem::setProduct()

public function setProduct(?Product $product): self

OrderItem::getRecipient()

public function getRecipient(): ?array

OrderItem::setRecipient()

public function setRecipient(?array $recipient): self

OrderItem::getPersonalisation()

public function getPersonalisation(): ?array

OrderItem::setPersonalisation()

public function setPersonalisation(?array $personalisation): self

OrderItem::getOptions()

public function getOptions(): array

OrderItem::applyOptions()

public function applyOptions(\Base\Marketplace\Model\OptionSelection $selection, ?string $locale = null): self

The line takes these options: kept as a copy, their surcharge added to the product's unit price (before VAT, like it).

OrderItem::getOptionsSurcharge()

public function getOptionsSurcharge(): int

What the options add to each unit, before VAT.

OrderItem::getOptionsLabel()

public function getOptionsLabel(): string

"Bien cuit, Œuf mollet" - empty without options.

OrderItem::getOptionsKey()

public function getOptionsKey(): string

Which options, whatever their order: two lines of a product differ by it.

OrderItem::getAttachments()

public function getAttachments(): Collection

OrderItem::getComment()

public function getComment(): ?string

OrderItem::setComment()

public function setComment(?string $comment): self

OrderItem::getQuantity()

public function getQuantity(): ?int

OrderItem::setQuantity()

public function setQuantity(int $quantity): self

OrderItem::getCurrency()

public function getCurrency(): string

OrderItem::setCurrency()

public function setCurrency(string $currency)

OrderItem::getGrossPrice()

public function getGrossPrice(): int

OrderItem::getSalePrice()

public function getSalePrice(): int

OrderItem::getSalePricePerUnit()

public function getSalePricePerUnit(): int

OrderItem::getVAT()

public function getVAT(): float

OrderItem::getNetPrice()

public function getNetPrice(): int

OrderItem::getUnitPrice()

public function getUnitPrice(): int

OrderItem::setUnitPrice()

public function setUnitPrice(float|int $unitPrice, ?string $currency = null): self

OrderItem::getDiscountCharge()

public function getDiscountCharge(): int

OrderItem::setDiscountCharge()

public function setDiscountCharge(float|int $discountCharge, ?string $currency = null): self

OrderItem::getVatCharge()

public function getVatCharge(): int

OrderItem::setVatCharge()

public function setVatCharge(float|int $vatCharge, ?string $currency = null): self

OrderItem::getShipments()

public function getShipments(): Collection

OrderItem::addShipment()

public function addShipment(Shipment $shipment): self

OrderItem::removeShipment()

public function removeShipment(Shipment $shipment): self

Pickup class

class Pickup Pickup.php:21

How an order is handed over, when it is not simply posted: collected at the shop on a slot, brought nearby by the shop (a list of postcodes), or sent - and for when, to whom, how far along the shop is. The Order keeps the lines, the prices and the payment; this keeps the rest, one row per order, and a token: /…/{token} follows it without an account.

"Fulfilment" names this in some applications and "Supply" is what is made to order by a supplier (Entity\Order\SupplyJob): hence Pickup.

Pickup::__construct()

public function __construct(Order $order, \DateTimeImmutable $day, PickupMode $mode = PickupMode::PICKUP, ?string $token = null)

Pickup::newToken()

public static function newToken(): string

32 random bytes, URL-safe: nobody guesses a tracking page.

Pickup::getId()

public function getId(): ?int

Pickup::getOrder()

public function getOrder(): Order

Pickup::getToken()

public function getToken(): string

Pickup::getMode()

public function getMode(): PickupMode

Pickup::setMode()

public function setMode(PickupMode $mode): self

Pickup::isPickup()

public function isPickup(): bool

Pickup::isDelivery()

public function isDelivery(): bool

Pickup::isShipping()

public function isShipping(): bool

Pickup::getStatus()

public function getStatus(): PickupStatus

Pickup::setStatus()

public function setStatus(PickupStatus $status): self

Pickup::isAtCheckout()

public function isAtCheckout(): bool

Pickup::isOpen()

public function isOpen(): bool

Pickup::getFlow()

public function getFlow(): array
Returns

the steps of its tracking page

Pickup::getStep()

public function getStep(): int

Where it stands among its steps; -1 once cancelled, refused or refunded.

Pickup::getContactName()

public function getContactName(): ?string

Pickup::setContactName()

public function setContactName(?string $contactName): self

Pickup::getEmail()

public function getEmail(): ?string

Pickup::setEmail()

public function setEmail(?string $email): self

Pickup::getPhone()

public function getPhone(): ?string

Pickup::setPhone()

public function setPhone(?string $phone): self

Pickup::getDay()

public function getDay(): \DateTimeImmutable

Pickup::setDay()

public function setDay(\DateTimeImmutable $day): self

Pickup::getSlot()

public function getSlot(): ?string

Pickup::setSlot()

public function setSlot(?string $slot): self

Pickup::getReadyAt()

public function getReadyAt(): ?\DateTimeImmutable

Pickup::setReadyAt()

public function setReadyAt(?\DateTimeImmutable $readyAt): self

Pickup::getAddress()

public function getAddress(): ?string

Pickup::setAddress()

public function setAddress(?string $address): self

Pickup::getPostcode()

public function getPostcode(): ?string

Pickup::setPostcode()

public function setPostcode(?string $postcode): self

Pickup::getCity()

public function getCity(): ?string

Pickup::setCity()

public function setCity(?string $city): self

Pickup::getCountry()

public function getCountry(): ?string

Pickup::setCountry()

public function setCountry(?string $country): self

Pickup::getNote()

public function getNote(): ?string

Pickup::setNote()

public function setNote(?string $note): self

Pickup::getTrackingNumber()

public function getTrackingNumber(): ?string

Pickup::setTrackingNumber()

public function setTrackingNumber(?string $trackingNumber): self

Pickup::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Shipment class

class Shipment implements IconizeInterface, LinkableInterface Shipment.php:17

Shipment::__toString()

public function __toString()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?string

Shipment::__iconize()

public function __iconize(): ?array

Shipment::__iconizeStatic()

public static function __iconizeStatic(): ?array

Shipment::getId()

public function getId()

Shipment::__construct()

public function __construct()

Shipment::getOrder()

public function getOrder(): ?Order

Shipment::setOrder()

public function setOrder(?Order $order): self

Shipment::getMethod()

public function getMethod(): ?ShippingMethod

Shipment::setMethod()

public function setMethod(?ShippingMethod $method): self

Shipment::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Shipment::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

Shipment::getItems()

public function getItems(): Collection

Shipment::addItem()

public function addItem(OrderItem $item): self

Shipment::removeItem()

public function removeItem(OrderItem $item): self

Shipment::getNumber()

public function getNumber(): ?string

Shipment::setNumber()

public function setNumber(string $number): self

Subscription class

class Subscription implements Stringable Subscription.php:19

A plan paid by subscription: who subscribes, to which plan, through which omnitrade gateway, and the provider's own ids (the subscription, the customer its portal opens for). Its state and the end of the period paid follow the provider's events (Service\Subscriptions); the Entitlements it carries last as long as it runs.

Subscription::__construct()

public function __construct(User $subscriber, string $gateway, string $providerReference, ?Product $product = null, ?Order $order = null)

Subscription::__toString()

public function __toString(): string

Subscription::getId()

public function getId(): ?int

Subscription::getSubscriber()

public function getSubscriber(): ?User

Subscription::getProduct()

public function getProduct(): ?Product

Subscription::setProduct()

public function setProduct(?Product $product): self

Subscription::getOrder()

public function getOrder(): ?Order

Subscription::getGateway()

public function getGateway(): string

Subscription::getProviderReference()

public function getProviderReference(): string

Subscription::getProviderCustomer()

public function getProviderCustomer(): ?string

Subscription::setProviderCustomer()

public function setProviderCustomer(?string $providerCustomer): self

Subscription::getStatus()

public function getStatus(): SubscriptionStatus

Subscription::setStatus()

public function setStatus(SubscriptionStatus $status): self

Subscription::getInterval()

public function getInterval(): string

Subscription::setInterval()

public function setInterval(string $interval): self

Subscription::getCurrentPeriodEnd()

public function getCurrentPeriodEnd(): ?\DateTimeImmutable

Subscription::setCurrentPeriodEnd()

public function setCurrentPeriodEnd(?\DateTimeImmutable $currentPeriodEnd): self

Subscription::isCancelAtPeriodEnd()

public function isCancelAtPeriodEnd(): bool

Subscription::setCancelAtPeriodEnd()

public function setCancelAtPeriodEnd(bool $cancelAtPeriodEnd): self

Subscription::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Subscription::getEndedAt()

public function getEndedAt(): ?\DateTimeImmutable

Subscription::isRunning()

public function isRunning(): bool

What it gives is due now.

SupplyJob class

class SupplyJob implements Stringable SupplyJob.php:15

Part of a paid order handed to a supplier to be made and sent: the lines for one recipient at one supplier, the supplier's reference for it, where it stands and, once it left, its parcel's tracking.

SupplyJob::__construct()

public function __construct(Order $order, string $supplier, string $reference, array $lines, array $recipient)

SupplyJob::__toString()

public function __toString(): string

SupplyJob::getId()

public function getId(): ?int

SupplyJob::getOrder()

public function getOrder(): Order

SupplyJob::getSupplier()

public function getSupplier(): string

SupplyJob::getReference()

public function getReference(): string

SupplyJob::getSupplierReference()

public function getSupplierReference(): ?string

SupplyJob::getStatus()

public function getStatus(): SupplyStatus

SupplyJob::getLines()

public function getLines(): array

SupplyJob::getRecipient()

public function getRecipient(): array

SupplyJob::getTrackingNumber()

public function getTrackingNumber(): ?string

SupplyJob::getTrackingUrl()

public function getTrackingUrl(): ?string

SupplyJob::getCarrier()

public function getCarrier(): ?string

SupplyJob::getMessage()

public function getMessage(): ?string

SupplyJob::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

SupplyJob::getUpdatedAt()

public function getUpdatedAt(): \DateTimeImmutable

SupplyJob::update()

public function update(SupplyStatus $status, ?string $supplierReference = null, ?string $trackingNumber = null, ?string $trackingUrl = null, ?string $carrier = null, ?string $message = null): bool

What the supplier says, kept; true when something moved.

Transaction class

class Transaction implements IconizeInterface Transaction.php:13

Transaction::__iconize()

public function __iconize(): ?array

Transaction::__iconizeStatic()

public static function __iconizeStatic(): ?array

Transaction::__construct()

public function __construct()

Transaction::getNumber()

public function getNumber(): ?string

Transaction::setNumber()

public function setNumber(?string $number): self

Transaction::getDescription()

public function getDescription(): ?string

Transaction::setDescription()

public function setDescription(?string $description): self

Transaction::getClientEmail()

public function getClientEmail(): ?string

Transaction::setClientEmail()

public function setClientEmail(?string $clientEmail): self

Transaction::getClientId()

public function getClientId(): ?string

Transaction::setClientId()

public function setClientId(?string $clientId): self

Transaction::getTotalAmount()

public function getTotalAmount(): int

Transaction::setTotalAmount()

public function setTotalAmount(int $totalAmount): self

Transaction::getCurrencyCode()

public function getCurrencyCode(): ?string

Transaction::setCurrencyCode()

public function setCurrencyCode(?string $currencyCode): self

Transaction::getDetails()

public function getDetails(): array

Transaction::setDetails()

public function setDetails(array $details): self

Transaction::getId()

public function getId()

Transaction::isWaiting()

public function isWaiting()

Transaction::isPaid()

public function isPaid()

Transaction::isRefunded()

public function isRefunded()

Transaction::isCancelled()

public function isCancelled()

Transaction::getState()

public function getState()

Transaction::setState()

public function setState($state): self

Transaction::markAsPaid()

public function markAsPaid()

Transaction::markAsCancelled()

public function markAsCancelled()

Transaction::markAsRefunded()

public function markAsRefunded()

Transaction::getComment()

public function getComment(): ?string

Transaction::setComment()

public function setComment(string $comment): self

Transaction::getWebhook()

public function getWebhook(): ?string

Transaction::setWebhook()

public function setWebhook(?string $webhook): self

Transaction::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Transaction::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

Transaction::getOrder()

public function getOrder(): ?Order

Transaction::setOrder()

public function setOrder(?Order $order): self

Base\Marketplace\Entity\Order\Address

BillingAddress class

class BillingAddress extends Address BillingAddress.php:12

BillingAddress::getOrder()

public function getOrder(): ?Order

BillingAddress::setOrder()

public function setOrder(?Order $order): self

ShippingAddress class

class ShippingAddress extends Address ShippingAddress.php:12

ShippingAddress::getOrder()

public function getOrder(): ?Order

ShippingAddress::setOrder()

public function setOrder(?Order $order): self

Base\Marketplace\Entity\Order\Method

PaymentMethod class

class PaymentMethod implements IconizeInterface PaymentMethod.php:20

PaymentMethod::__toString()

public function __toString()

PaymentMethod::__iconize()

public function __iconize(): ?array

PaymentMethod::__iconizeStatic()

public static function __iconizeStatic(): ?array

PaymentMethod::__construct()

public function __construct()

PaymentMethod::getId()

public function getId()

PaymentMethod::getSlug()

public function getSlug(): ?string

PaymentMethod::setSlug()

public function setSlug(string $slug): self

PaymentMethod::getLabel()

public function getLabel(): ?string

PaymentMethod::setLabel()

public function setLabel(?string $label)

PaymentMethod::getThumbnail()

public function getThumbnail()

PaymentMethod::getThumbnailFile()

public function getThumbnailFile()

PaymentMethod::setThumbnail()

public function setThumbnail($thumbnail)

PaymentMethod::getOrders()

public function getOrders(): Collection

PaymentMethod::addOrder()

public function addOrder(Order $order): self

PaymentMethod::removeOrder()

public function removeOrder(Order $order): self

PaymentMethod::getRefundFee()

public function getRefundFee(): ?Fee

PaymentMethod::setRefundFee()

public function setRefundFee(?Fee $refundFee): self

PaymentMethod::getGatewayFactory()

public function getGatewayFactory(): ?string

PaymentMethod::setGatewayFactory()

public function setGatewayFactory(string $gatewayFactory): self

PaymentMethod::getGatewayConfig()

public function getGatewayConfig(): array

PaymentMethod::getGatewayParameters()

public function getGatewayParameters(): array

The gateway's own settings, from the marketplace.gateways.<slug> parameter.

PaymentMethod::getScopes()

public function getScopes(): Collection

PaymentMethod::addScope()

public function addScope(PaymentMethodScope $scope): self

PaymentMethod::removeScope()

public function removeScope(PaymentMethodScope $scope): self

PaymentMethod::getRules()

public function getRules(): Collection

PaymentMethod::addRule()

public function addRule(PaymentMethodRule $rule): self

PaymentMethod::removeRule()

public function removeRule(PaymentMethodRule $rule): self

ShippingMethod class

class ShippingMethod implements IconizeInterface ShippingMethod.php:21

ShippingMethod::__toString()

public function __toString()

ShippingMethod::__iconize()

public function __iconize(): ?array

ShippingMethod::__iconizeStatic()

public static function __iconizeStatic(): ?array

ShippingMethod::__construct()

public function __construct()

ShippingMethod::getId()

public function getId()

ShippingMethod::getOrders()

public function getOrders(): Collection

ShippingMethod::addOrder()

public function addOrder(Order $order): self

ShippingMethod::removeOrder()

public function removeOrder(Order $order): self

ShippingMethod::getGatewayParameters()

public function getGatewayParameters(): array

ShippingMethod::hasCarrier()

public function hasCarrier(): bool

Whether a carrier takes it: false for a pickup at the shop, the shop's own round.

ShippingMethod::getGatewayName()

public function getGatewayName(): ?string

ShippingMethod::setGatewayName()

public function setGatewayName(?string $gatewayName): self

ShippingMethod::getSlug()

public function getSlug(): ?string

ShippingMethod::setSlug()

public function setSlug(string $slug): self

ShippingMethod::getLabel()

public function getLabel(): ?string

ShippingMethod::setLabel()

public function setLabel(?string $label)

ShippingMethod::getShippingDelay()

public function getShippingDelay(): ?int

ShippingMethod::setShippingDelay()

public function setShippingDelay(?int $shippingDelay): self

ShippingMethod::getDeliveryTime()

public function getDeliveryTime(): ?int

ShippingMethod::setDeliveryTime()

public function setDeliveryTime(?int $deliveryTime): self

ShippingMethod::getThumbnail()

public function getThumbnail()

ShippingMethod::getThumbnailFile()

public function getThumbnailFile()

ShippingMethod::setThumbnail()

public function setThumbnail($thumbnail)

ShippingMethod::getTypeRate()

public function getTypeRate()

ShippingMethod::setTypeRate()

public function setTypeRate($typeRate): self

ShippingMethod::getUnitPrice()

public function getUnitPrice(): ?int

ShippingMethod::setUnitPrice()

public function setUnitPrice(?int $unitPrice): self

ShippingMethod::getCurrency()

public function getCurrency(): ?string

ShippingMethod::setCurrency()

public function setCurrency(string $currency): self

ShippingMethod::getServiceFee()

public function getServiceFee(): ?Fee

ShippingMethod::setServiceFee()

public function setServiceFee(?Fee $serviceFee): self

ShippingMethod::getTrackingUrl()

public function getTrackingUrl(): ?string

ShippingMethod::setTrackingUrl()

public function setTrackingUrl(?string $trackingUrl): self

ShippingMethod::getScopes()

public function getScopes(): Collection

ShippingMethod::addScope()

public function addScope(ShippingMethodScope $scope): self

ShippingMethod::removeScope()

public function removeScope(ShippingMethodScope $scope): self

ShippingMethod::getRules()

public function getRules(): Collection

ShippingMethod::addRule()

public function addRule(ShippingMethodRule $rule): self

ShippingMethod::removeRule()

public function removeRule(ShippingMethodRule $rule): self

Base\Marketplace\Entity\Product

Association class

class Association implements Stringable Association.php:14

One product leading to another on its page: what goes with it (a pairing), what is bought with it (cross-sell), what is better than it (upsell), with a word on why, in each language ("Sur un comté de 24 mois").

Association::__construct()

public function __construct(?Product $product = null, ?Product $target = null, AssociationType $type = AssociationType::PAIRING, array $notes = [])

Association::__toString()

public function __toString(): string

Association::getId()

public function getId(): ?int

Association::getProduct()

public function getProduct(): ?Product

Association::setProduct()

public function setProduct(?Product $product): self

Association::getTarget()

public function getTarget(): ?Product

Association::setTarget()

public function setTarget(?Product $target): self

Association::getType()

public function getType(): AssociationType

Association::setType()

public function setType(AssociationType $type): self

Association::getNotes()

public function getNotes(): array

Association::setNotes()

public function setNotes(array $notes): self

Association::getNote()

public function getNote(?string $locale = null): ?string

The note in this language, else in the first one written.

Association::setNote()

public function setNote(string $locale, ?string $note): self

Association::getPosition()

public function getPosition(): int

Association::setPosition()

public function setPosition(int $position): self

Attribute class

class Attribute extends Attribute implements IconizeInterface Attribute.php:12

Attribute::__iconizeStatic()

public static function __iconizeStatic(): ?array

Attribute::getProduct()

public function getProduct(): ?Product

Attribute::setProduct()

public function setProduct(?Product $product): self

AttributeSet class

class AttributeSet implements Stringable AttributeSet.php:23

The typed sheet of a kind of product, without code: which attributes a product of this taxon has (glitchr/omnibase's attribute adapters: a text, a number with its unit, a choice, a colour...), in which order, which are required and which the list filters on.

A wine's: appellation, region, grapes, colour, alcohol (% vol.), serving temperature (°C), keeping (years), tasting notes - declared in fixtures or in the back office, and its vintages and formats are Variants. A taxon without a set of its own takes its parent's; a set with no taxon is every product's.

AttributeSet::__construct()

public function __construct(string $name = '', ?Taxon $taxon = null)

AttributeSet::__toString()

public function __toString(): string

AttributeSet::getId()

public function getId(): ?int

AttributeSet::getName()

public function getName(): string

AttributeSet::setName()

public function setName(string $name): self

AttributeSet::getTaxon()

public function getTaxon(): ?Taxon

AttributeSet::setTaxon()

public function setTaxon(?Taxon $taxon): self

AttributeSet::getFields()

public function getFields(): Collection

AttributeSet::addField()

public function addField(Field $field): self

AttributeSet::removeField()

public function removeField(Field $field): self

AttributeSet::getFilterableFields()

public function getFilterableFields(): array
Returns

those the list filters on

AttributeSet::getField()

public function getField(string $code): ?Field

The field of this attribute code, if the set has one.

Feature class

class Feature extends Tag implements IconizeInterface Feature.php:18

Feature::__iconizeStatic()

public static function __iconizeStatic(): ?array

Feature::getProducts()

public function getProducts(): Collection

Feature::addProduct()

public function addProduct(Product $product)

Feature::removeProduct()

public function removeProduct(Product $product)

Feature::getImage()

public function getImage()

Feature::getImageFile()

public function getImageFile()

Feature::setImage()

public function setImage($image): self

Identifier class

class Identifier Identifier.php:15

Identifier::__iconize()

public function __iconize(): ?array

Identifier::__iconizeStatic()

public static function __iconizeStatic(): ?array

Identifier::__construct()

public function __construct()

Identifier::getId()

public function getId(): ?int

Identifier::getProduct()

public function getProduct(): ?Product

Identifier::setProduct()

public function setProduct(?Product $product): self

Identifier::getBarcodes()

public function getBarcodes(): Collection

Identifier::getBarcode()

public function getBarcode($std): ?Barcode

Identifier::addBarcode()

public function addBarcode(Barcode $barcode): self

Identifier::removeBarcode()

public function removeBarcode(Barcode $barcode): self

Image class

class Image extends Image implements IconizeInterface Image.php:12

Image::__iconize()

public function __iconize(): ?array

Image::__iconizeStatic()

public static function __iconizeStatic(): ?array

Image::getProduct()

public function getProduct(): ?Product

Image::setProduct()

public function setProduct(?Product $product): self

Option class

class Option implements Stringable Option.php:12

One option of a group: "Bien cuit", "Œuf mollet (+1,50 €)". Its price is what it adds to the product's unit price, in the product's currency and like it before VAT; the product's VAT rate applies to it.

Option::__construct()

public function __construct(string $label = '', int $price = 0, bool $default = false)

Option::__toString()

public function __toString(): string

Option::getId()

public function getId(): ?int

Option::getGroup()

public function getGroup(): ?OptionGroup

Option::setGroup()

public function setGroup(?OptionGroup $group): self

Option::getLabel()

public function getLabel(?string $locale = null): string

Option::setLabel()

public function setLabel(string $label): self

Option::getLabels()

public function getLabels(): array

Option::setLabels()

public function setLabels(array $labels): self

Option::getPrice()

public function getPrice(): int

Option::setPrice()

public function setPrice(int $price): self

Option::isDefault()

public function isDefault(): bool

Option::setDefault()

public function setDefault(bool $default): self

Option::isAvailable()

public function isAvailable(): bool

Option::setAvailable()

public function setAvailable(bool $available): self

Option::getPosition()

public function getPosition(): int

Option::setPosition()

public function setPosition(int $position): self

OptionGroup class

class OptionGroup implements Stringable OptionGroup.php:20

A choice the buyer makes on a product, which is not another product: how it is cooked, what is added, how it is finished. One option of the group (a cooking) or several (extras), between a minimum and a maximum; each option may add to the price. The choices are copied onto the cart line and the order line (OrderItem::$options), their price in the line's.

A variant is another reference with its own stock (a size, a vintage); an option is not: it has neither stock nor page.

OptionGroup::__construct()

public function __construct(string $label = '', bool $multiple = false, int $minimum = 0, ?int $maximum = null)

OptionGroup::__toString()

public function __toString(): string

OptionGroup::getId()

public function getId(): ?int

OptionGroup::getProduct()

public function getProduct(): ?Product

OptionGroup::setProduct()

public function setProduct(?Product $product): self

OptionGroup::getLabel()

public function getLabel(?string $locale = null): string

The label in this language, else the one it was written in.

OptionGroup::setLabel()

public function setLabel(string $label): self

OptionGroup::getLabels()

public function getLabels(): array

OptionGroup::setLabels()

public function setLabels(array $labels): self

OptionGroup::isMultiple()

public function isMultiple(): bool

OptionGroup::setMultiple()

public function setMultiple(bool $multiple): self

OptionGroup::getMinimum()

public function getMinimum(): int

OptionGroup::setMinimum()

public function setMinimum(int $minimum): self

OptionGroup::isRequired()

public function isRequired(): bool

OptionGroup::getMaximum()

public function getMaximum(): ?int

One for a single choice; the group's own for a multiple one (null: no ceiling).

OptionGroup::setMaximum()

public function setMaximum(?int $maximum): self

OptionGroup::getPosition()

public function getPosition(): int

OptionGroup::setPosition()

public function setPosition(int $position): self

OptionGroup::getOptions()

public function getOptions(): Collection

OptionGroup::getAvailableOptions()

public function getAvailableOptions(): array
Returns

those that can be chosen now

OptionGroup::addOption()

public function addOption(Option $option): self

OptionGroup::removeOption()

public function removeOption(Option $option): self

OptionGroup::option()

public function option(string $label, int $price = 0, bool $default = false, array $labels = []): self

Shorthand for fixtures: $group->option('Bien cuit'), ->option('Œuf mollet', 150).

Taxon class

class Taxon extends Taxon Taxon.php:11

Taxon::__iconizeStatic()

public static function __iconizeStatic(): ?array

Taxon::__construct()

public function __construct(?string $label = null, ?string $slug = null, ?Store $store = null)

Taxon::getStore()

public function getStore(): ?Store

Taxon::setStore()

public function setStore(?Store $store): self

Taxon::isAgeRestricted()

public function isAgeRestricted(): bool

Taxon::getAgeRestricted()

public function getAgeRestricted(): bool

Taxon::setAgeRestricted()

public function setAgeRestricted(bool $ageRestricted): self

Variant class

class Variant extends Product implements TranslatableInterface Variant.php:18

Variant::__iconizeStatic()

public static function __iconizeStatic(): ?array

Variant::__construct()

public function __construct(?Product $product = null, int $unitPrice = 0, ?string $currency = null)

Variant::isVariant()

public static function isVariant()

Variant::getPrincipal()

public function getPrincipal(): ?Product

Variant::setPrincipal()

public function setPrincipal(?Product $wallpaper)

Variant::getImage()

public function getImage(?int $i = null, $inheritIfNotSet = !Product::INHERITS_FROM): ?Image

Variant::getImageCrop()

public function getImageCrop(string $slug, ?int $i = null, $inheritIfNotSet = !Product::INHERITS_FROM): ?ImageCrop

Variant::getImages()

public function getImages($inheritIfNotSet = !Product::INHERITS_FROM): Collection

Variant::getImageMarketplaces()

public function getImageMarketplaces($inheritIfNotSet = !Product::INHERITS_FROM)

Variant::getTitle()

public function getTitle(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?string

Variant::getHeadline()

public function getHeadline(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?string

Variant::getExcerpt()

public function getExcerpt(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?string

Variant::getContent()

public function getContent(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?string

Variant::getKeywords()

public function getKeywords(?string $locale = null, int $inheritanceDepthIfNotSet = 1): array

Variant::getStore()

public function getStore(): ?Store

Variant::setStore()

public function setStore(?Store $store)

Variant::getTaxa()

public function getTaxa($inheritIfNotSet = Product::INHERITS_FROM): Collection

Variant::getTags()

public function getTags($inheritIfNotSet = Product::INHERITS_FROM): Collection

Variant::getOwner()

public function getOwner(int $i = 0, $inheritIfNotSet = Product::INHERITS_FROM)

Variant::getOwners()

public function getOwners($inheritIfNotSet = Product::INHERITS_FROM): Collection

Variant::getAuthor()

public function getAuthor(int $i = 0, $inheritIfNotSet = Product::INHERITS_FROM)

Variant::getAuthors()

public function getAuthors($inheritIfNotSet = Product::INHERITS_FROM): Collection

Base\Marketplace\Entity\Product\Attribute

Barcode class

class Barcode extends AbstractAttribute Barcode.php:16

Barcode::__iconizeStatic()

public static function __iconizeStatic(): ?array

Barcode::__construct()

public function __construct(BarcodeAdapter $adapter, mixed $value = null)

Barcode::get()

public function get(?string $locale = null): mixed

Barcode::set()

public function set(...$args): self

Barcode::resolve()

public function resolve(?string $locale = null): mixed

Barcode::getIdentifier()

public function getIdentifier(): ?Identifier

Barcode::setIdentifier()

public function setIdentifier(?Identifier $identifier): self

Barcode::getValue()

public function getValue(): ?string

Barcode::setValue()

public function setValue($value)

Barcode::getAdapter()

public function getAdapter(): ?BarcodeAdapter

Barcode::setAdapter()

public function setAdapter(?AbstractAdapter $adapter): self

Barcode::getStandard()

public function getStandard(): ?string

class Hyperlink extends Hyperlink Hyperlink.php:11

public static function __iconizeStatic(): ?array
public function getProduct(): ?Product
public function setProduct(?Product $product): self

Base\Marketplace\Entity\Product\AttributeSet

Field class

class Field implements Stringable Field.php:15

One attribute of a set: the adapter (its code, its translated label, its type, from glitchr/omnibase), its unit, where it comes, whether a product must have it, whether the list filters on it and how (a choice among the values met, or a range for a number).

const FILTER_CHOICE = 'choice'
const FILTER_RANGE = 'range'

Field::__construct()

public function __construct(?AbstractAdapter $adapter = null, bool $filterable = false, bool $required = false, string $filter = self::FILTER_CHOICE, ?string $unit = null)

Field::__toString()

public function __toString(): string

Field::getId()

public function getId(): ?int

Field::getAttributeSet()

public function getAttributeSet(): ?AttributeSet

Field::setAttributeSet()

public function setAttributeSet(?AttributeSet $attributeSet): self

Field::getAdapter()

public function getAdapter(): ?AbstractAdapter

Field::setAdapter()

public function setAdapter(?AbstractAdapter $adapter): self

Field::getCode()

public function getCode(): ?string

The attribute's code ("appellation"), the key the filters read in the query string.

Field::getPosition()

public function getPosition(): int

Field::setPosition()

public function setPosition(int $position): self

Field::isRequired()

public function isRequired(): bool

Field::setRequired()

public function setRequired(bool $required): self

Field::isFilterable()

public function isFilterable(): bool

Field::setFilterable()

public function setFilterable(bool $filterable): self

Field::getFilter()

public function getFilter(): string

Field::setFilter()

public function setFilter(string $filter): self

Field::getUnit()

public function getUnit(): ?string

Field::setUnit()

public function setUnit(?string $unit): self

Field::isVisible()

public function isVisible(): bool

Field::setVisible()

public function setVisible(bool $visible): self

Base\Marketplace\Entity\Product\Attribute\Adapter

BarcodeAdapter class

class BarcodeAdapter extends AbstractAdapter implements IconizeInterface BarcodeAdapter.php:13

BarcodeAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

BarcodeAdapter::getType()

public static function getType(): string

BarcodeAdapter::getOptions()

public function getOptions(): array

BarcodeAdapter::resolve()

public function resolve(mixed $value): mixed

BarcodeAdapter::getStandard()

public function getStandard()

BarcodeAdapter::setStandard()

public function setStandard($standard): self

Base\Marketplace\Entity\Quote

AbstractQuote class

abstract class AbstractQuote implements Stringable AbstractQuote.php:23

What every quote is, whatever it sells: a client (an account, or an e-mail and a name), their company checked against the State's register, what they asked for, the seller's answer, a status, a discount, a date it holds until, a link only they have (the token).

Each trade gives it its lines and what accepting makes of it: the marketplace's own Quote (products or free lines, by the lot, an Incoterm, a country) and omnibase/forge's (hours at a rate, credited when paid) map this superclass onto their own table.

AbstractQuote::__construct()

public function __construct(string $reference = '')

AbstractQuote::__toString()

public function __toString(): string

AbstractQuote::getLines()

abstract public function getLines(): Collection
Returns

its lines, in order

AbstractQuote::getSubtotal()

abstract public function getSubtotal(): int

Before the discount, in cents.

AbstractQuote::getId()

public function getId(): ?int

AbstractQuote::getReference()

public function getReference(): string

AbstractQuote::setReference()

public function setReference(string $reference): static

AbstractQuote::getToken()

public function getToken(): string

AbstractQuote::getClient()

public function getClient(): ?User

AbstractQuote::setClient()

public function setClient(?User $client): static

AbstractQuote::getSiret()

public function getSiret(): ?string

AbstractQuote::setSiret()

public function setSiret(?string $siret): static

AbstractQuote::getCompany()

public function getCompany(): ?array

AbstractQuote::setCompanyCheck()

public function setCompanyCheck(array $lookup): static

Records the register's answer: FOUND with the company, or why not.

AbstractQuote::setCompanyRecord()

public function setCompanyRecord(?array $company): static

Records a company checked elsewhere (VIES for a foreign one): its name, its number, the source.

AbstractQuote::getCompanyBadge()

public function getCompanyBadge(): ?string

For the back office: verified, closed, unknown, unchecked.

AbstractQuote::getCompanyName()

public function getCompanyName(): ?string

The company's name as the register has it, else null.

AbstractQuote::getEmail()

public function getEmail(): string

AbstractQuote::setEmail()

public function setEmail(string $email): static

AbstractQuote::getContactName()

public function getContactName(): string

AbstractQuote::setContactName()

public function setContactName(string $contactName): static

AbstractQuote::getTitle()

public function getTitle(): string

AbstractQuote::setTitle()

public function setTitle(string $title): static

AbstractQuote::getRequest()

public function getRequest(): ?string

AbstractQuote::setRequest()

public function setRequest(?string $request): static

AbstractQuote::getMessage()

public function getMessage(): ?string

AbstractQuote::setMessage()

public function setMessage(?string $message): static

AbstractQuote::getStatus()

public function getStatus(): QuoteStatus

AbstractQuote::setStatus()

public function setStatus(QuoteStatus $status): static

AbstractQuote::getDiscountPercent()

public function getDiscountPercent(): int

AbstractQuote::setDiscountPercent()

public function setDiscountPercent(int $discountPercent): static

AbstractQuote::getCurrency()

public function getCurrency(): string

AbstractQuote::setCurrency()

public function setCurrency(string $currency): static

AbstractQuote::getValidUntil()

public function getValidUntil(): ?\DateTimeImmutable

AbstractQuote::setValidUntil()

public function setValidUntil(?\DateTimeImmutable $validUntil): static

AbstractQuote::isExpired()

public function isExpired(?\DateTimeImmutable $at = null): bool

AbstractQuote::hasSomethingToSell()

public function hasSomethingToSell(): bool

Whether there is anything to sell in it: a total above zero.

AbstractQuote::isAcceptable()

public function isAcceptable(): bool

Whether the client may accept it now.

AbstractQuote::getDiscountAmount()

public function getDiscountAmount(): int

AbstractQuote::getTotal()

public function getTotal(): int

What the client pays before VAT, in cents.

AbstractQuote::getOrderReference()

public function getOrderReference(): ?string

AbstractQuote::setOrderReference()

public function setOrderReference(?string $orderReference): static

AbstractQuote::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

AbstractQuote::getAcceptedAt()

public function getAcceptedAt(): ?\DateTimeImmutable

AbstractQuote::accept()

public function accept(): static

AbstractQuote::markPaid()

public function markPaid(?string $orderReference = null): static

Paid: the order that paid it named.

QuoteLine class

class QuoteLine implements Stringable QuoteLine.php:16

One line of a quote: a product of the catalogue or a free line (the transport, a label printed for the importer), a number of lots, how many units a lot holds and the price of one lot - "20 cases of 6 at 162 € the case". A line sold by the unit has lots of 1.

QuoteLine::__construct()

public function __construct(?Product $product = null, int $quantity = 1, int $lotPrice = 0, int $lotSize = 1, ?string $label = null)

QuoteLine::__toString()

public function __toString(): string

QuoteLine::getId()

public function getId(): ?int

QuoteLine::getQuote()

public function getQuote(): ?Quote

QuoteLine::setQuote()

public function setQuote(?Quote $quote): self

QuoteLine::getProduct()

public function getProduct(): ?Product

QuoteLine::setProduct()

public function setProduct(?Product $product): self

QuoteLine::isFree()

public function isFree(): bool

QuoteLine::getLabel()

public function getLabel(): string

QuoteLine::setLabel()

public function setLabel(?string $label): self

QuoteLine::getQuantity()

public function getQuantity(): int

QuoteLine::setQuantity()

public function setQuantity(int $quantity): self

QuoteLine::getLotSize()

public function getLotSize(): int

QuoteLine::setLotSize()

public function setLotSize(int $lotSize): self

QuoteLine::getLotPrice()

public function getLotPrice(): int

QuoteLine::setLotPrice()

public function setLotPrice(int $lotPrice): self

QuoteLine::getPosition()

public function getPosition(): int

QuoteLine::setPosition()

public function setPosition(int $position): self

QuoteLine::getUnits()

public function getUnits(): int

How many units the line holds.

QuoteLine::getAmount()

public function getAmount(): int

The line's amount before VAT, in cents.

Base\Marketplace\Entity\Review

Taxon class

class Taxon extends Taxon Taxon.php:11

Taxon::__iconizeStatic()

public static function __iconizeStatic(): ?array

Taxon::__construct()

public function __construct(?string $label = null, ?string $slug = null, ?Store $store = null)

Taxon::getStore()

public function getStore(): ?Store

Taxon::setStore()

public function setStore(?Store $store): self

Base\Marketplace\Entity\Sales

Channel class

class Channel extends Tag implements IconizeInterface Channel.php:16

Channel::__iconizeStatic()

public static function __iconizeStatic(): ?array

Channel::__construct()

public function __construct()

Channel::getProducts()

public function getProducts(): Collection

Channel::addProduct()

public function addProduct(Product $product): self

Channel::removeProduct()

public function removeProduct(Product $product): self

Discount class

class Discount implements IconizeInterface Discount.php:18

Discount::__toString()

public function __toString()

Discount::__construct()

public function __construct()

Discount::__iconize()

public function __iconize(): ?array

Discount::__iconizeStatic()

public static function __iconizeStatic(): ?array

Discount::getId()

public function getId()

Discount::getLabel()

public function getLabel(): ?string

Discount::setLabel()

public function setLabel(?string $label)

Discount::getValidAt()

public function getValidAt(): ?\DateTimeInterface

Discount::setValidAt()

public function setValidAt(?\DateTimeInterface $validAt): self

Discount::getExpiredAt()

public function getExpiredAt(): ?\DateTimeInterface

Discount::setExpiredAt()

public function setExpiredAt(?\DateTimeInterface $expiredAt): self

Discount::getCountOrders()

public function getCountOrders(): int

Discount::setCountOrders()

public function setCountOrders(mixed $countOrder): self

Discount::getOrders()

public function getOrders(): Collection

Discount::addOrder()

public function addOrder(Order $order): self

Discount::removeOrder()

public function removeOrder(Order $order): self

Discount::getRules()

public function getRules(): Collection

Discount::addRule()

public function addRule(DiscountRule $rule): self

Discount::removeRule()

public function removeRule(DiscountRule $rule): self

Discount::getActions()

public function getActions(): Collection

Discount::getFormattedActions()

public function getFormattedActions(): string

Discount::addAction()

public function addAction(DiscountAction $action): self

Discount::removeAction()

public function removeAction(DiscountAction $action): self

Discount::getScopes()

public function getScopes(): Collection

Discount::addScope()

public function addScope(DiscountScope $scope): self

Discount::removeScope()

public function removeScope(DiscountScope $scope): self

Fee class

class Fee implements IconizeInterface Fee.php:16

Fee::__toString()

public function __toString()

Fee::__iconize()

public function __iconize(): ?array

Fee::__iconizeStatic()

public static function __iconizeStatic(): ?array

Fee::__construct()

public function __construct()

Fee::getId()

public function getId()

Fee::getLabel()

public function getLabel(): ?string

Fee::setLabel()

public function setLabel(?string $label)

Fee::getScopes()

public function getScopes(): Collection

Fee::addScope()

public function addScope(FeeScope $scope): self

Fee::removeScope()

public function removeScope(FeeScope $scope): self

Fee::getRules()

public function getRules(): Collection

Fee::addRule()

public function addRule(FeeRule $rule): self

Fee::removeRule()

public function removeRule(FeeRule $rule): self

Fee::getActions()

public function getActions(): Collection

Fee::addAction()

public function addAction(FeeAction $action): self

Fee::removeAction()

public function removeAction(FeeAction $action): self

Forex class

class Forex implements IconizeInterface Forex.php:11

Forex::__iconize()

public function __iconize(): ?array

Forex::__iconizeStatic()

public static function __iconizeStatic(): ?array

Forex::getId()

public function getId()

Forex::getSource()

public function getSource(): ?string

Forex::setSource()

public function setSource(string $source): self

Forex::getTarget()

public function getTarget(): ?string

Forex::setTarget()

public function setTarget(string $target): self

Forex::getProvider()

public function getProvider(): ?string

Forex::getRate()

public function getRate(): ?float

Forex::setProvider()

public function setProvider(?string $provider): self

Forex::setRate()

public function setRate(float $rate, ?string $provider = null): self

The rate, and where it comes from: a provider's name, or null for one set by hand.

Forex::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

Forex::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

Region class

class Region extends Tag implements IconizeInterface Region.php:17

Region::__iconize()

public function __iconize(): ?array

Region::__iconizeStatic()

public static function __iconizeStatic(): ?array

Region::__construct()

public function __construct()

Region::getStores()

public function getStores(): Collection

Region::addStore()

public function addStore(Store $stores): self

Region::removeStore()

public function removeStore(Store $stores): self

Region::getCurrency()

public function getCurrency(): ?string

Region::setCurrency()

public function setCurrency(string $currency): self

Region::isEnabled()

public function isEnabled(): ?bool

Region::setEnabled()

public function setEnabled(bool $enabled): self

Region::getCountries()

public function getCountries(): ?array

Region::setCountries()

public function setCountries(array $countries): self

Region::getOrders()

public function getOrders(): Collection

Region::addOrder()

public function addOrder(Order $order): self

Region::removeOrder()

public function removeOrder(Order $order): self

Tax class

class Tax implements IconizeInterface Tax.php:15

Tax::__iconize()

public function __iconize(): ?array

Tax::__iconizeStatic()

public static function __iconizeStatic(): ?array

Tax::__construct()

public function __construct()

Tax::getId()

public function getId()

Tax::getLabel()

public function getLabel(): ?string

Tax::setLabel()

public function setLabel(?string $label)

Tax::getScopes()

public function getScopes(): Collection

Tax::addScope()

public function addScope(TaxScope $scope): self

(It took a FeeScope and set its fee: copied from Fee, a VAT could not be scoped.)

Tax::removeScope()

public function removeScope(TaxScope $scope): self

Tax::getRate()

public function getRate(): ?float

Tax::setRate()

public function setRate(float $rate): self

Base\Marketplace\Entity\Sales\Attribute

DiscountAction class

class DiscountAction extends AbstractAction DiscountAction.php:12

DiscountAction::get()

public function get(?string $locale = null): mixed

DiscountAction::set()

public function set(...$args): self

DiscountAction::resolve()

public function resolve(?string $locale = null): mixed

DiscountAction::getDiscount()

public function getDiscount(): ?Discount

DiscountAction::setDiscount()

public function setDiscount(?Discount $discount): self

DiscountAction::appliesToItems()

public function appliesToItems(): bool

DiscountRule class

class DiscountRule extends AbstractRule DiscountRule.php:12

DiscountRule::get()

public function get(?string $locale = null): mixed

DiscountRule::set()

public function set(...$args): self

DiscountRule::resolve()

public function resolve(?string $locale = null): mixed

DiscountRule::getDiscount()

public function getDiscount(): ?Discount

DiscountRule::setDiscount()

public function setDiscount(?Discount $discount): self

DiscountScope class

class DiscountScope extends AbstractScope DiscountScope.php:12

DiscountScope::get()

public function get(?string $locale = null): mixed

DiscountScope::set()

public function set(...$args): self

DiscountScope::resolve()

public function resolve(?string $locale = null): mixed

DiscountScope::getDiscount()

public function getDiscount(): ?Discount

DiscountScope::setDiscount()

public function setDiscount(?Discount $discount): self

FeeAction class

class FeeAction extends AbstractAction FeeAction.php:12

FeeAction::get()

public function get(?string $locale = null): mixed

FeeAction::set()

public function set(...$args): self

FeeAction::resolve()

public function resolve(?string $locale = null): mixed

FeeAction::getFee()

public function getFee(): ?Fee

FeeAction::setFee()

public function setFee(?Fee $fee): self

FeeAction::appliesToItems()

public function appliesToItems(): bool

FeeRule class

class FeeRule extends AbstractRule FeeRule.php:12

FeeRule::get()

public function get(?string $locale = null): mixed

FeeRule::set()

public function set(...$args): self

FeeRule::resolve()

public function resolve(?string $locale = null): mixed

FeeRule::getFee()

public function getFee(): ?Fee

FeeRule::setFee()

public function setFee(?Fee $fee): self

FeeScope class

class FeeScope extends AbstractScope FeeScope.php:12

FeeScope::get()

public function get(?string $locale = null): mixed

FeeScope::set()

public function set(...$args): self

FeeScope::resolve()

public function resolve(?string $locale = null): mixed

FeeScope::getFee()

public function getFee(): ?Fee

FeeScope::setFee()

public function setFee(?Fee $fee): self

PaymentMethodRule class

class PaymentMethodRule extends AbstractRule PaymentMethodRule.php:12

PaymentMethodRule::get()

public function get(?string $locale = null): mixed

PaymentMethodRule::set()

public function set(...$args): self

PaymentMethodRule::resolve()

public function resolve(?string $locale = null): mixed

PaymentMethodRule::getPaymentMethod()

public function getPaymentMethod(): ?PaymentMethod

PaymentMethodRule::setPaymentMethod()

public function setPaymentMethod(?PaymentMethod $paymentMethod): self

PaymentMethodScope class

class PaymentMethodScope extends AbstractScope PaymentMethodScope.php:12

PaymentMethodScope::get()

public function get(?string $locale = null): mixed

PaymentMethodScope::set()

public function set(...$args): self

PaymentMethodScope::resolve()

public function resolve(?string $locale = null): mixed

PaymentMethodScope::getPaymentMethod()

public function getPaymentMethod(): ?PaymentMethod

PaymentMethodScope::setPaymentMethod()

public function setPaymentMethod(?PaymentMethod $paymentMethod): self

ShippingMethodRule class

class ShippingMethodRule extends AbstractRule ShippingMethodRule.php:12

ShippingMethodRule::get()

public function get(?string $locale = null): mixed

ShippingMethodRule::set()

public function set(...$args): self

ShippingMethodRule::resolve()

public function resolve(?string $locale = null): mixed

ShippingMethodRule::getShippingMethod()

public function getShippingMethod(): ?ShippingMethod

ShippingMethodRule::setShippingMethod()

public function setShippingMethod(?ShippingMethod $shippingMethod): self

ShippingMethodScope class

class ShippingMethodScope extends AbstractScope ShippingMethodScope.php:12

ShippingMethodScope::get()

public function get(?string $locale = null): mixed

ShippingMethodScope::set()

public function set(...$args): self

ShippingMethodScope::resolve()

public function resolve(?string $locale = null): mixed

ShippingMethodScope::getShippingMethod()

public function getShippingMethod(): ?ShippingMethod

ShippingMethodScope::setShippingMethod()

public function setShippingMethod(?ShippingMethod $shippingMethod): self

TaxScope class

class TaxScope extends AbstractScope TaxScope.php:12

TaxScope::get()

public function get(?string $locale = null): mixed

TaxScope::set()

public function set(...$args): self

TaxScope::resolve()

public function resolve(?string $locale = null): mixed

TaxScope::getTax()

public function getTax(): ?Tax

TaxScope::setTax()

public function setTax(?Tax $tax): self

Base\Marketplace\Entity\Sales\Attribute\Action

FixedAmountAdapter class

class FixedAmountAdapter extends AbstractActionAdapter FixedAmountAdapter.php:16

FixedAmountAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

FixedAmountAdapter::getType()

public static function getType(): string

FixedAmountAdapter::getOptions()

public function getOptions(): array

FixedAmountAdapter::resolve()

public function resolve(mixed $value): mixed

FixedAmountAdapter::apply()

public function apply(mixed $value, mixed $subject): mixed

FixedAmountAdapter::getCurrency()

public function getCurrency(): string

FixedAmountAdapter::setCurrency()

public function setCurrency(string $currency)

FixedAmountAdapter::appliesToItems()

public function appliesToItems(): ?bool

FixedAmountAdapter::setAppliesToItems()

public function setAppliesToItems(bool $appliesToItems): self

PercentageAmountAdapter class

class PercentageAmountAdapter extends AbstractActionAdapter PercentageAmountAdapter.php:14

PercentageAmountAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

PercentageAmountAdapter::getType()

public static function getType(): string

PercentageAmountAdapter::getOptions()

public function getOptions(): array

PercentageAmountAdapter::resolve()

public function resolve(mixed $value): mixed

PercentageAmountAdapter::apply()

public function apply(mixed $value, mixed $subject): mixed

PercentageAmountAdapter::appliesToItems()

public function appliesToItems(): ?bool

PercentageAmountAdapter::setAppliesToItems()

public function setAppliesToItems(bool $appliesToItems): self

Base\Marketplace\Entity\Sales\Attribute\Rule

CartContainsAdapter class

class CartContainsAdapter extends AbstractRuleAdapter CartContainsAdapter.php:13

CartContainsAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

CartContainsAdapter::getType()

public static function getType(): string

CartContainsAdapter::getOptions()

public function getOptions(): array

CartContainsAdapter::resolve()

public function resolve(mixed $value): mixed

CartContainsAdapter::supports()

public function supports(mixed $value): bool

CartContainsAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

CartQuantityAdapter class

class CartQuantityAdapter extends AbstractRuleAdapter CartQuantityAdapter.php:14

CartQuantityAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

CartQuantityAdapter::getType()

public static function getType(): string

CartQuantityAdapter::getOptions()

public function getOptions(): array

CartQuantityAdapter::resolve()

public function resolve(mixed $value): mixed

CartQuantityAdapter::supports()

public function supports(mixed $value): bool

CartQuantityAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

CartQuantityAdapter::getOperation()

public function getOperation()

CartQuantityAdapter::setOperation()

public function setOperation($operation)

TotalPriceAdapter class

class TotalPriceAdapter extends AbstractRuleAdapter TotalPriceAdapter.php:15

TotalPriceAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TotalPriceAdapter::getType()

public static function getType(): string

TotalPriceAdapter::getOptions()

public function getOptions(): array

TotalPriceAdapter::resolve()

public function resolve(mixed $value): mixed

TotalPriceAdapter::supports()

public function supports(mixed $value): bool

TotalPriceAdapter::compliesWith()

public function compliesWith(mixed $value, mixed $subject): bool

TotalPriceAdapter::getCurrency()

public function getCurrency(): string

TotalPriceAdapter::setCurrency()

public function setCurrency(string $currency)

TotalPriceAdapter::getOperation()

public function getOperation()

TotalPriceAdapter::setOperation()

public function setOperation($operation)

Base\Marketplace\Entity\Sales\Attribute\Scope

OrderAdapter class

class OrderAdapter extends AbstractScopeAdapter OrderAdapter.php:13

OrderAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

OrderAdapter::getType()

public static function getType(): string

OrderAdapter::getOptions()

public function getOptions(): array

OrderAdapter::resolve()

public function resolve(mixed $value): mixed

OrderAdapter::supports()

public function supports(mixed $value): bool

OrderAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

ProductAdapter class

class ProductAdapter extends AbstractScopeAdapter ProductAdapter.php:14

ProductAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

ProductAdapter::getType()

public static function getType(): string

ProductAdapter::getOptions()

public function getOptions(): array

ProductAdapter::resolve()

public function resolve(mixed $value): mixed

ProductAdapter::supports()

public function supports(mixed $value): bool

ProductAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

RegionAdapter class

class RegionAdapter extends AbstractScopeAdapter RegionAdapter.php:18

RegionAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

RegionAdapter::getType()

public static function getType(): string

RegionAdapter::getOptions()

public function getOptions(): array

RegionAdapter::resolve()

public function resolve(mixed $value): mixed

RegionAdapter::supports()

public function supports(mixed $value): bool

RegionAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

StoreAdapter class

class StoreAdapter extends AbstractScopeAdapter StoreAdapter.php:17

StoreAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

StoreAdapter::getType()

public static function getType(): string

StoreAdapter::getOptions()

public function getOptions(): array

StoreAdapter::resolve()

public function resolve(mixed $value): mixed

StoreAdapter::supports()

public function supports(mixed $value): bool

StoreAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

The value is stored as JSON: a store id, a slug, or {id: ...} - or a Store when set in memory. Subjects are compared through their store.

TaxonAdapter class

class TaxonAdapter extends AbstractScopeAdapter TaxonAdapter.php:16

TaxonAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

TaxonAdapter::getType()

public static function getType(): string

TaxonAdapter::getOptions()

public function getOptions(): array

TaxonAdapter::resolve()

public function resolve(mixed $value): mixed

TaxonAdapter::supports()

public function supports(mixed $value): bool

TaxonAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

UserAdapter class

class UserAdapter extends AbstractScopeAdapter UserAdapter.php:14

UserAdapter::__iconizeStatic()

public static function __iconizeStatic(): ?array

UserAdapter::getType()

public static function getType(): string

UserAdapter::getOptions()

public function getOptions(): array

UserAdapter::resolve()

public function resolve(mixed $value): mixed

UserAdapter::supports()

public function supports(mixed $value): bool

UserAdapter::contains()

public function contains(mixed $value, mixed $subject): bool

Base\Marketplace\Entity\Sales\Discount

Coupon class

class Coupon extends Discount implements IconizeInterface Coupon.php:14

Coupon::__toString()

public function __toString()

Coupon::__iconize()

public function __iconize(): ?array

Coupon::__iconizeStatic()

public static function __iconizeStatic(): ?array

Coupon::getCode()

public function getCode(): ?string

Coupon::setCode()

public function setCode(string $code): self

Coupon::getQuota()

public function getQuota(): ?int

Coupon::setQuota()

public function setQuota(?int $quota): self

Coupon::getQuotaPerCustomer()

public function getQuotaPerCustomer(): ?int

Coupon::setQuotaPerCustomer()

public function setQuotaPerCustomer(?int $quotaPerCustomer): self

Coupon::isIndividualUse()

public function isIndividualUse(): ?bool

Coupon::setIndividualUse()

public function setIndividualUse(bool $individualUse): self

Coupon::getOwner()

public function getOwner(): ?User

Coupon::setOwner()

public function setOwner(?User $owner): self

Promotion class

class Promotion extends Discount implements IconizeInterface Promotion.php:12

Promotion::__toString()

public function __toString()

Promotion::__iconize()

public function __iconize(): ?array

Promotion::__iconizeStatic()

public static function __iconizeStatic(): ?array

Promotion::getPriority()

public function getPriority(): ?int

Promotion::setPriority()

public function setPriority(int $priority): self

Base\Marketplace\Entity\Sales\Referral

Referral class

class Referral Referral.php:15

Somebody who came through a member's code: the referee (one referral each, for good), where it stands, the order that qualified it, and why it was refused when it was.

Referral::__construct()

public function __construct(ReferralCode $code, User $referee)

Referral::getId()

public function getId(): ?int

Referral::getCode()

public function getCode(): ReferralCode

Referral::getReferrer()

public function getReferrer(): ?User

Referral::getReferee()

public function getReferee(): ?User

Referral::getStatus()

public function getStatus(): ReferralStatus

Referral::getOrderReference()

public function getOrderReference(): ?string

Referral::getFingerprint()

public function getFingerprint(): ?string

Referral::getRejection()

public function getRejection(): ?string

Referral::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Referral::getQualifiedAt()

public function getQualifiedAt(): ?\DateTimeImmutable

Referral::getRewardedAt()

public function getRewardedAt(): ?\DateTimeImmutable

Referral::qualify()

public function qualify(string $orderReference, ?string $fingerprint = null, ?\DateTimeImmutable $at = null): self

Referral::markRewarded()

public function markRewarded(): self

Referral::reject()

public function reject(string $reason): self

self, email, card, cap, refunded, review.

..

ReferralCode class

class ReferralCode implements Stringable ReferralCode.php:10

A member's referral code: one each, the part of the link they share (an application route: /p/{code}).

ReferralCode::__construct()

public function __construct(User $owner, ?string $code = null)

ReferralCode::generate()

public static function generate(int $length = 8): string

ReferralCode::normalize()

public static function normalize(string $code): string

ReferralCode::__toString()

public function __toString(): string

ReferralCode::getId()

public function getId(): ?int

ReferralCode::getOwner()

public function getOwner(): ?User

ReferralCode::getCode()

public function getCode(): string

ReferralCode::isEnabled()

public function isEnabled(): bool

ReferralCode::setEnabled()

public function setEnabled(bool $enabled): self

ReferralCode::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Reward class

class Reward Reward.php:13

What a referral gave: the referee's welcome coupon, the referrer's coupon or credits once the referee's first order held.

const REFEREE = 'referee'
const REFERRER = 'referrer'

Reward::__construct()

public function __construct(Referral $referral, User $beneficiary, string $role, ?\DateTimeImmutable $grantedAt = null)

Reward::getId()

public function getId(): ?int

Reward::getReferral()

public function getReferral(): Referral

Reward::getBeneficiary()

public function getBeneficiary(): ?User

Reward::getRole()

public function getRole(): string

Reward::getCoupon()

public function getCoupon(): ?Coupon

Reward::setCoupon()

public function setCoupon(?Coupon $coupon): self

Reward::getCreditKind()

public function getCreditKind(): ?string

Reward::getCreditQuantity()

public function getCreditQuantity(): ?int

Reward::setCredit()

public function setCredit(string $kind, int $quantity): self

Reward::getGrantedAt()

public function getGrantedAt(): \DateTimeImmutable

Base\Marketplace\Entity\Sales\Tax

Vat class

class Vat extends Tax implements IconizeInterface Vat.php:12

Vat::__iconize()

public function __iconize(): ?array

Vat::__iconizeStatic()

public static function __iconizeStatic(): ?array

Base\Marketplace\Entity\Wishlist

Contribution class

class Contribution Contribution.php:16

Money given to a pot or towards a shared object: the gift (amount), the platform's fee on it (fee), and what the giver is charged - the gift, plus the fee when they chose to cover it. Paid to the list's payout account as a destination charge; the provider's reference is kept to recognise its webhook.

Contribution::__construct()

public function __construct(Item $item, int $amount, string $name, ?string $email = null)

Contribution::getId()

public function getId(): ?int

Contribution::getItem()

public function getItem(): Item

Contribution::getWishlist()

public function getWishlist(): ?Wishlist

Contribution::getReference()

public function getReference(): string

Contribution::getAmount()

public function getAmount(): int

The gift, in minor units.

Contribution::getFee()

public function getFee(): int

Contribution::isFeeCovered()

public function isFeeCovered(): bool

Contribution::setFee()

public function setFee(int $fee, bool $covered): self

Contribution::getCharged()

public function getCharged(): int

What the giver pays: the gift, plus the fee when they cover it.

Contribution::getReceived()

public function getReceived(): int

What the owner receives: the gift, less the fee unless the giver covered it.

Contribution::getCurrency()

public function getCurrency(): string

Contribution::getName()

public function getName(): string

Contribution::getEmail()

public function getEmail(): ?string

Contribution::getMessage()

public function getMessage(): ?string

Contribution::setMessage()

public function setMessage(?string $message): self

Contribution::getGiverReference()

public function getGiverReference(): ?string

Contribution::setGiverReference()

public function setGiverReference(?string $giverReference): self

Contribution::getStatus()

public function getStatus(): ContributionStatus

Contribution::isPaid()

public function isPaid(): bool

Contribution::getGateway()

public function getGateway(): ?string

Contribution::getProviderReference()

public function getProviderReference(): ?string

Contribution::setProvider()

public function setProvider(string $gateway, ?string $reference): self

Contribution::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Contribution::getPaidAt()

public function getPaidAt(): ?\DateTimeImmutable

Contribution::markPaid()

public function markPaid(): self

Contribution::markCancelled()

public function markCancelled(): self

Contribution::markRefunded()

public function markRefunded(): self

Contribution::getRedirectUrl()

public function getRedirectUrl(): ?string

Contribution::setRedirectUrl()

public function setRedirectUrl(?string $redirectUrl): self

Item class

class Item implements Stringable Item.php:20

A wish: an object from any shop - its page's address, what an omnitrade gateway read there (title, picture, price, merchant, the day the price was read), the affiliate link when the shop has a programme -, a product of this shop, or a pot. quantity of an object may be reserved in all; a SHARE's price (times its quantity) is what contributions add up to; a FUND's price, when set, is a goal shown, not a ceiling.

Item::__construct()

public function __construct(string $title = '', WishlistItemKind $kind = WishlistItemKind::OBJECT, ?int $price = null, string $currency = 'EUR')

Item::__toString()

public function __toString(): string

Item::getId()

public function getId(): ?int

Item::getWishlist()

public function getWishlist(): ?Wishlist

Item::setWishlist()

public function setWishlist(?Wishlist $wishlist): self

Item::getKind()

public function getKind(): WishlistItemKind

Item::setKind()

public function setKind(WishlistItemKind $kind): self

Item::getTitle()

public function getTitle(): string

Item::setTitle()

public function setTitle(string $title): self

Item::getDescription()

public function getDescription(): ?string

Item::setDescription()

public function setDescription(?string $description): self

Item::getImageUrl()

public function getImageUrl(): ?string

Item::setImageUrl()

public function setImageUrl(?string $imageUrl): self

Item::getPrice()

public function getPrice(): ?int

Item::setPrice()

public function setPrice(?int $price, ?\DateTimeImmutable $fetchedAt = null): self

Item::getCurrency()

public function getCurrency(): string

Item::setCurrency()

public function setCurrency(string $currency): self

Item::getQuantity()

public function getQuantity(): int

Item::setQuantity()

public function setQuantity(int $quantity): self

Item::getProduct()

public function getProduct(): ?Product

Item::setProduct()

public function setProduct(?Product $product): self

Item::getGateway()

public function getGateway(): ?string

Item::getProductReference()

public function getProductReference(): ?string

Item::setSource()

public function setSource(?string $gateway, ?string $productReference): self

Item::getUrl()

public function getUrl(): ?string

Item::setUrl()

public function setUrl(?string $url): self

Item::getAffiliateUrl()

public function getAffiliateUrl(): ?string

Item::setAffiliateUrl()

public function setAffiliateUrl(?string $affiliateUrl): self

Item::getBuyUrl()

public function getBuyUrl(): ?string

Where a giver is sent to buy it: the affiliate link when there is one.

Item::getMerchant()

public function getMerchant(): ?string

Item::setMerchant()

public function setMerchant(?string $merchant): self

Item::getPriceFetchedAt()

public function getPriceFetchedAt(): ?\DateTimeImmutable

Item::getPosition()

public function getPosition(): int

Item::setPosition()

public function setPosition(int $position): self

Item::isHidden()

public function isHidden(): bool

Item::setHidden()

public function setHidden(bool $hidden): self

Item::getReservations()

public function getReservations(): Collection

Item::getContributions()

public function getContributions(): Collection

Item::getReserved()

public function getReserved(?\DateTimeImmutable $at = null): int

How many are promised or bought.

Item::getAvailable()

public function getAvailable(?\DateTimeImmutable $at = null): int

How many are still to be offered (an object).

Item::getCollected()

public function getCollected(): int

Money given, paid (the givers' gifts, before the platform's fee).

Item::getRemaining()

public function getRemaining(): ?int

What a SHARE still lacks; null for a pot without ceiling or an object.

Item::isFulfilled()

public function isFulfilled(): bool

Nothing more to give: every object reserved, or the share's price reached.

PayoutAccount class

class PayoutAccount implements Stringable PayoutAccount.php:15

Where the money given to somebody's lists goes: their connected account at the provider (a Stripe Express account), opened through Wishlist\PayoutAccounts. The contributions are paid to it directly (destination charges): the platform never holds them.

PayoutAccount::__construct()

public function __construct(User $owner, string $gateway, string $reference, string $country = 'FR')

PayoutAccount::__toString()

public function __toString(): string

PayoutAccount::getId()

public function getId(): ?int

PayoutAccount::getOwner()

public function getOwner(): ?User

PayoutAccount::getGateway()

public function getGateway(): string

PayoutAccount::getReference()

public function getReference(): string

PayoutAccount::getCountry()

public function getCountry(): string

PayoutAccount::isDetailsSubmitted()

public function isDetailsSubmitted(): bool

PayoutAccount::isChargesEnabled()

public function isChargesEnabled(): bool

PayoutAccount::isPayoutsEnabled()

public function isPayoutsEnabled(): bool

PayoutAccount::getRequirements()

public function getRequirements(): array

PayoutAccount::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

PayoutAccount::getCheckedAt()

public function getCheckedAt(): ?\DateTimeImmutable

PayoutAccount::isReady()

public function isReady(): bool

Contributions may be paid to it.

PayoutAccount::update()

public function update(bool $detailsSubmitted, bool $chargesEnabled, bool $payoutsEnabled, array $requirements = []): self

Reservation class

class Reservation Reservation.php:14

Somebody promises an object of a list: it leaves the list for the others, so nothing is given twice. Held until it expires (30 days by default) - unless confirmed as bought - or cancelled with the link sent to its author (only the link's hash is kept).

Reservation::__construct()

public function __construct(Item $item, int $quantity, string $name, ?string $email, string $tokenHash, \DateTimeImmutable $expiresAt)

Reservation::getId()

public function getId(): ?int

Reservation::getItem()

public function getItem(): Item

Reservation::getQuantity()

public function getQuantity(): int

Reservation::getName()

public function getName(): string

Reservation::getEmail()

public function getEmail(): ?string

Reservation::getMessage()

public function getMessage(): ?string

Reservation::setMessage()

public function setMessage(?string $message): self

Reservation::getGiverReference()

public function getGiverReference(): ?string

Reservation::setGiverReference()

public function setGiverReference(?string $giverReference): self

Reservation::getStatus()

public function getStatus(): ReservationStatus

Reservation::setStatus()

public function setStatus(ReservationStatus $status): self

Reservation::getTokenHash()

public function getTokenHash(): string

Reservation::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Reservation::getExpiresAt()

public function getExpiresAt(): \DateTimeImmutable

Reservation::holds()

public function holds(?\DateTimeImmutable $at = null): bool

It keeps the object off the list at that moment.

Wishlist class

class Wishlist implements Stringable Wishlist.php:24

A list of wishes: a wedding's or a birthday's gifts, a birth list, a fund. Its owner keeps it; it may belong to something of the application's (an event: Model\WishlistHolderInterface). Its items are objects from any shop (read through glitchr/omnitrade from their page), products of this shop, or pots; those who give reserve an object or contribute money, paid straight to the owner's payout account.

surprise: the owner sees that a wish is taken or how much a pot holds, not by whom - until they choose to look (a birth list's default).

Wishlist::__construct()

public function __construct(User $owner, string $title, WishlistKind $kind = WishlistKind::GIFTS, ?WishlistHolderInterface $holder = null)

Wishlist::__toString()

public function __toString(): string

Wishlist::getId()

public function getId(): ?int

Wishlist::getToken()

public function getToken(): string

Wishlist::getOwner()

public function getOwner(): ?User

Wishlist::getHolderType()

public function getHolderType(): ?string

Wishlist::getHolderId()

public function getHolderId(): ?string

Wishlist::setHolder()

public function setHolder(?WishlistHolderInterface $holder): self

Wishlist::getTitle()

public function getTitle(): string

Wishlist::setTitle()

public function setTitle(string $title): self

Wishlist::getMessage()

public function getMessage(): ?string

Wishlist::setMessage()

public function setMessage(?string $message): self

Wishlist::getKind()

public function getKind(): WishlistKind

Wishlist::setKind()

public function setKind(WishlistKind $kind): self

Wishlist::isSurprise()

public function isSurprise(): bool

Wishlist::setSurprise()

public function setSurprise(bool $surprise): self

Wishlist::getCurrency()

public function getCurrency(): string

Wishlist::setCurrency()

public function setCurrency(string $currency): self

Wishlist::getShippingAddress()

public function getShippingAddress(): ?string

Wishlist::setShippingAddress()

public function setShippingAddress(?string $shippingAddress): self

Wishlist::getPayoutAccount()

public function getPayoutAccount(): ?PayoutAccount

Wishlist::setPayoutAccount()

public function setPayoutAccount(?PayoutAccount $payoutAccount): self

Wishlist::isGiverMayCoverFees()

public function isGiverMayCoverFees(): bool

Wishlist::setGiverMayCoverFees()

public function setGiverMayCoverFees(bool $giverMayCoverFees): self

Wishlist::isOpen()

public function isOpen(): bool

Wishlist::setOpen()

public function setOpen(bool $open): self

Wishlist::getCreatedAt()

public function getCreatedAt(): \DateTimeImmutable

Wishlist::takesContributions()

public function takesContributions(): bool

Money may be given: open, and a payout account ready to receive it.

Wishlist::getItems()

public function getItems(): Collection

Wishlist::addItem()

public function addItem(Item $item): self

Wishlist::removeItem()

public function removeItem(Item $item): self

Wishlist::getCollected()

public function getCollected(): int

Everything given in money, paid.

Base\Marketplace\Enum

AssociationType enum

enum AssociationType AssociationType.php:6

How one product leads to another on its page.

case PAIRING = 'pairing'

Goes with it: a dish for a wine, a cheese for a sake.

case CROSS_SELL = 'cross_sell'

Bought with it: a carafe, glasses, another vintage.

case UPSELL = 'upsell'

Better than it: the grand vin above the second wine.

Barcode class

class Barcode extends EnumType implements IconizeInterface Barcode.php:11

const UPC = 'UPC'
const EAN = 'EAN'
const GTIN = 'GTIN'
const ISBN = 'ISBN'
const SKU = 'SKU'
const ASIN = 'ASIN'
const GCID = 'GCID'
const FNSKU = 'FNSKU'
const EPID = 'EPID'
const GLN = 'GLN'
const LINEAR = 'BARCODE'
const QRCODE = 'QRCODE'
const DATAMATRIX = 'DATAMATRIX'
const DOTCODE = 'DOTCODE'

Barcode::__iconize()

public function __iconize(): ?array

Barcode::__iconizeStatic()

public static function __iconizeStatic(): ?array

ContributionStatus enum

enum ContributionStatus ContributionStatus.php:5

case PENDING = 'pending'
case PAID = 'paid'
case CANCELLED = 'cancelled'
case REFUNDED = 'refunded'

Incoterm enum

enum Incoterm Incoterm.php:10

Who pays the transport and bears the risk, and up to where (Incoterms® 2020) - the six a trade quote meets most. The quote names the place after it: "FOB Le Havre", "DAP Tokyo".

case EXW = 'EXW'

Ex Works: the buyer collects at the seller's cellar.

case FCA = 'FCA'

Free Carrier: handed to the buyer's carrier, export cleared.

case FOB = 'FOB'

Free On Board: loaded on the ship at the port of departure.

case CIF = 'CIF'

Cost, Insurance and Freight: the seller pays sea freight and insurance to the port of arrival.

case DAP = 'DAP'

Delivered At Place: delivered at the named place, import duties left to the buyer.

case DDP = 'DDP'

Delivered Duty Paid: delivered, import duties and taxes paid by the seller.

Incoterm::sellerShips()

public function sellerShips(): bool

Whether the seller arranges (and prices) the main carriage.

OrderState class

class OrderState extends EnumType implements IconizeInterface, ColorizeInterface OrderState.php:12

const CART = 'ORDER_CART'
const ABANDON = 'ORDER_CART_ABANDON'
const ARCHIVE = 'ORDER_ARCHIVE'
const PENDING = 'ORDER_PENDING'
const CONFIRM = 'ORDER_CONFIRM'
const CONFIRM_PARTIAL = 'ORDER_CONFIRM_PARTIAL'
const PROCESSING = 'ORDER_PROCESSING'
const DELAYED = 'ORDER_DELAYED'
const CANCEL = 'ORDER_CANCEL'
const SHIPPED = 'ORDER_SHIPPED'
const COMPLETE = 'ORDER_COMPLETE'
const REVIEWED = 'ORDER_COMPLETE_REVIEW'
const REFUND = 'ORDER_REFUND'
const RETURNING = 'ORDER_RETURNING'
const RETURN_PARTIAL = 'ORDER_RETURN_PARTIAL'
const RETURN_RECEIVED = 'ORDER_RETURN_RECEIVED'

OrderState::__iconize()

public function __iconize(): ?array

OrderState::__iconizeStatic()

public static function __iconizeStatic(): ?array

OrderState::__colorize()

public function __colorize(): ?array

OrderState::__colorizeStatic()

public static function __colorizeStatic(): ?array

PaymentState class

class PaymentState extends EnumType implements IconizeInterface PaymentState.php:11

const AWAITING = 'PAYMENT_AWAITING'
const CANCEL = 'PAYMENT_CANCEL'
const AUTHORIZE_PARTIAL = 'PAYMENT_AUTHORIZE_PARTIAL'
const AUTHORIZE = 'PAYMENT_AUTHORIZE'
const PAID_PARTIAL = 'PAYMENT_PAID_PARTIAL'
const PAID = 'PAYMENT_PAID'
const REFUND_PARTIAL = 'PAYMENT_REFUND_PARTIAL'
const REFUND = 'PAYMENT_REFUND'

PaymentState::__iconize()

public function __iconize(): ?array

PaymentState::__iconizeStatic()

public static function __iconizeStatic(): ?array

PickupMode enum

enum PickupMode PickupMode.php:6

How an order is handed over: collected at the shop on a slot, brought nearby by the shop itself, or sent by a carrier.

case PICKUP = 'pickup'
case DELIVERY = 'delivery'
case SHIPPING = 'shipping'

PickupMode::trans()

public function trans(): string

PickupMode::needsAddress()

public function needsAddress(): bool

Whether somebody travels to the customer: an address is needed.

PickupStatus enum

enum PickupStatus PickupStatus.php:11

Where a hand-over stands, in the order the shop moves it along:

checkout ─▶ received ─▶ accepted ─▶ preparing ─▶ ready ─▶ (out_for_delivery) ─▶ done └─▶ refused └── cancelled | refunded, from anywhere before done

case CHECKOUT = 'checkout'

The order exists, its payment has not come yet.

case RECEIVED = 'received'

Paid (or placed): waiting for the shop's word.

case ACCEPTED = 'accepted'
case PREPARING = 'preparing'
case READY = 'ready'
case OUT_FOR_DELIVERY = 'out_for_delivery'

On its way: the shop's own round, or the carrier's.

case DONE = 'done'
case CANCELLED = 'cancelled'
case REFUSED = 'refused'
case REFUNDED = 'refunded'

PickupStatus::flow()

public static function flow(PickupMode $mode = PickupMode::PICKUP): array
Returns

the steps a tracking page shows, for this mode

PickupStatus::isOpen()

public function isOpen(): bool

PickupStatus::trans()

public function trans(): string

ProductAvailability class

class ProductAvailability extends EnumType implements IconizeInterface ProductAvailability.php:11

const PREORDER = 'AVAL_PREORDER'
const PRESALE = 'AVAL_PRESALE'
const INSTOCK = 'AVAL_INSTOCK'
const SOLDOUT = 'AVAL_SOLDOUT'
const LIMITED = 'AVAL_LIMITED'
const OUT_OF_STOCK = 'AVAL_OUT_OF_STOCK'
const BACKORDER = 'AVAL_BACKORDER'
const DISCONTINUED = 'AVAL_DISCONTINUED'
const INSTORE_ONLY = 'AVAL_INSTORE_ONLY'
const ONLINE_ONLY = 'AVAL_ONLINE_ONLY'

ProductAvailability::__iconize()

public function __iconize(): ?array

ProductAvailability::__iconizeStatic()

public static function __iconizeStatic(): ?array

ProductKind enum

enum ProductKind ProductKind.php:14

What a product is, for what happens once it is paid:

GOODS something delivered or downloaded (the default); PLAN a right of access - a pass bought once or a subscription -: paid, it grants an Entitlement (Model\PlanTerms says which); CREDIT_PACK units to spend later (answers of an assistant, hours, stationery): paid, it credits the buyer's ledger.

case GOODS = 'goods'
case PLAN = 'plan'
case CREDIT_PACK = 'credit_pack'

QuoteStatus enum

enum QuoteStatus QuoteStatus.php:16

A quote's life, the same for every trade (a négociant's export offer, a studio's hours):

requested a visitor asked for one (the quote form); nothing priced yet draft the seller is writing the lines sent the client can read and accept it accepted the client said yes: an order waits for payment paid the order was paid declined the client said no, or it lapsed

case REQUESTED = 'requested'
case DRAFT = 'draft'
case SENT = 'sent'
case ACCEPTED = 'accepted'
case PAID = 'paid'
case DECLINED = 'declined'

QuoteStatus::isOpenToClient()

public function isOpenToClient(): bool

QuoteStatus::isEditable()

public function isEditable(): bool

The seller may still change the lines and send it (again).

QuoteStatus::pipeline()

public static function pipeline(): array
Returns

in the order of the pipeline's columns

ReferralStatus enum

enum ReferralStatus ReferralStatus.php:5

case PENDING = 'pending'

The referee signed up through the code; nothing bought yet.

case QUALIFIED = 'qualified'

Their first order is paid: the referrer's reward waits for the cooling-off period.

case REWARDED = 'rewarded'

The referrer was rewarded.

case REJECTED = 'rejected'

Refused: an abuse (the same person, the same card), the month's ceiling, a refund, a review.

ReservationStatus enum

enum ReservationStatus ReservationStatus.php:5

case HELD = 'held'

Promised: nobody else may take it, until it expires.

case CONFIRMED = 'confirmed'

Bought: it no longer expires.

case CANCELLED = 'cancelled'
case EXPIRED = 'expired'

ReservationStatus::holds()

public function holds(): bool

It keeps the object off the list.

ShippingRate class

class ShippingRate extends EnumType implements IconizeInterface ShippingRate.php:9

How a shipping method prices a parcel: one flat rate, priority, or international.

const FLAT_RATE = 'RATE_FLAT'
const PRIORITY_RATE = 'RATE_PRIORITY'
const INTERNATIONAL_RATE = 'RATE_INTERNATIONAL'

ShippingRate::__iconize()

public function __iconize(): ?array

ShippingRate::__iconizeStatic()

public static function __iconizeStatic(): ?array

SubscriptionStatus enum

enum SubscriptionStatus SubscriptionStatus.php:6

Where a subscription stands; the values are glitchr/omnitrade's (Model\Subscription).

case INCOMPLETE = 'incomplete'
case TRIALING = 'trialing'
case ACTIVE = 'active'
case PAST_DUE = 'past_due'
case UNPAID = 'unpaid'
case PAUSED = 'paused'
case CANCELLED = 'cancelled'

SubscriptionStatus::isRunning()

public function isRunning(): bool

What it gives is due.

SupplyStatus enum

enum SupplyStatus SupplyStatus.php:6

Where something made to order stands at its supplier.

case DRAFT = 'draft'

Sent as a draft: priced, checked, not launched.

case SUBMITTED = 'submitted'

Sent; the supplier has not answered yet.

case ACCEPTED = 'accepted'
case IN_PRODUCTION = 'in_production'
case SHIPPED = 'shipped'
case DELIVERED = 'delivered'
case CANCELLED = 'cancelled'
case FAILED = 'failed'

Refused by the supplier, or could not be sent: its message says why.

SupplyStatus::isFinal()

public function isFinal(): bool

TradeDirection enum

enum TradeDirection TradeDirection.php:6

Which way the goods of a trade quote travel, seen from the seller.

case EXPORT = 'export'

From the seller's country to the buyer's (Bordeaux → Tokyo).

case IMPORT = 'import'

From abroad to the buyer, the seller sourcing (Japanese sake for a Paris restaurant).

case DOMESTIC = 'domestic'

Within the seller's country, or within the EU.

WishlistItemKind enum

enum WishlistItemKind WishlistItemKind.php:14

How a wish is fulfilled:

OBJECT somebody reserves it and buys it themselves, at the shop it comes from (or in this shop when it is one of its products); SHARE an object too dear for one: several contribute money towards its price, until it is reached; FUND a pot with no ceiling (or a goal): each gives what they want.

case OBJECT = 'object'
case SHARE = 'share'
case FUND = 'fund'

WishlistItemKind::takesMoney()

public function takesMoney(): bool

WishlistKind enum

enum WishlistKind WishlistKind.php:6

What a list is for: gifts wished for (a wedding, a birthday), a birth list, or a fund alone (a honeymoon).

case GIFTS = 'gifts'
case BIRTH = 'birth'
case FUND = 'fund'

Base\Marketplace\Event

CatalogueNotificationEvent class

final class CatalogueNotificationEvent extends Event CatalogueNotificationEvent.php:14

A platform said a product or a stock level changed (its webhook, read by the omnitrade gateway): Catalogue\CatalogueNotificationListener brings it in when the catalogue is read from that gateway. The outcome is what the webhook answers.

public readonly string $gateway
public readonly Notification $notification

CatalogueNotificationEvent::__construct()

public function __construct(public readonly string $gateway, public readonly Notification $notification)

CatalogueNotificationEvent::getOutcome()

public function getOutcome(): ?string

CatalogueNotificationEvent::setOutcome()

public function setOutcome(string $outcome): void

ContributionPaidEvent class

final class ContributionPaidEvent extends Event ContributionPaidEvent.php:9

A contribution has just been paid: dispatched once. The application thanks, notes the gift, tells the owner.

public readonly Contribution $contribution

ContributionPaidEvent::__construct()

public function __construct(public readonly Contribution $contribution)

ContributionPreparingEvent class

final class ContributionPreparingEvent extends Event ContributionPreparingEvent.php:15

A contribution is about to be paid: the platform's fee on it is marketplace.wishlist.fee_rate of the gift plus fee_fixed, unless a listener says otherwise ($fee, in minor units) - a rate that depends on the owner's plan, say. $metadata goes to the provider and comes back on its webhooks.

public readonly Contribution $contribution
public int $fee
public array $metadata
public ?string $description

ContributionPreparingEvent::__construct()

public function __construct(public readonly Contribution $contribution, public int $fee, public array $metadata = [], public ?string $description = null)

EntitlementEndedEvent class

final class EntitlementEndedEvent extends Event EntitlementEndedEvent.php:13

A right has ended - a pass run out, a subscription stopped: dispatched once per entitlement by marketplace:subscriptions. The application closes what it had opened (an archive in read-only, an export offered).

public readonly Entitlement $entitlement

EntitlementEndedEvent::__construct()

public function __construct(public readonly Entitlement $entitlement)

EntitlementEndingEvent class

final class EntitlementEndingEvent extends Event EntitlementEndingEvent.php:9

A right ends within marketplace.plans.reminder_days: dispatched once, for the application to tell its holder.

public readonly Entitlement $entitlement

EntitlementEndingEvent::__construct()

public function __construct(public readonly Entitlement $entitlement)

EntitlementGrantedEvent class

final class EntitlementGrantedEvent extends Event EntitlementGrantedEvent.php:10

A right has just been granted - a plan paid, a gift made: the application opens what it opens.

public readonly Entitlement $entitlement
public readonly ?Order $order

EntitlementGrantedEvent::__construct()

public function __construct(public readonly Entitlement $entitlement, public readonly ?Order $order = null)

OrderPaidEvent class

final class OrderPaidEvent extends Event OrderPaidEvent.php:13

An order has just been paid in full. The place for an application to deliver what does not ship: unlock a download, credit an account, put an item in a wardrobe. Dispatched once, after the flush that marked it paid.

public readonly Order $order

OrderPaidEvent::__construct()

public function __construct(public readonly Order $order)

PaymentCancelledEvent class

final class PaymentCancelledEvent extends Event PaymentCancelledEvent.php:20

A payment did not happen - the member turned back on the provider's page, or the provider let it expire - and the order is back to being a cart.

Dispatched by Checkout::cancel() after that flush.

An application that started the payment for a purpose of its own (an order it never meant as a cart) can undo it here, and, when the member is coming back through the return page, say where they land: setResponse(). The webhook ignores the response.

public readonly Order $order
public readonly Transaction $transaction

PaymentCancelledEvent::__construct()

public function __construct(public readonly Order $order, public readonly Transaction $transaction)

PaymentCancelledEvent::getResponse()

public function getResponse(): ?Response

PaymentCancelledEvent::setResponse()

public function setResponse(?Response $response): void

PaymentNotificationEvent class

final class PaymentNotificationEvent extends Event PaymentNotificationEvent.php:15

A provider's webhook that is not about an order's payment nor the catalogue: a connected account updated, a subscription renewed or ended, a payment the marketplace's orders do not know (a contribution to a list, an application's own). Whoever it concerns says so (setOutcome), which ends the round.

public readonly string $gateway

The omnitrade gateway's name.

public readonly Notification $notification

PaymentNotificationEvent::__construct()

public function __construct(public readonly string $gateway, public readonly Notification $notification)

PaymentNotificationEvent::getOutcome()

public function getOutcome(): ?string

PaymentNotificationEvent::setOutcome()

public function setOutcome(string $outcome): void

PaymentPreparingEvent class

final class PaymentPreparingEvent extends Event PaymentPreparingEvent.php:24

An order is about to be handed to a glitchr/omnitrade gateway: the last moment to say how. A listener may

  • send the money to a connected account (Stripe Connect) and keep a fee: $destination ("acct_..."), $applicationFee (minor units, within the order's net price);
  • make it a subscription: $interval (day, week, month, year), $intervalCount, $price (a price kept at the provider), $trialDays, $customer (the provider's customer when the buyer already is one) - the bridge sets these itself for an order of one recurring plan;
  • add metadata the provider keeps and gives back on its webhooks, change the description shown on its page, its language.
public ?string $destination = null
public ?int $applicationFee = null
public ?string $interval = null
public int $intervalCount = 1
public ?string $price = null
public ?int $trialDays = null
public ?string $customer = null
public readonly Order $order
public readonly Transaction $transaction
public readonly PaymentMethod $method
public readonly string $gateway

The omnitrade gateway's name.

public array $metadata
public ?string $description
public ?string $locale

PaymentPreparingEvent::__construct()

public function __construct(public readonly Order $order, public readonly Transaction $transaction, public readonly PaymentMethod $method, public readonly string $gateway, public array $metadata = [], public ?string $description = null, public ?string $locale = null)

PaymentPreparingEvent::isSubscription()

public function isSubscription(): bool

PickupChangedEvent class

final class PickupChangedEvent extends Event PickupChangedEvent.php:14

A hand-over moved (Service\Pickups::move()): received once its order is paid, accepted, ready, done... The application tells the customer, the kitchen, the driver. $previous is null when it was just opened.

public readonly Pickup $pickup
public readonly ?PickupStatus $previous

PickupChangedEvent::__construct()

public function __construct(public readonly Pickup $pickup, public readonly ?PickupStatus $previous = null)

QuickOrderDoneEvent class

final class QuickOrderDoneEvent extends Event QuickOrderDoneEvent.php:15

The page of a quick order is about to be shown to the holder of its link (Service\QuickOrder::doneUrl()). An application that delivers something there - files to download, a ticket - sets its own response; without one, the bundle shows the order (@Marketplace/client/quick_done.html.twig).

public readonly Order $order

QuickOrderDoneEvent::__construct()

public function __construct(public readonly Order $order)

QuickOrderDoneEvent::getResponse()

public function getResponse(): ?Response

QuickOrderDoneEvent::setResponse()

public function setResponse(?Response $response): void

ReferralQualifyingEvent class

final class ReferralQualifyingEvent extends Event ReferralQualifyingEvent.php:15

A referee's first order is paid: before the referral qualifies, a listener may refuse it ($rejection: a reason of its own) or tell what the order was paid with ($fingerprint: the card's, as the provider gives it) so the same card as the referrer's is refused.

public ?string $rejection = null
public readonly Referral $referral
public readonly Order $order
public ?string $fingerprint

ReferralQualifyingEvent::__construct()

public function __construct(public readonly Referral $referral, public readonly Order $order, public ?string $fingerprint = null)

ReferralRewardedEvent class

final class ReferralRewardedEvent extends Event ReferralRewardedEvent.php:9

A reward was granted (the referee's welcome, the referrer's thanks): the application tells its beneficiary.

public readonly Reward $reward

ReferralRewardedEvent::__construct()

public function __construct(public readonly Reward $reward)

SubscriptionChangedEvent class

final class SubscriptionChangedEvent extends Event SubscriptionChangedEvent.php:10

A subscription's state moved (renewed, past due, set to stop, ended), as the provider told.

public readonly Subscription $subscription
public readonly ?SubscriptionStatus $previous

SubscriptionChangedEvent::__construct()

public function __construct(public readonly Subscription $subscription, public readonly ?SubscriptionStatus $previous = null)

SupplyJobChangedEvent class

final class SupplyJobChangedEvent extends Event SupplyJobChangedEvent.php:10

A supplier's job moved (accepted, in production, shipped with its tracking, failed): the application tells the buyer.

public readonly SupplyJob $job
public readonly ?SupplyStatus $previous

SupplyJobChangedEvent::__construct()

public function __construct(public readonly SupplyJob $job, public readonly ?SupplyStatus $previous = null)

Base\Marketplace\EventListener

InvoiceOnPaymentListener class

final class InvoiceOnPaymentListener InvoiceOnPaymentListener.php:17

marketplace.invoice.auto_issue: an order's invoice issued as soon as it is paid. An invoice that cannot be issued (the seller not configured, a database that fails) does not undo the payment: it is said in the log, and the back office issues it.

InvoiceOnPaymentListener::__construct()

public function __construct(readonly Invoices $invoices, readonly bool $autoIssue = false, readonly ?LoggerInterface $logger = null)

InvoiceOnPaymentListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

PickupPaidListener class

final class PickupPaidListener PickupPaidListener.php:11

An order with a hand-over is paid: the shop has received it (saved with the confirmation's own flush).

PickupPaidListener::__construct()

public function __construct(readonly Pickups $pickups)

PickupPaidListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

PlanPurchaseListener class

final class PlanPurchaseListener PlanPurchaseListener.php:20

An order is paid: each plan in it becomes an Entitlement of its buyer (its grants, until its months run out - or, bought by subscription, as long as the Subscription created here runs), its credits are credited, and each credit pack credits its kinds, times the quantity bought.

PlanPurchaseListener::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Entitlements $entitlements, readonly Credits $credits)

PlanPurchaseListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

PlanPurchaseListener::code()

public static function code(\Base\Marketplace\Entity\Product $product): string

A plan's code: its principal's slug for a variant (the pass, whatever its size), else its own.

QuickOrderReturnListener class

final class QuickOrderReturnListener QuickOrderReturnListener.php:17

A buyer back from the payment provider lands on marketplace_payment_return, which sends anyone who is not the signed-in customer to the basket. A quick order has nobody signed in: when the order is one this visitor made (its id is in their session), the request goes to QuickOrderController::Back() instead - same URL, its own ending.

QuickOrderReturnListener::__invoke()

public function __invoke(RequestEvent $event): void

QuotePaidListener class

final class QuotePaidListener QuotePaidListener.php:11

A quote's order is paid: the quote is marked paid, the order named on it.

QuotePaidListener::__construct()

public function __construct(readonly EntityManagerInterface $entityManager)

QuotePaidListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

ReferralListener class

final class ReferralListener ReferralListener.php:10

An order is paid: a referee's first one qualifies their referral.

ReferralListener::__construct()

public function __construct(readonly Referrals $referrals)

ReferralListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

SubscriptionNotificationListener class

final class SubscriptionNotificationListener SubscriptionNotificationListener.php:10

A subscription's event from a provider's webhook: applied to the Subscription kept here.

SubscriptionNotificationListener::__construct()

public function __construct(readonly Subscriptions $subscriptions)

SubscriptionNotificationListener::__invoke()

public function __invoke(PaymentNotificationEvent $event): void

SupplyListener class

final class SupplyListener SupplyListener.php:14

An order is paid: what in it is made to order goes to its suppliers.

After the listeners that deliver rights (priority below theirs): a supplier's failure is kept on its job, never thrown.

SupplyListener::__construct()

public function __construct(readonly Supply $supply)

SupplyListener::__invoke()

public function __invoke(OrderPaidEvent $event): void

WishlistNotificationListener class

final class WishlistNotificationListener WishlistNotificationListener.php:15

The lists' share of a provider's webhooks: a payout account updated (its holder finished the onboarding, the provider asks for more), a contribution's payment completed or expired.

WishlistNotificationListener::__construct()

public function __construct(readonly Contributions $contributions, readonly PayoutAccounts $accounts)

WishlistNotificationListener::__invoke()

public function __invoke(PaymentNotificationEvent $event): void

Base\Marketplace\Form

AssociationType class

class AssociationType extends AbstractType AssociationType.php:16

One pairing, cross-sell or upsell of a product in the back office, with its note in each language of the site.

AssociationType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

AssociationType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

AttributeSetFieldType class

class AttributeSetFieldType extends AbstractType AttributeSetFieldType.php:15

One attribute of a set in the back office: which, required, filtered on and how, shown.

AttributeSetFieldType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

AttributeSetFieldType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

ProductOptionType class

class ProductOptionType extends AbstractType ProductOptionType.php:14

One option of a group in the back office: its label, what it adds to the price (cents, before VAT), preselected, available.

ProductOptionType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

ProductOptionType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

QuickOrderType class

class QuickOrderType extends AbstractType QuickOrderType.php:25

A product bought in one step (Service\QuickOrder): the buyer's e-mail address - none for a member signed in, the order is theirs - and where to come back to. Public, with no account: guarded as glitchr/omnibase guards a form (its option guard, action "quick_order": a trap, the time it takes, the lists, the captcha when the site has glitchr/omnishield); a form's own trap only where the host's core is from before the guard.

Printed by @Marketplace/client/_quick_order.html.twig, which asks marketplace_quick_order_form() for it.

const NAME = 'quick_order'

QuickOrderType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

QuickOrderType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

QuickOrderType::getBlockPrefix()

public function getBlockPrefix(): string

QuoteLineType class

class QuoteLineType extends AbstractType QuoteLineType.php:15

One line of a quote in the back office: a product or a free label, lots, units per lot, the price of a lot (cents).

QuoteLineType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

QuoteLineType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

QuoteRequestType class

class QuoteRequestType extends AbstractType QuoteRequestType.php:34

What a professional fills in to ask for a quote: who, which company (checked: a SIRET at the State's register, an EU VAT number at VIES), what, which way, on which terms, where, how much, for when. The trade fields are left out with trade: false (a studio's quote needs none).

Options: phone, attachments (files, checked by Service\Attachments), privacy / privacy_consent / privacy_parameters (glitchr/omnibase's PrivacyType). Guarded as glitchr/omnibase guards a form (its option guard, action "quote"): a trap, the time it takes, the lists, the captcha when the site has glitchr/omnishield - in place of the form's own trap, which stays only where the host's core is from before the guard.

QuoteRequestType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

The texts name their domain (@marketplace.…): omnibase gives every field the "fields" domain, which the form's own translation_domain does not reach.

QuoteRequestType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

Base\Marketplace\Invoice

FacturX class

final class FacturX FacturX.php:28

An invoice's Factur-X: its data as the structured XML of EN 16931 (UN/CEFACT CII, Factur-X 1.0's profile EN 16931 - "COMFORT"), and the PDF that carries it, as horstoeko/zugferd writes them (PDF/A-3, the XML attached as factur-x.xml).

The profile: EN 16931 is the European standard's core model, the one the French reform's base set of data is defined on; MINIMUM and BASIC WL are not invoices for French law, BASIC drops what a line of the shop may say (its allowances), EXTENDED adds what no line here holds.

Amounts are written in the currency's unit (19.90), from the invoice's integers in its smallest unit (1990).

const PROFILE = ZugferdProfiles::PROFILE_EN16931

FacturX::available()

public static function available(): bool

FacturX::xml()

public function xml(Invoice $invoice): string

FacturX::attach()

public function attach(Invoice $invoice, string $pdf): string

The invoice's PDF, the XML attached: what is sent and kept.

FacturX::validate()

public function validate(string $xml): array
Returns

what the schema finds wrong in this XML (EN 16931's XSD): none for a valid one

FacturX::extract()

public static function extract(string $pdf): ?string

The XML a PDF carries, null when it carries none.

InvoiceComposer class

final class InvoiceComposer InvoiceComposer.php:31

What an invoice says, written from an order the day it is issued: the seller (marketplace.invoice.seller, the store's VAT number over it), the buyer (the customer, the order's billing and delivery addresses), the lines, the totals, the mentions - copied, so that the invoice no longer depends on them.

The amounts are the order's, its VAT included: each line's price before VAT and its VAT are read, not computed again. Only the order's own charges (shipping, service, other taxes) and its order-level discount carry no VAT of their own in the order: they are amounts the buyer paid, VAT included, and each is split between the VAT rates of the lines in proportion of their bases - an accessory follows the rate of what it accompanies - so that the invoice's total is exactly what the order cost.

InvoiceComposer::__construct()

public function __construct(readonly Pricing $pricing, readonly ?TranslatorInterface $translator = null, readonly array $seller = [], readonly string $operation = 'goods', readonly bool $vatOnDebits = false, readonly ?string $latePenalties = null, readonly ?string $discount = null, readonly array $mentions = [])
$seller

marketplace.invoice.seller

InvoiceComposer::seller()

public function seller(Order $order): array
Returns

the seller that day

InvoiceComposer::buyer()

public function buyer(Order $order): array
Returns

the buyer that day

InvoiceComposer::amounts()

public function amounts(Order $order): array

The order's lines, and its charges and discount split by VAT rate.

InvoiceComposer::mentions()

public function mentions(Order $order, array $buyer, array $totals, \DateTimeImmutable $issuedAt, ?\DateTimeImmutable $dueAt, ?Invoice $credited = null, ?string $reason = null): array

The mentions the invoice prints, in the seller's language: the VAT exemption, the nature of the operations, the option for VAT on debits, the payment (made, or its date), the discount for early payment and - to a business - the penalties for late payment and the flat indemnity, then the seller's own.

InvoiceComposer::exemption()

public static function exemption(?string $mention): ?array

The category of an exempt order's VAT (EN 16931, UNTDID 5305) and its reason, from the mention Pricing wrote.

InvoiceNumbering class

final class InvoiceNumbering InvoiceNumbering.php:22

The numbers of the invoices: a sequence without a gap per series and year - F-2026-000001, F-2026-000002... - as the law asks (a chronological and continuous sequence, CGI ann. II art. 242 nonies A; series are allowed).

A number is taken and the invoice that bears it stored in one go, under a lock of the series (symfony/lock, marketplace.invoice.<series>) and in a transaction: two invoices issued at the same moment, from two requests or two workers, never get the same number, and a number is never taken without its invoice being written - a failure rolls both back. The table's unique key (series, year, sequence) holds should the lock be missing.

InvoiceNumbering::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly ?LockFactory $locks = null, readonly int $digits = 6)

InvoiceNumbering::format()

public function format(string $series, int $year, int $sequence): string

InvoiceNumbering::issue()

public function issue(string $series, \DateTimeImmutable $issuedAt, callable $make): Invoice

The next number of the series, given to the invoice $make builds with it, stored at once.

Base\Marketplace\Invoice\Transmission

InvoiceStatusCommand class

class InvoiceStatusCommand extends Command InvoiceStatusCommand.php:21

marketplace:invoice:status [<number>...]: asks the gateway the invoices went through (glitchr/omnibill) where they stand, and keeps it on them - every invoice transmitted whose status is not final (paid, refused, rejected) when none is named. For a platform without webhooks, from a cron. Registered only with glitchr/omnibill.

InvoiceStatusCommand::__construct()

public function __construct(readonly Invoices $invoices, readonly EntityManagerInterface $entityManager)

InvoiceStatusStore class

final class InvoiceStatusStore InvoiceStatusStore.php:23

Where omnibill/email keeps the statuses of the invoices it sent - nobody else tells them: beside the invoices (Entity\InvoiceFlow), found by the message's reference. A status recorded before the invoice knows its reference (the e-mail being sent) is held until it does.

The store is an object of an anonymous class, made by create(): no class of this bundle implements an omnibill interface, so that loading any of them (a compiler pass's class_exists() over every definition, excluded ones included) never fails on a site without the family. Registered only when omnibill/email is installed.

InvoiceStatusStore::create()

public static function create(EntityManagerInterface $entityManager): StatusStoreInterface

InvoiceTransmission class

class InvoiceTransmission InvoiceTransmission.php:48

The shop's invoices through glitchr/omnibill: an invoice sent is submitted to a gateway - omnibill/email by default, an approved platform (omnibill/afnor) the day the shop must issue through one -, and where it stands there (sent, deposited, refused, paid...) is kept beside it (Entity\InvoiceFlow).

marketplace: invoice: gateway: email # an omnibill gateway's name (omnibill.gateways.<name>); null: the bundle's own e-mail

"email" needs no configuration: with omnibill/email installed and no omnibill gateway of that name, the invoice goes from the seller's address (marketplace.invoice.seller.email). This folder is registered, and its entity mapped, only when glitchr/omnibill is installed: without it, Service\Invoices sends its own e-mail and nothing here exists. What omnibill throws leaves as a TransmissionException (a LogicException).

InvoiceTransmission::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly ?TranslatorInterface $translator = null, readonly ?Registry $registry = null, readonly ?MailerInterface $mailer = null, readonly ?StatusStoreInterface $store = null, readonly ?string $gateway = 'email')

InvoiceTransmission::isEnabled()

public function isEnabled(): bool

Whether invoices go through a gateway: one is named, and it can be built.

InvoiceTransmission::name()

public function name(): ?string

InvoiceTransmission::flowOf()

public function flowOf(Invoice $invoice): ?InvoiceFlow

Where the invoice stands on the gateway, if it went through one.

InvoiceTransmission::describe()

public function describe(Invoice $invoice): ?string

Its latest lifecycle status, in words ("Encaissée"), with the gateway; null when it went through none.

InvoiceTransmission::submit()

public function submit(Invoice $invoice, string $pdf, string $filename, ?string $link = null, ?string $to = null): InvoiceFlow

The invoice, its PDF (Factur-X) given, submitted to the gateway: what it answers is kept beside the invoice, and an invoice handed over is sent.

$pdf

the invoice's PDF: Service\Invoices::pdf()

$link

the invoice's signed address, for the e-mail's text

InvoiceTransmission::refresh()

public function refresh(Invoice $invoice): ?InvoiceFlow

Asks the gateway where the invoice stands, and keeps it; null when it went through none.

InvoiceTransmission::paid()

public function paid(Invoice $invoice, \DateTimeImmutable $at): void

"Encaissée" (212), a status the reform makes mandatory: declared to the gateway, kept beside the invoice.

InvoiceTransmission::declare()

public function declare(Invoice $invoice, LifecycleStatus $status, ?\DateTimeImmutable $at = null, ?string $reason = null): void

Declares a status of one's own invoice to the gateway when it takes it; kept beside the invoice either way.

InvoiceTransmission::supportsNotify()

public function supportsNotify(string $gateway): bool

InvoiceTransmission::notify()

public function notify(string $gateway, string $body, array $headers): Invoice|false|null

A gateway's callback (an approved platform's webhook): its signature checked by the gateway, the invoice it is about updated.

Returns

the invoice updated; null when it names none of the shop's; false when its signature does not hold

InvoiceTransmission::row()

public static function row(StatusChange $change): array

TransmissionException class

class TransmissionException extends LogicException TransmissionException.php:10

A gateway of glitchr/omnibill refused, did not answer, or is not set up: told to the back office as any refusal (a LogicException), its cause kept as the previous exception.

Base\Marketplace\Invoice\Transmission\Entity

InvoiceFlow class

class InvoiceFlow InvoiceFlow.php:17

Where an invoice stands on the glitchr/omnibill gateway it went through: the gateway, its reference of the transmission, the lifecycle statuses known (sent, deposited, refused, paid...). One per invoice, beside it - the invoice itself does not change once issued.

Mapped only when glitchr/omnibill is installed (MarketplaceExtension): a site without the family has no table for it, and needs none.

InvoiceFlow::__construct()

public function __construct(Invoice $invoice, string $gateway, string $reference)

InvoiceFlow::getId()

public function getId(): ?int

InvoiceFlow::getInvoice()

public function getInvoice(): Invoice

InvoiceFlow::getGateway()

public function getGateway(): string

InvoiceFlow::getReference()

public function getReference(): string

InvoiceFlow::restart()

public function restart(string $gateway, string $reference): static

Sent again, through a gateway: a new transmission, its history afresh.

InvoiceFlow::getStatus()

public function getStatus(): ?string

InvoiceFlow::getHistory()

public function getHistory(): array

InvoiceFlow::setHistory()

public function setHistory(array $history): static

InvoiceFlow::getUpdatedAt()

public function getUpdatedAt(): \DateTimeImmutable

Base\Marketplace\Model

CompanyRecord class

final class CompanyRecord CompanyRecord.php:10

A French company as the State's register knows it (API Recherche d'entreprises, fed by INSEE's Sirene and the RNE): kept with a quote or a request, as it was when checked.

public readonly string $siren
public readonly ?string $siret
public readonly string $name
public readonly ?string $address
public readonly ?string $activity
public readonly ?string $legalForm
public readonly bool $active

Still trading: false when the company, or that establishment, is closed.

public readonly ?string $createdOn
public readonly \DateTimeImmutable $checkedAt

CompanyRecord::__construct()

public function __construct(public readonly string $siren, public readonly ?string $siret, public readonly string $name, public readonly ?string $address, public readonly ?string $activity, public readonly ?string $legalForm, public readonly bool $active, public readonly ?string $createdOn, public readonly \DateTimeImmutable $checkedAt = new \DateTimeImmutable())

CompanyRecord::toArray()

public function toArray(): array

CompanyRecord::fromArray()

public static function fromArray(array $data): self

MerchantInterface interface

interface MerchantInterface MerchantInterface.php:23

Whoever sells the thing.

The marketplace needs a seller on a product, a store and an order, but it must not name the concrete class: in this shop that is App\Entity\User\Merchant, a subclass of the APP's User, and a bundle cannot reach into an app's user hierarchy without pinning every consumer to one shop's model.

Doctrine associations point at this interface and are bound to a real class per application through resolve_target_entities - see the host's config/packages/doctrine.yaml. That is what lets Order::$managers stay a mapped relation without the bundle knowing what a Merchant is.

Kept to what the marketplace actually asks of a seller - its trading name, used for the brand shown on a product - rather than mirroring the whole entity, so implementing it stays cheap.

MerchantInterface::getCompanyName()

public function getCompanyName(): ?string

OptionSelection class

final class OptionSelection OptionSelection.php:13

The options chosen for one line, checked against the product's groups (Service\ProductOptions::select()): what they add to the unit price, how they read, and what the line keeps of them - a copy, since the product's options may change after the order.

public readonly array $options

in the order of their groups

OptionSelection::__construct()

public function __construct(public readonly array $options = [])
$options

in the order of their groups

OptionSelection::isEmpty()

public function isEmpty(): bool

OptionSelection::surcharge()

public function surcharge(): int

What the options add to the unit price: smallest unit, before VAT.

OptionSelection::labels()

public function labels(?string $locale = null): array
Returns

"Bien cuit", "Œuf mollet"

OptionSelection::key()

public function key(): string

Two lines of the same product are one line when their options are the same.

OptionSelection::toArray()

public function toArray(?string $locale = null): array

What an OrderItem stores.

PlanTerms class

final readonly class PlanTerms PlanTerms.php:22

What a PLAN or a CREDIT_PACK product gives once paid, kept as JSON on the product (Product::$plan), so plans are data: made and priced in the back office, never in code.

billing "one_time" (a pass: access for months months, null = for good) or "recurring" (a subscription renewed every interval: month or year); grants the rights, by key - a limit (an integer: "guests": 150, "events.major": 1), a switch (true/false: "themes.premium"), a rate ("commission": 0.02) or any value an application reads; credits units credited at each payment, by kind ("ai": 200); level how plans compare: a higher level is an upgrade.

A product sold by size (a pass for 30, 80, 150 guests) is a product with variants: each variant has its price and its own terms.

const ONE_TIME = 'one_time'
const RECURRING = 'recurring'
public string $billing
public ?string $interval
public ?int $months
public array $grants
public array $credits
public int $level

PlanTerms::__construct()

public function __construct(public string $billing = self::ONE_TIME, public ?string $interval = null, public ?int $months = null, public array $grants = [], public array $credits = [], public int $level = 0)

PlanTerms::fromArray()

public static function fromArray(?array $data): self

PlanTerms::toArray()

public function toArray(): array

PlanTerms::isRecurring()

public function isRecurring(): bool

PlanTerms::expiry()

public function expiry(\DateTimeImmutable $from): ?\DateTimeImmutable

When a pass bought at $from ends; null: never (or, for a subscription, when it stops being paid).

PlanTerms::grant()

public function grant(string $key, mixed $default = null): mixed

QuickPayment class

final class QuickPayment QuickPayment.php:9

What QuickOrder::buy() hands back: the order made, and where its payment stands.

public readonly Order $order
public readonly PaymentResult $result

QuickPayment::__construct()

public function __construct(public readonly Order $order, public readonly PaymentResult $result)

QuoteRequest class

final class QuoteRequest QuoteRequest.php:16

What the quote form collects. A DTO, not the Quote itself: omnibase's form factory refuses an entity as form data (a half-filled entity in the unit of work is a flush waiting to happen); the controller turns it into a Quote once it is valid.

public string $contactName = ''
public string $email = ''
public ?string $phone = null

A number to be called back on.

public ?string $companyName = null
public ?string $siret = null

A French company's SIREN or SIRET - checked against the State's register.

public ?string $vatNumber = null

An EU company's VAT number - checked against VIES.

public string $title = ''
public ?TradeDirection $direction = null
public ?Incoterm $incoterm = null
public ?string $country = null
public ?string $place = null
public ?string $volume = null
public ?\DateTimeImmutable $targetDate = null
public ?string $deliveryAddress = null
public string $request = ''
public array $products = []

The products the request starts from (ids), when it was asked from their pages.

public array $files = []

ShippingUnitInterface interface

interface ShippingUnitInterface ShippingUnitInterface.php:8

ShippingUnitInterface::getShippingUnits()

public function getShippingUnits(): float

VatCustomerInterface interface

interface VatCustomerInterface VatCustomerInterface.php:14

A customer who may buy as a business: its intra-EU VAT number, and whether VIES confirmed it (Service\VatNumbers). A confirmed number from another EU country than the store's makes an order a reverse charge (Pricing\ReverseCharge): no VAT on it, the buyer accounts for it.

The app's User implements it, usually with VatCustomerTrait - the bundle does not reach into an app's user hierarchy (see MerchantInterface).

VatCustomerInterface::getVatNumber()

public function getVatNumber(): ?string

Country prefix included, as VIES writes it: "DE123456789", "EL...".

VatCustomerInterface::setVatNumber()

public function setVatNumber(?string $vatNumber): static

A number set is not confirmed yet: markVatNumberChecked() says it is.

VatCustomerInterface::getVatNumberCheckedAt()

public function getVatNumberCheckedAt(): ?\DateTimeImmutable

VatCustomerInterface::getVatConsultationNumber()

public function getVatConsultationNumber(): ?string

VIES's consultation number for that check: the proof the number was valid that day.

VatCustomerInterface::markVatNumberChecked()

public function markVatNumberChecked(?\DateTimeImmutable $at = null, ?string $consultationNumber = null): static

VatCustomerInterface::getVatCountry()

public function getVatCountry(): ?string

The two letters of its country, as VIES writes them ("EL" for Greece).

VatCustomerInterface::hasConfirmedVatNumber()

public function hasConfirmedVatNumber(): bool

VatCustomerTrait trait

trait VatCustomerTrait VatCustomerTrait.php:11

VatCustomerInterface on an app's User entity: the number, when VIES confirmed it and its consultation number.

VatCustomerTrait::getVatNumber()

public function getVatNumber(): ?string

VatCustomerTrait::setVatNumber()

public function setVatNumber(?string $vatNumber): static

VatCustomerTrait::getVatNumberCheckedAt()

public function getVatNumberCheckedAt(): ?\DateTimeImmutable

VatCustomerTrait::getVatConsultationNumber()

public function getVatConsultationNumber(): ?string

VatCustomerTrait::markVatNumberChecked()

public function markVatNumberChecked(?\DateTimeImmutable $at = null, ?string $consultationNumber = null): static

VatCustomerTrait::getVatCountry()

public function getVatCountry(): ?string

VatCustomerTrait::hasConfirmedVatNumber()

public function hasConfirmedVatNumber(): bool

WishlistHolderInterface interface

interface WishlistHolderInterface WishlistHolderInterface.php:11

What a list belongs to besides its owner: an event, a household, a project - anything of the application's. The list keeps its type and id (not a relation: the marketplace knows nothing of the application), and Repository\Wishlist\WishlistRepository::findForHolder() finds it again.

WishlistHolderInterface::getWishlistHolderType()

public function getWishlistHolderType(): string

A name of the application's for this kind of holder: "occasion".

WishlistHolderInterface::getWishlistHolderId()

public function getWishlistHolderId(): int|string|null

Base\Marketplace\Payment

DevGateway class

final class DevGateway implements PaymentGatewayInterface DevGateway.php:21

Paid by nobody, at once: an order walked all the way through in development without a Stripe key - and in a demonstration, where no money may move. Registered only when the kernel runs in debug or in the demo environment (MarketplaceExtension), and supports() says no anywhere else all the same, so a method on the "dev" gateway never shows in production.

A payment method (PaymentMethod) whose gateway factory is "dev" offers it - created in the back office or in the fixtures.

The applications' own copies (App\Market\DevGateway) are no longer needed.

const DEMO_ENVIRONMENT = 'demo'

glitchr/omnibase's demonstration environment (Base\Demo\DemoMode::ENVIRONMENT).

DevGateway::__construct()

public function __construct(readonly bool $debug = false, readonly string $environment = 'prod')

DevGateway::name()

public static function name(): string

DevGateway::supports()

public function supports(Order $order, PaymentMethod $method): bool

DevGateway::pay()

public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResult

ManualGateway class

class ManualGateway implements PaymentGatewayInterface ManualGateway.php:18

Paid outside the site - a bank transfer, a cheque, cash on collection. The order waits (pending) until someone in the admin marks it paid. The instructions shown to the buyer are the method's settings:

marketplace: gateways: virement: { instructions: 'IBAN FR76 ... - mention the reference' }

ManualGateway::name()

public static function name(): string

ManualGateway::supports()

public function supports(Order $order, PaymentMethod $method): bool

ManualGateway::pay()

public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResult

PaymentGatewayInterface interface

interface PaymentGatewayInterface PaymentGatewayInterface.php:29

One way of taking money for an order.

A PaymentMethod (an entity, configured in the admin) names its gateway by gatewayFactory; the gateway with that name() is the one that takes the payment. Services implementing this interface are tagged marketplace.payment_gateway and collected by PaymentGatewayRegistry, so an application adds a gateway by writing a class - a currency of its own, a card processor, a bank transfer.

pay() does as much as it can at once and says how it went:

PaymentResult::paid() the money is in (an in-game currency, a captured card): the order is paid; PaymentResult::pending() it will be later (a transfer, a cheque): the order waits; PaymentResult::redirect($url) the buyer must go and pay elsewhere and come back (a hosted card page); PaymentResult::refused($why) it will not be.

PaymentGatewayInterface::name()

public static function name(): string

The value a PaymentMethod's gatewayFactory holds to use this gateway.

PaymentGatewayInterface::supports()

public function supports(Order $order, PaymentMethod $method): bool

Whether this gateway can take this order at all (the currency, the buyer, the amount).

PaymentGatewayInterface::pay()

public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResult

PaymentGatewayRegistry class

class PaymentGatewayRegistry PaymentGatewayRegistry.php:23

Every gateway of the application, by name(): its own first (manual, and whatever it wrote), then - when glitchr/omnitrade is installed - a bridge to each gateway configured under omnitrade.gateways, by that name. A PaymentMethod's gatewayFactory is one of these names.

In a demonstration (glitchr/omnibase's demo environment) no money moves: the gateways of glitchr/omnitrade - Stripe, PayPal, a real provider behind each - are not there at all, neither offered at the checkout nor reached by a return page or a webhook. The application's own stay (manual, and the "dev" gateway, registered there for that purpose).

PaymentGatewayRegistry::__construct()

public function __construct(iterable $gateways, ?OmnitradeGateways $omnitrade = null, string $environment = 'prod')

PaymentGatewayRegistry::get()

public function get(?string $name): ?PaymentGatewayInterface

PaymentGatewayRegistry::for()

public function for(PaymentMethod $method): ?PaymentGatewayInterface

PaymentGatewayRegistry::names()

public function names(): array

PaymentGatewayRegistry::usableFor()

public function usableFor(Order $order, iterable $methods): array

The payment methods, among $methods, that can take this order: a gateway exists for them and accepts it.

PaymentResult class

final class PaymentResult PaymentResult.php:6

What a gateway's pay() came to - see PaymentGatewayInterface.

const PAID = 'paid'
const PENDING = 'pending'
const REDIRECT = 'redirect'
const REFUSED = 'refused'

PaymentResult::paid()

public static function paid(): self

PaymentResult::pending()

public static function pending(): self

PaymentResult::redirect()

public static function redirect(string $url): self

PaymentResult::refused()

public static function refused(string $reason, array $parameters = []): self

PaymentResult::isPaid()

public function isPaid(): bool

PaymentResult::isPending()

public function isPending(): bool

PaymentResult::isRedirect()

public function isRedirect(): bool

PaymentResult::isRefused()

public function isRefused(): bool

Base\Marketplace\Payment\Omnitrade

OmnitradeGateway class

final class OmnitradeGateway implements PaymentGatewayInterface OmnitradeGateway.php:43

A payment method that names a glitchr/omnitrade gateway: the shop's PaymentMethod is a proxy, its gatewayFactory the name of a gateway configured under omnitrade.gateways (stripe, paypal, a Shopify shop...), and this bridge takes the order there.

omnitrade: gateways: card: { factory: stripe, options: { api_key: '%env(STRIPE_API_KEY)%', webhook_secret: '%env(STRIPE_WEBHOOK_SECRET)%' } }

a PaymentMethod "Carte bancaire", gatewayFactory: card

One instance per omnitrade gateway, built by OmnitradeGateways and found by PaymentGatewayRegistry after the application's own gateways. The provider's reference for the payment (a Checkout session, a PayPal order) is kept on the Transaction (webhook), where PaymentController's return page and webhook find it again.

OmnitradeGateway::__construct()

public function __construct(readonly string $gatewayName, readonly GatewayInterface $gateway, readonly UrlGeneratorInterface $urls, readonly array $options = [], readonly ?EventDispatcherInterface $dispatcher = null)
$options

the gateway's options as it runs on: configured, and typed in the back office over them

OmnitradeGateway::option()

public function option(string $name): ?string

One of the options the gateway runs on (api_key, webhook_secret...), null when unset or empty.

OmnitradeGateway::name()

public static function name(): string

Every bridge answers to this; the registry keys them by their omnitrade gateway's name (getName()).

OmnitradeGateway::getName()

public function getName(): string

The omnitrade gateway's name: what a PaymentMethod's gatewayFactory holds.

OmnitradeGateway::provider()

public function provider(): string

The provider behind it: stripe, paypal, shopify, woocommerce.

OmnitradeGateway::gateway()

public function gateway(): GatewayInterface

OmnitradeGateway::supports()

public function supports(Order $order, PaymentMethod $method): bool

OmnitradeGateway::pay()

public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResult

OmnitradeGateway::fetch()

public function fetch(Transaction $transaction): OmnitradeTransaction

Where the provider's payment stands now.

OmnitradeGateway::notify()

public function notify(string $body, array $headers): Notification

A webhook, checked and read.

Throws

Omnitrade\Exception\InvalidNotificationException when it was not the provider's

OmnitradeGateway::refund()

public function refund(Transaction $transaction, int $amount, string $currency, string $idempotencyKey, ?string $reason = null): string

Pays $amount (minor units) back on what the transaction was paid with and returns the provider's refund id. The idempotency key makes the same refund asked twice happen once.

Throws

OmnitradeException when the provider knows no payment for it, or refuses

OmnitradeGateway::reference()

public static function reference(Transaction $transaction): string

The provider's reference the transaction was paid under: kept as its webhook, else in its details (an older payment's stripe_session too).

OmnitradeGateway::prepare()

public function prepare(Order $order, Transaction $transaction, PaymentMethod $method): PaymentPreparingEvent

How the order goes to the provider, as the application's listeners have it (Event\PaymentPreparingEvent): an order of one recurring plan is a subscription of that plan's interval unless they say otherwise.

OmnitradeGateway::payment()

public function payment(Order $order, Transaction $transaction, PaymentMethod $method, ?PaymentPreparingEvent $event = null): Payment

What the provider is asked for: the order, as omnitrade describes a payment.

OmnitradeGateways class

final class OmnitradeGateways OmnitradeGateways.php:37

The bridges to glitchr/omnitrade's configured gateways, one per name.

Registered only when glitchr/omnitrade is installed (config/services.php); PaymentGatewayRegistry asks here after the application's own gateways.

A gateway's options may also be typed in the back office, as settings under api.payment_method.<gateway>.<option> - the Stripe keys of the "stripe" gateway are api.payment_method.stripe.api_key and api.payment_method.stripe.webhook_secret, a PayPal secret api.payment_method.paypal.secret. Typed, they win over the configuration (config/packages/omnitrade.yaml, the environment); empty, the configuration serves. Any provider, any option: nothing to write per provider.

In a demonstration (glitchr/omnibase's demo environment) no money moves and no provider is reached - whoever asks: the checkout, a list's contributions, its owner's payout account, an address read for a wish all come here. There, none of omnitrade.gateways answers, whatever keys it holds, typed or configured: get() gives the gateway made by a factory the application marked as a trial one (TrialGatewayFactoryInterface), asked by that factory's name, and null for everything else - which every caller already takes as "no such gateway". A real gateway asked for is written to the log, once.

const SETTINGS = 'api.payment_method'

OmnitradeGateways::__construct()

public function __construct(readonly Registry $registry, readonly UrlGeneratorInterface $urls, readonly ?SettingBagInterface $settings = null, readonly ?\Psr\EventDispatcher\EventDispatcherInterface $dispatcher = null, readonly string $environment = 'prod', iterable $trials = [], readonly ?LoggerInterface $logger = null)

OmnitradeGateways::isDemonstration()

public function isDemonstration(): bool

Whether this is a demonstration: only the application's trial gateways answer.

OmnitradeGateways::get()

public function get(string $name): ?OmnitradeGateway

The bridge to the gateway of that name; null when there is none, or when it lacks what it needs to run (no API key yet, typed or configured): such a method is simply not offered at checkout. In a demonstration, null for every gateway but the application's trial ones.

OmnitradeGateways::names()

public function names(): array

OmnitradeGateways::typed()

public function typed(string $name): array

The options typed in the back office for this gateway, the empty ones left out.

TrialGatewayFactoryInterface interface

interface TrialGatewayFactoryInterface extends GatewayFactoryInterface TrialGatewayFactoryInterface.php:30

A glitchr/omnitrade gateway factory of the application's own whose gateways move no money and reach no provider: accounts ready at once, a payment paid on the spot by nobody, a product read from nowhere.

In a demonstration (glitchr/omnibase's demo environment) these are the only omnitrade gateways the marketplace talks to: OmnitradeGateways gives the gateway such a factory makes, asked by the factory's name, and none of omnitrade.gateways - whatever keys they hold. An application that wants its lists to take contributions in demo writes one and names it (marketplace.wishlist.payout_gateway under when@demo):

#[When(env: 'demo')]
final class TrialGatewayFactory implements TrialGatewayFactoryInterface
{
    public function getName(): string { return 'essai'; }
    public function create(array $options = []): GatewayInterface { return new Gateway('essai', 'Paiement d’essai', [new TrialAction()]); }
}

Implementing this is a promise: the marketplace cannot check what a gateway does. Outside demo the interface changes nothing.

Base\Marketplace\Pricing

ExportExemption class

final class ExportExemption implements VatExemptionInterface ExportExemption.php:21

Goods leaving the European Union carry no VAT: an order delivered outside it (its shipping address - a quote's order has its quote's) by a seller inside it is invoiced without, and the invoice says why - article 262 I of the French CGI for a French seller, article 146 of the VAT directive otherwise. The customs side (the export declaration, the excise document for alcohol) stays the seller's, off the site.

After the store's own regime (StoreVatRegime, 100), before a reverse charge (ReverseCharge, 50): an export is exempt whoever buys.

const MENTION = 'Exonération de TVA - article 262 I du CGI (livraison à l\'exportation)'
const MENTION_EU = 'VAT exempt - export of goods, Article 146 of Council Directive 2006/112/EC'
const EU = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'GR', 'ES', 'FI', 'FR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', …

The member states, by ISO 3166-1 alpha-2 (Greece is GR here, EL only in VIES).

ExportExemption::__construct()

public function __construct(readonly ?string $sellerCountry = 'FR')

ExportExemption::exempts()

public function exempts(Order $order): ?string

ExportExemption::inEu()

public static function inEu(string $country): bool

Whether a country is inside the EU's VAT territory (Monaco is, with France).

ReverseCharge class

final class ReverseCharge implements VatExemptionInterface ReverseCharge.php:21

The buyer's side: a business from another EU country than the store's, whose VAT number VIES confirmed (Service\VatNumbers), is invoiced without VAT and accounts for it itself (article 196 of Directive 2006/112/EC). A business of the store's own country, a customer without a confirmed number, pays VAT.

The store's country is its VAT number's: a store without one charges no reverse charge. After the store's own regime (StoreVatRegime, priority 100): a store that charges no VAT at all says so first.

const MENTION = 'Autoliquidation - article 196 de la directive 2006/112/CE, article 283-2 du CGI'

A French seller's mention: the directive and the CGI.

const MENTION_EU = 'Reverse charge - Article 196 of Council Directive 2006/112/EC'
const EU = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI', 'FR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', …

The EU's VAT prefixes, as VIES writes them: Greece is EL, Northern Ireland XI.

ReverseCharge::exempts()

public function exempts(Order $order): ?string

StoreVatRegime class

final class StoreVatRegime implements VatExemptionInterface StoreVatRegime.php:15

The seller's side: a store whose owner does not charge VAT (Store:: chargesVat(), a small business under the franchise en base) sells without it, whoever buys. Asked before the buyer's side (a reverse charge only matters when the store charges VAT).

const MENTION = 'TVA non applicable, art. 293 B du CGI'

StoreVatRegime::exempts()

public function exempts(Order $order): ?string

VatExemptionInterface interface

interface VatExemptionInterface VatExemptionInterface.php:17

Whether an order is sold without VAT - an EU business buying from another member state (reverse charge), an export... Each service implementing it is asked once per repricing (tagged marketplace.vat_exemption, autoconfigured); the first that exempts wins.

exempts() answers the mention an invoice must carry (e.g. "Autoliquidation - art. 283-2 du CGI", with the buyer's VAT number), kept on the order (Order::getVatExemption()); null when the order pays VAT.

VatExemptionInterface::exempts()

public function exempts(Order $order): ?string

Base\Marketplace\Quote

QuoteRepositoryTrait trait

trait QuoteRepositoryTrait QuoteRepositoryTrait.php:18

What every quote table answers, for a ServiceEntityRepository of quotes: numbered when saved, a client's quotes, the pipeline's columns. A trait rather than a parent class: omnibase registers every class of a bundle's src/Repository as a repository service of its own, an abstract one too.

The using repository says its prefix with quotePrefix() (Q-2026-0042).

QuoteRepositoryTrait::saveNumbered()

public function saveNumbered(AbstractQuote $quote, ?\DateTimeImmutable $at = null): void

Numbers a new quote <PREFIX>-<year>-<n> and saves it, in one transaction.

n is one more than the year's highest, read with its rows locked (SELECT ... FOR UPDATE): two quotes asked for at the same moment wait for each other instead of taking the same number, and a quote deleted leaves a gap rather than a number taken twice.

A quote that has its reference already is only saved.

QuoteRepositoryTrait::findForClient()

public function findForClient(User $user): array
Returns

the client's, or those sent to their e-mail

QuoteRepositoryTrait::pipeline()

public function pipeline(): array
Returns

the quotes by status, in the pipeline's order

Base\Marketplace\Quote\Signature

QuoteSignatures class

class QuoteSignatures QuoteSignatures.php:44

A priced quote accepted by signing it in the site's page, through glitchr/omnisign (glitchr/omnibase's Base\Service\Signatures): its PDF (@Marketplace/quote/quote.pdf.twig) sent as an envelope about the quote, the client signing where they are, the quote accepted - its order, its payment, as an acceptance without a signature - once the provider says it is completed (the way back, or its webhook: SignatureEvent::COMPLETED).

Declined or expired, the quote stays open. The signed PDF and its evidence stay with the envelope, in the private storage.

marketplace:
    quotes:
        signature: contracts            # a gateway of omnisign.gateways; absent (null): accepting is a click
        signature_template: ~           # DocuSeal's open-source edition signs its own templates only: one's id

This folder is registered only when glitchr/omnisign and the core's Signatures are there; nothing of it implements an omnisign interface.

const BOX = ['x' => 354, 'y' => 700, 'width' => 198, 'height' => 56]

The signature's box on the quote's last page, in points from its top left corner (A4: 595 × 842).

QuoteSignatures::__construct()

public function __construct(readonly Signatures $signatures, readonly QuoteToOrder $quoteToOrder, readonly EntityManagerInterface $entityManager, readonly Environment $twig, readonly ?LoggerInterface $logger = null, readonly ?string $gateway = null, readonly ?string $template = null, readonly array $seller = [])
$seller

marketplace.invoice.seller: who the quote is from

QuoteSignatures::isEnabled()

public function isEnabled(): bool

Whether accepting a quote asks for a signature: a gateway named, and configured.

QuoteSignatures::latest()

public function latest(Quote $quote): ?Envelope

The quote's latest envelope, if it was sent to be signed.

QuoteSignatures::pdf()

public function pdf(Quote $quote): string

The quote as a PDF: what is signed.

QuoteSignatures::start()

public function start(Quote $quote, string $returnUrl): string

Where the client signs the quote, in the site's page: its envelope sent once, asked again while it waits for its signature.

QuoteSignatures::back()

public function back(Quote $quote, User $client): array

Back from signing: where the envelope stands, asked of the provider; the quote accepted for $client once it is completed.

Returns

the envelope's status (sent, completed, declined, expired, canceled), the order once accepted

QuoteSignatures::onCompleted()

public function onCompleted(SignatureEvent $event): void

Completed, the way back or the provider's webhook: the quote accepted, as a click accepted it.

QuoteSignatures::file()

public function file(Quote $quote, string $kind = 'document'): ?string

The signed quote, or its evidence ("evidence"), once completed.

Base\Marketplace\Repository

AttachmentRepository class

class AttachmentRepository extends ServiceEntityRepository AttachmentRepository.php:10

AttachmentRepository::__construct()

public function __construct(ManagerRegistry $registry)

BrandRepository class

class BrandRepository extends ThreadRepository BrandRepository.php:14

BrandRepository::findOneByName()

public function findOneByName(string $name): ?Brand

The brand of that name, in any of its translations' titles - or null.

CreditRepository class

class CreditRepository extends ServiceEntityRepository CreditRepository.php:10

CreditRepository::__construct()

public function __construct(ManagerRegistry $registry)

EntitlementRepository class

class EntitlementRepository extends ServiceEntityRepository EntitlementRepository.php:10

EntitlementRepository::__construct()

public function __construct(ManagerRegistry $registry)

InvoiceRepository class

class InvoiceRepository extends ServiceEntityRepository InvoiceRepository.php:15

InvoiceRepository::lastSequence()

public function lastSequence(string $series, int $year): int

The last number taken in a series and a year: 0 before the first.

InvoiceRepository::standingFor()

public function standingFor(Order $order): ?Invoice

The invoice of an order that stands - not cancelled by a credit note.

InvoiceRepository::ofOrder()

public function ofOrder(Order $order): array
Returns

an order's invoices and credit notes, oldest first

OrderRepository class

class OrderRepository extends ServiceEntityRepository OrderRepository.php:14

ProductRepository class

class ProductRepository extends ThreadRepository ProductRepository.php:14

QuoteRepository class

class QuoteRepository extends ServiceEntityRepository QuoteRepository.php:16

The business quotes, numbered D-<year>-<n> (saveNumbered()), a client's (findForClient()), by status (pipeline()).

QuoteRepository::__construct()

public function __construct(ManagerRegistry $registry)

ReviewRepository class

class ReviewRepository extends ThreadRepository ReviewRepository.php:14

StoreRepository class

class StoreRepository extends ThreadRepository StoreRepository.php:14

UsageRepository class

class UsageRepository extends ServiceEntityRepository UsageRepository.php:10

UsageRepository::__construct()

public function __construct(ManagerRegistry $registry)

Base\Marketplace\Repository\Catalogue

PlatformLinkRepository class

class PlatformLinkRepository extends ServiceEntityRepository PlatformLinkRepository.php:10

PlatformLinkRepository::__construct()

public function __construct(ManagerRegistry $registry)

PlatformLinkRepository::findVariant()

public function findVariant(string $gateway, string $remoteVariant): ?PlatformLink

PlatformLinkRepository::findProduct()

public function findProduct(string $gateway, string $remoteProduct): array

PlatformLinkRepository::findItem()

public function findItem(string $gateway, string $remoteItem): ?PlatformLink

PlatformLinkRepository::lastRemoteUpdate()

public function lastRemoteUpdate(string $gateway): ?\DateTimeImmutable

The newest change read from this platform: where an incremental sync starts.

Base\Marketplace\Repository\Order

OrderItemRepository class

class OrderItemRepository extends ServiceEntityRepository OrderItemRepository.php:14

PickupRepository class

class PickupRepository extends ServiceEntityRepository PickupRepository.php:16

The hand-overs: an order's, a tracking page's (by its token), a day's.

PickupRepository::__construct()

public function __construct(ManagerRegistry $registry)

PickupRepository::of()

public function of(Order $order): ?Pickup

PickupRepository::byToken()

public function byToken(string $token): array
Returns

the orders made together, oldest first

PickupRepository::onDay()

public function onDay(\DateTimeImmutable $day): array

What the shop has to hand over on a day, a slot after the other; the carts whose payment never came are left out.

ShipmentRepository class

class ShipmentRepository extends ServiceEntityRepository ShipmentRepository.php:14

SubscriptionRepository class

class SubscriptionRepository extends ServiceEntityRepository SubscriptionRepository.php:10

SubscriptionRepository::__construct()

public function __construct(ManagerRegistry $registry)

SupplyJobRepository class

class SupplyJobRepository extends ServiceEntityRepository SupplyJobRepository.php:10

SupplyJobRepository::__construct()

public function __construct(ManagerRegistry $registry)

TransactionRepository class

class TransactionRepository extends ServiceEntityRepository TransactionRepository.php:14

Base\Marketplace\Repository\Order\Address

BillingAddressRepository class

class BillingAddressRepository extends AddressRepository BillingAddressRepository.php:10

ShippingAddressRepository class

class ShippingAddressRepository extends AddressRepository ShippingAddressRepository.php:10

Base\Marketplace\Repository\Order\Method

PaymentMethodRepository class

class PaymentMethodRepository extends ServiceEntityRepository PaymentMethodRepository.php:14

ShippingMethodRepository class

class ShippingMethodRepository extends ServiceEntityRepository ShippingMethodRepository.php:14

Base\Marketplace\Repository\Product

AttributeRepository class

class AttributeRepository extends AttributeRepository AttributeRepository.php:13

AttributeSetRepository class

class AttributeSetRepository extends ServiceEntityRepository AttributeSetRepository.php:12

AttributeSetRepository::__construct()

public function __construct(ManagerRegistry $registry)

AttributeSetRepository::forTaxon()

public function forTaxon(?Taxon $taxon): ?AttributeSet

The set of a taxon: its own, else its parent's, up the tree, else the set of every product.

AttributeSetRepository::forProduct()

public function forProduct(Product $product): ?AttributeSet

The set a product is described by: its first taxon's that has one.

FeatureRepository class

class FeatureRepository extends ServiceEntityRepository FeatureRepository.php:14

IdentifierRepository class

class IdentifierRepository extends ServiceEntityRepository IdentifierRepository.php:14

ImageRepository class

class ImageRepository extends ImageRepository ImageRepository.php:13

TaxonRepository class

class TaxonRepository extends TaxonRepository TaxonRepository.php:13

VariantRepository class

class VariantRepository extends ProductRepository VariantRepository.php:14

Base\Marketplace\Repository\Product\Attribute

BarcodeRepository class

class BarcodeRepository extends ServiceEntityRepository BarcodeRepository.php:14

HyperlinkRepository class

class HyperlinkRepository extends ServiceEntityRepository HyperlinkRepository.php:14

Base\Marketplace\Repository\Product\Attribute\Adapter

BarcodeAdapterRepository class

class BarcodeAdapterRepository extends AttributeRepository BarcodeAdapterRepository.php:14

Base\Marketplace\Repository\Review

TaxonRepository class

class TaxonRepository extends TaxonRepository TaxonRepository.php:13

Base\Marketplace\Repository\Sales

ChannelRepository class

class ChannelRepository extends ServiceEntityRepository ChannelRepository.php:15

DiscountRepository class

class DiscountRepository extends ServiceEntityRepository DiscountRepository.php:14

FeeRepository class

class FeeRepository extends ServiceEntityRepository FeeRepository.php:14

ForexRepository class

class ForexRepository extends ServiceEntityRepository ForexRepository.php:14

RegionRepository class

class RegionRepository extends ServiceEntityRepository RegionRepository.php:14

TaxRepository class

class TaxRepository extends ServiceEntityRepository TaxRepository.php:14

Base\Marketplace\Repository\Sales\Attribute

DiscountActionRepository class

class DiscountActionRepository extends ServiceEntityRepository DiscountActionRepository.php:14

DiscountRuleRepository class

class DiscountRuleRepository extends ServiceEntityRepository DiscountRuleRepository.php:14

DiscountScopeRepository class

class DiscountScopeRepository extends ServiceEntityRepository DiscountScopeRepository.php:14

FeeActionRepository class

class FeeActionRepository extends ServiceEntityRepository FeeActionRepository.php:14

FeeRuleRepository class

class FeeRuleRepository extends ServiceEntityRepository FeeRuleRepository.php:14

FeeScopeRepository class

class FeeScopeRepository extends ServiceEntityRepository FeeScopeRepository.php:14

PaymentMethodRuleRepository class

class PaymentMethodRuleRepository extends ServiceEntityRepository PaymentMethodRuleRepository.php:14

PaymentMethodScopeRepository class

class PaymentMethodScopeRepository extends ServiceEntityRepository PaymentMethodScopeRepository.php:14

ShippingMethodRuleRepository class

class ShippingMethodRuleRepository extends ServiceEntityRepository ShippingMethodRuleRepository.php:14

ShippingMethodScopeRepository class

class ShippingMethodScopeRepository extends ServiceEntityRepository ShippingMethodScopeRepository.php:14

TaxScopeRepository class

class TaxScopeRepository extends ServiceEntityRepository TaxScopeRepository.php:14

Base\Marketplace\Repository\Sales\Attribute\Action

FixedAmountAdapterRepository class

class FixedAmountAdapterRepository extends ServiceEntityRepository FixedAmountAdapterRepository.php:14

PercentageAmountAdapterRepository class

class PercentageAmountAdapterRepository extends ServiceEntityRepository PercentageAmountAdapterRepository.php:14

Base\Marketplace\Repository\Sales\Attribute\Rule

CartContainsAdapterRepository class

class CartContainsAdapterRepository extends ServiceEntityRepository CartContainsAdapterRepository.php:14

CartQuantityAdapterRepository class

class CartQuantityAdapterRepository extends ServiceEntityRepository CartQuantityAdapterRepository.php:14

TotalPriceAdapterRepository class

class TotalPriceAdapterRepository extends ServiceEntityRepository TotalPriceAdapterRepository.php:14

Base\Marketplace\Repository\Sales\Attribute\Scope

OrderAdapterRepository class

class OrderAdapterRepository extends ServiceEntityRepository OrderAdapterRepository.php:14

ProductAdapterRepository class

class ProductAdapterRepository extends ServiceEntityRepository ProductAdapterRepository.php:14

RegionAdapterRepository class

class RegionAdapterRepository extends ServiceEntityRepository RegionAdapterRepository.php:14

StoreAdapterRepository class

class StoreAdapterRepository extends ServiceEntityRepository StoreAdapterRepository.php:14

TaxonAdapterRepository class

class TaxonAdapterRepository extends ServiceEntityRepository TaxonAdapterRepository.php:14

UserAdapterRepository class

class UserAdapterRepository extends ServiceEntityRepository UserAdapterRepository.php:14

Base\Marketplace\Repository\Sales\Discount

CouponRepository class

class CouponRepository extends ServiceEntityRepository CouponRepository.php:14

PromotionRepository class

class PromotionRepository extends ServiceEntityRepository PromotionRepository.php:14

Base\Marketplace\Repository\Sales\Referral

ReferralCodeRepository class

class ReferralCodeRepository extends ServiceEntityRepository ReferralCodeRepository.php:10

ReferralCodeRepository::__construct()

public function __construct(ManagerRegistry $registry)

ReferralRepository class

class ReferralRepository extends ServiceEntityRepository ReferralRepository.php:10

ReferralRepository::__construct()

public function __construct(ManagerRegistry $registry)

Base\Marketplace\Repository\Sales\Tax

VatRepository class

class VatRepository extends TaxRepository VatRepository.php:14

Base\Marketplace\Repository\Wishlist

ContributionRepository class

class ContributionRepository extends ServiceEntityRepository ContributionRepository.php:10

ContributionRepository::__construct()

public function __construct(ManagerRegistry $registry)

PayoutAccountRepository class

class PayoutAccountRepository extends ServiceEntityRepository PayoutAccountRepository.php:10

PayoutAccountRepository::__construct()

public function __construct(ManagerRegistry $registry)

WishlistRepository class

class WishlistRepository extends ServiceEntityRepository WishlistRepository.php:11

WishlistRepository::__construct()

public function __construct(ManagerRegistry $registry)

WishlistRepository::findForHolder()

public function findForHolder(WishlistHolderInterface $holder): array
Returns

the lists of an event, a project...

WishlistRepository::findOneByToken()

public function findOneByToken(string $token): ?Wishlist

Base\Marketplace\Security

InvoiceVoter class

final class InvoiceVoter extends Voter InvoiceVoter.php:16

Who reads an invoice: its buyer (the customer of its order, signed in), and whoever runs the shop's back office (MarketplaceVoter::VIEW).

const VIEW = 'MARKETPLACE_INVOICE_VIEW'

InvoiceVoter::__construct()

public function __construct(readonly AuthorizationCheckerInterface $authorization)

MarketplaceVoter class

final class MarketplaceVoter extends Voter implements ResetInterface MarketplaceVoter.php:35

Who reaches the marketplace in the back office:

  • MARKETPLACE_MANAGE (change anything): the creators, marketplace.admin_role (ROLE_SUPERADMIN by default; ROLE_EDITOR inherits it).
  • MARKETPLACE_VIEW (read every marketplace screen): the creators, and the owners of a shop - a member among a Store's owners.
  • MARKETPLACE_PRICING (change VAT, taxes, prices, discounts, a store's VAT regime): the creators, and the shops' owners - their business, their prices, and theirs only: asked about a record, an owner is granted it when it belongs to one of their stores (a product, a store, a tax, fee or discount scoped to it). What every shop shares - a region's VAT, the exchange rates - stays the creators'.

Nobody else, whatever other back-office rights they hold. The marketplace's CRUDs carry MARKETPLACE_VIEW as their entity permission (MarketplaceAdminTrait); their changes already require ROLE_SUPERADMIN, the admin's default for new, edit and delete.

const VIEW = 'MARKETPLACE_VIEW'
const MANAGE = 'MARKETPLACE_MANAGE'
const PRICING = 'MARKETPLACE_PRICING'

MarketplaceVoter::__construct()

public function __construct(readonly AccessDecisionManagerInterface $accessDecisionManager, readonly EntityManagerInterface $entityManager, readonly string $creators = 'ROLE_SUPERADMIN')

MarketplaceVoter::reset()

public function reset(): void

Between requests (a worker): ownership may have changed.

Base\Marketplace\Service

AgeGate class

class AgeGate AgeGate.php:22

The age a visitor must have reached to see what is sold to adults only (a wine, a sake: Product::isAgeRestricted()), and whether they said so.

The age is set by country or by language (marketplace.age_gate.ages: 18 by default, 20 in Japan and in Japanese), the country read from the visitor's country cookie or header when the application sets one. The answer is kept in a cookie for a year (a necessary cookie: the law asks for the check); a "no" sends the visitor away.

AgeGate::__construct()

public function __construct(readonly RequestStack $requests, readonly bool $enabled = true, readonly int $default = 18, readonly array $ages = [], readonly ?string $notice = null, readonly bool $site = false)
$ages

by language ("ja") or country ("JP")

AgeGate::isEnabled()

public function isEnabled(): bool

AgeGate::minimumAge()

public function minimumAge(?string $locale = null, ?string $country = null): int

The age asked of this visitor: their country's, else their language's, else the default.

AgeGate::guards()

public function guards(Product|Taxon|bool|null $subject = null): bool

Whether this page needs the gate: the whole site when age_gate.site is true, else a restricted product or taxon, or true given by a page that is (a cellar's list).

AgeGate::isConfirmed()

public function isConfirmed(?Request $request = null): bool

Whether the visitor confirmed the age this page asks (a lower one does not count for a higher one).

AgeGate::mustAsk()

public function mustAsk(Product|Taxon|bool|null $subject = null): bool

Whether to show the gate now.

AgeGate::confirmation()

public function confirmation(?int $age = null): Cookie

The cookie keeping the visitor's yes: the age they confirmed, for a year.

AgeGate::notice()

public function notice(): ?string

The health notice the law asks next to alcohol (France: loi Évin), as configured; null: none.

Attachments class

class Attachments Attachments.php:23

The files given with a quote request or for an order line (Entity\Attachment): stored outside the public directory under a random name, limited in number, weight and kind, served as downloads only - to the back office, or to whoever holds a signed link (url(): what a supplier is given to fetch an artwork).

Attachments::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly UriSigner $signer, readonly UrlGeneratorInterface $router, readonly string $directory, readonly int $maxSize = 20971520, readonly int $maxFiles = 5, readonly array $extensions = ['pdf', 'png', 'jpg', 'jpeg', 'webp', 'gif', 'svg', 'ai', 'eps', 'psd', 'tif', 'tiff', 'zip'])

Attachments::maxFiles()

public function maxFiles(): int

Attachments::maxSize()

public function maxSize(): int

Attachments::extensions()

public function extensions(): array

Attachments::refusal()

public function refusal(iterable $files, int $already = 0): ?array

Why these files cannot be taken, as a key of the marketplace translations and its parameters - or null when they can.

Attachments::attachToQuote()

public function attachToQuote(Quote $quote, iterable $files): array

Keeps the files of a quote request.

Throws

CartException attachment.error.*

Attachments::attachToItem()

public function attachToItem(OrderItem $item, iterable $files): array

Keeps the files of an order line: the buyer's artwork.

Throws

CartException attachment.error.*

Attachments::file()

public function file(Attachment $attachment): ?string

The file on disk; null when it is gone.

Attachments::download()

public function download(Attachment $attachment): BinaryFileResponse

A download: never shown in the page (an SVG may carry a script), named as the sender named it.

Attachments::url()

public function url(Attachment $attachment, int $ttl = 604800): string

A link good for $ttl seconds, for somebody without an account: a supplier fetching an artwork.

Attachments::remove()

public function remove(Attachment $attachment): void

AttributeFilters class

class AttributeFilters AttributeFilters.php:22

The list's filters, built from the attributes a set marks filterable: for a choice, the values met among the products and how many have each (a wine's colour, appellation, grapes); for a range, the lowest and the highest (its alcohol, its keeping). The visitor's choice comes in the query string - ?f[colour][]=rouge&f[alcohol][min]=12 - and narrows the products, every filter at once, a value of a list among its items ("Merlot" in "Merlot, Cabernet franc").

In memory, over the products given: right for a shop of a few hundred references; a large catalogue filters in Typesense instead (plan 0 §1.7).

AttributeFilters::selection()

public function selection(Request $request): array
Returns

code => values, or a range

AttributeFilters::facets()

public function facets(iterable $products, ?AttributeSet $set, ?string $locale = null): array

AttributeFilters::apply()

public function apply(iterable $products, array $selection, ?string $locale = null): array

The products every chosen filter holds.

AttributeFilters::valuesOf()

public function valuesOf(Product $product, string $code, ?string $locale = null): array

A product's values of an attribute, as strings: a list split on its commas, a variant's own values too (a vintage's alcohol).

Cart class

class Cart Cart.php:23

The signed-in member's carts: one open Order (state CART) per store, since two stores may not share a currency, a region or a way of being paid.

The bundle's Order already is the cart - addItem()/removeItem() only work while it is one - so this service only finds it, creates it, and keeps the quantities sane.

Cart::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Security $security, readonly RegionResolver $regions, readonly int $maxQuantity = 99, readonly ?ProductOptions $options = null)

Cart::customer()

public function customer(): ?User

Cart::of()

public function of(Store $store, bool $create = false): ?Order

The open cart for a store, or null if the member has none (and $create is false).

Cart::all()

public function all(): array
Returns

every open cart of the member, one per store

Cart::count()

public function count(): int

How many items the member's carts hold, for a badge.

Cart::add()

public function add(Product $product, int $quantity = 1, iterable $options = []): Order
$options

the options chosen (Product\OptionGroup), by id: a line per product and choice

Throws

CartException

Cart::update()

public function update(Order $order, OrderItem $line, int $quantity): void

Set a line's quantity; zero removes it.

@throws CartException

Cart::remove()

public function remove(Order $order, OrderItem $line): void
Throws

CartException

Cart::assertMine()

public function assertMine(Order $order): void
Throws

CartException

CartException class

class CartException extends RuntimeException CartException.php:6

Something the buyer should read; the message is a key in the "marketplace" domain.

CartException::__construct()

public function __construct(string $key, readonly array $parameters = [])

CartException::getParameters()

public function getParameters(): array

Checkout class

class Checkout Checkout.php:31

From a cart to an order: check it can still be bought, open a transaction, hand it to the payment method's gateway, and act on the answer.

paid the order is confirmed, stock goes down, OrderPaidEvent is dispatched (an application delivers what does not ship there); pending the order waits for its money - see ManualGateway; redirect the buyer goes to pay elsewhere; the gateway's return route calls confirm() when it comes back paid; refused the cart stays a cart, the transaction is cancelled.

Checkout::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PaymentGatewayRegistry $gateways, readonly EventDispatcherInterface $dispatcher, readonly Cart $cart, readonly string $defaultGateway = 'stripe')

Checkout::methodsFor()

public function methodsFor(Order $order): array
Returns

the methods able to take this order

Checkout::pay()

public function pay(Order $order, PaymentMethod $method): PaymentResult
Throws

CartException

Checkout::settle()

public function settle(Order $order, PaymentMethod $method): PaymentResult

pay() without asking who is logged in: for a payment the application makes on the customer's behalf, where nobody is - a purchase that a webhook completes, say. The caller vouches that the order is the customer's own and still a cart.

Throws

CartException

Checkout::confirm()

public function confirm(Order $order, Transaction $transaction): void

The money is in: confirm, take the stock, tell the application - once.

Confirmations come in pairs: the return page and the webhook arrive together, a webhook is retried, a buyer comes back from their history, an order already shipped or refunded is reported paid again. So the order's row is locked and whether it is already paid is read from the database, not from memory or the second-level cache: the second one finds it paid and does nothing - no second delivery (two licences, double hours), no stock taken twice, no refund undone.

And delivery commits with the confirmation: OrderPaidEvent's listeners run in the same transaction, so if one fails, nothing is confirmed and the provider's next try delivers - rather than an order confirmed with nothing delivered, which no retry would ever deliver.

The order and the transaction are locked, not reloaded: what the caller set on them before (a provider's reference) is kept, and saved either way.

Checkout::cancel()

public function cancel(Order $order, Transaction $transaction): PaymentCancelledEvent

The payment did not happen (cancelled, expired, refused later): back to the cart - unless the application takes it from there (the event).

CompanyRegistry class

class CompanyRegistry CompanyRegistry.php:20

Who a French company is, from its SIREN (9 digits) or SIRET (14), through Omnistate (glitchr/omnistate): the State's free register, API Recherche d'entreprises (omnistate/annuaire-entreprises: no key; INSEE's Sirene and the RNE - the same companies as Infogreffe's, without its fee). The number is checked here first (its length, its Luhn key), then looked up; Omnistate keeps the answer (omnistate.ttl, a day by default).

const FOUND = 'found'
const NOT_FOUND = 'not_found'
const INVALID = 'invalid'
const UNAVAILABLE = 'unavailable'

CompanyRegistry::__construct()

public function __construct(readonly Omnistate $omnistate, readonly ?LoggerInterface $logger = null)

CompanyRegistry::normalize()

public static function normalize(?string $number): string

The digits of a SIREN or SIRET as typed ("552 100 554 00054").

CompanyRegistry::isWellFormed()

public static function isWellFormed(?string $number): bool

A SIREN or a SIRET by its form: 9 or 14 digits, and its Luhn key (La Poste's SIRETs aside).

CompanyRegistry::lookup()

public function lookup(?string $number): array
Returns

FOUND with the company, or NOT_FOUND, INVALID (not a SIREN/SIRET), UNAVAILABLE (the register did not answer: not the visitor's fault)

CompanyRegistry::companyBadge()

public static function companyBadge(?string $siret, ?array $check): ?string

One line for the back office, from a stored check: "✓ Name - address" (verified, trading), "⚠ closed", "? not found", "… unchecked".

CreditException class

class CreditException extends RuntimeException CreditException.php:6

Not enough credit of that kind for what is asked.

public readonly string $kind
public readonly int $asked
public readonly int $balance

CreditException::__construct()

public function __construct(public readonly string $kind, public readonly int $asked, public readonly int $balance)

Credits class

class Credits Credits.php:16

Somebody's credits of one kind (Entity\Credit): credited by a pack bought or a plan's allowance, spent one use at a time. The balance is what the grants still valid gave, less everything spent - never below zero: what an expired grant had left is lost, what was spent stays spent.

Credits::__construct()

public function __construct(readonly EntityManagerInterface $entityManager)

Credits::grant()

public function grant(User $holder, string $kind, int $quantity, ?string $reason = null, ?\DateTimeImmutable $expiresAt = null, ?string $orderReference = null): Credit

Credits::balance()

public function balance(User $holder, string $kind, ?\DateTimeImmutable $at = null): int

Credits::spend()

public function spend(User $holder, string $kind, int $quantity = 1, ?string $reason = null, ?string $resourceType = null, int|string|null $resourceId = null): Credit

Spends $quantity, once: the holder's row is locked while the balance is read, so two uses cannot both take the last credit.

Throws

CreditException when the balance does not cover it

Credits::has()

public function has(User $holder, string $kind, int $quantity = 1): bool

Credits::refund()

public function refund(Credit $spent, ?string $reason = null): ?Credit

Gives back a spending (an answer that failed): a grant of the same size, without expiry.

EntitlementException class

class EntitlementException extends RuntimeException EntitlementException.php:6

What was asked is not granted, or none is left: the application offers an upgrade.

public readonly string $key

EntitlementException::__construct()

public function __construct(public readonly string $key, string $message = '')

Entitlements class

class Entitlements Entitlements.php:29

What somebody may do, from the rights they hold (Entity\Entitlement).

A grant is read by its kind:

a switch true in one active entitlement is enough: allows('export'); a value the highest-level entitlement's: value('commission'); a ceiling the largest among them: limit('guests') - 150 guests per event; a count the sum of them, less what was used: remaining('events.major'), consume() takes one, release() gives it back.

A resource narrows the question to the entitlements made for that one thing (a course, an event) plus those made for none.

Entitlements::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly ?EventDispatcherInterface $dispatcher = null)

Entitlements::grant()

public function grant(User $holder, string $code, array $grants = [], ?\DateTimeImmutable $expiresAt = null, array $context = []): Entitlement

Entitlements::active()

public function active(User $holder, ?string $resourceType = null, int|string|null $resourceId = null, ?\DateTimeImmutable $at = null): array

The rights held now, the highest level first.

Entitlements::holds()

public function holds(User $holder, string $code, ?string $resourceType = null, int|string|null $resourceId = null): bool

Whether they hold an entitlement of that code (for that resource): the right that is its own grant.

Entitlements::allows()

public function allows(User $holder, string $key, ?string $resourceType = null, int|string|null $resourceId = null): bool

A switch is on, or a count has some left.

Entitlements::value()

public function value(User $holder, string $key, mixed $default = null, ?string $resourceType = null, int|string|null $resourceId = null): mixed

The grant as the highest-level entitlement that has it says.

Entitlements::limit()

public function limit(User $holder, string $key, ?string $resourceType = null, int|string|null $resourceId = null): ?int

A ceiling: the largest among the active entitlements; null when none sets one.

Entitlements::remaining()

public function remaining(User $holder, string $key, ?string $resourceType = null, int|string|null $resourceId = null): int

A count: what all the active entitlements grant, less what was used.

Entitlements::consume()

public function consume(User $holder, string $key, int $quantity = 1, ?string $usedByType = null, int|string|null $usedById = null): Usage

Takes $quantity of a counted grant, from one entitlement that has as much left; what took it is named ($usedByType, $usedById) so release() finds it again. The entitlement's row is locked while counting: two requests cannot take the last one both.

Throws

EntitlementException when none has as much left

Entitlements::release()

public function release(User $holder, string $key, ?string $usedByType, int|string|null $usedById): int

Gives back what that thing had taken of a counted grant.

Entitlements::coveredBy()

public function coveredBy(User $holder, string $key, ?string $usedByType, int|string|null $usedById): ?Entitlement

The entitlement a thing took a counted grant from (the plan that covers an event), if any.

Entitlements::left()

public function left(Entitlement $entitlement, string $key): int

What one entitlement has left of a counted grant.

ExchangeRates class

final class ExchangeRates implements ResetInterface ExchangeRates.php:41

The exchange rates the shop converts with: the Forex table ("Taux de change" in the back office), one row per pair from the store's currency.

At the start of every request and command they are handed to base-bundle's Trading as its rates (addFallback): Order and OrderItem convert, the format_currency filter displays, and none of them asks a provider anything while a visitor's page is built - a paid API's monthly quota is not spent by visitors, and a slow provider slows no page.

refresh() asks for the day's rates and writes them in the table - on demand only, an administrator's action or a command. One HTTP call for every currency at once: Fixer.io when its key is in the settings (marketplace.forex.fixer; the free plan counts 100 calls a month), else the European Central Bank's reference rates, free and keyless. A rate set by hand stays until the next refresh.

Fixer's calls are counted per month (requestsThisMonth()) before they are sent - a failed one counts at Fixer too - and a refresh comes at most once every MIN_INTERVAL, so a double click or an impatient administrator never spends the quota twice. Fixer is asked only for the currencies wanted.

const FIXER_KEY = 'marketplace.forex.fixer'
const FIXER_QUOTA = 100
const MIN_INTERVAL = '1 hour'

ExchangeRates::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly TradingInterface $trading, readonly HttpClientInterface $http, readonly string $currency, readonly ?SettingBagInterface $settings = null, readonly array $targets = [])

ExchangeRates::load()

public function load(): void

The table, as Trading's rates: once per request or command.

ExchangeRates::reset()

public function reset(): void

A worker serves many requests: each reads the table again.

ExchangeRates::rates()

public function rates(): array
Returns

the rates from the store's currency, by target

ExchangeRates::rate()

public function rate(string $target): ?float

The rate from the store's currency to $target, from the table; null when there is none.

ExchangeRates::refresh()

public function refresh(array $targets = []): array

Asks the provider for the day's rates - one HTTP call - and writes them, from the store's currency to every currency the shop uses (its stores, regions and products), to the configured marketplace.forex.targets and to the $targets given.

Returns

the rates written

Throws

ExchangeRatesException when it is too soon, or the provider does not answer with rates

ExchangeRates::lastRefresh()

public function lastRefresh(): ?\DateTimeImmutable

When the rates were last asked for (Fixer or the ECB); null before the first time.

ExchangeRates::requestsThisMonth()

public function requestsThisMonth(): int

Fixer's calls this calendar month, as counted here.

ExchangeRates::usesFixer()

public function usesFixer(): bool

Whether a key makes refresh() ask Fixer (else the European Central Bank).

ExchangeRatesException class

final class ExchangeRatesException extends RuntimeException ExchangeRatesException.php:6

Why the exchange rates were not refreshed: no key, too soon, the provider's refusal.

..

Invoices class

class Invoices Invoices.php:43

The shop's invoices: issued for a paid order (issue()), cancelled by a credit note (credit()), sent by e-mail (send()), marked paid; and their documents - the PDF (@Marketplace/invoice/invoice.pdf.twig, a site's templates/bundles/MarketplaceBundle/invoice/invoice.pdf.twig over it) carrying its Factur-X XML.

$invoice = $invoices->issue($order); // F-2026-000041, frozen $pdf = $invoices->pdf($invoice); // PDF/A-3 + factur-x.xml $creditNote = $invoices->credit($invoice, 'Retour du colis');

With marketplace.invoice.auto_issue, an order's invoice is issued when it is paid (EventListener\InvoiceOnPaymentListener).

With glitchr/omnibill, send() goes through its gateway (marketplace.invoice.gateway: omnibill/email by default, an approved platform later) and the invoice keeps where it stands there (Invoice\Transmission\InvoiceTransmission); without it, send() mails the invoice itself.

Invoices::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly InvoiceComposer $composer, readonly InvoiceNumbering $numbering, readonly FacturX $facturX, readonly Environment $twig, readonly UrlGeneratorInterface $router, readonly UriSigner $signer, readonly ?MailerInterface $mailer = null, readonly ?TranslatorInterface $translator = null, readonly string $prefix = 'F', readonly string $creditPrefix = 'A', readonly int $paymentDays = 30, readonly ?InvoiceTransmission $transmission = null)

Invoices::repository()

public function repository(): InvoiceRepository

Invoices::of()

public function of(Order $order): ?Invoice

The order's invoice that stands, if it has one.

Invoices::issue()

public function issue(Order $order, ?\DateTimeImmutable $at = null): Invoice

The invoice of an order: issued once, for an order paid or waiting for its payment (a cart is not invoiced). An order whose invoice was cancelled by a credit note may be invoiced again.

Throws

LogicException for a cart, or an order that has its invoice

Invoices::credit()

public function credit(Invoice $invoice, ?string $reason = null, ?\DateTimeImmutable $at = null): Invoice

The credit note that cancels an invoice, whole: its lines and amounts, its seller and buyer as the invoice has them, its own number in the credit notes' series; the invoice is cancelled by it.

Invoices::markPaid()

public function markPaid(Invoice $invoice, ?\DateTimeImmutable $at = null): void

Invoices::gateway()

public function gateway(): ?string

The gateway invoices go through (glitchr/omnibill), null when they are mailed by this bundle.

Invoices::lifecycle()

public function lifecycle(Invoice $invoice): ?string

Where the invoice stands on that gateway, in words ("Encaissée (email)"); null when it went through none.

Invoices::refresh()

public function refresh(Invoice $invoice): bool

Asks the gateway where the invoice stands; false when it went through none.

Invoices::html()

public function html(Invoice $invoice): string

The invoice's page as the PDF prints it (HTML).

Invoices::pdf()

public function pdf(Invoice $invoice): string

The invoice as a PDF, its Factur-X XML attached when horstoeko/zugferd is installed.

Invoices::xml()

public function xml(Invoice $invoice): string

Invoices::filename()

public function filename(Invoice $invoice): string

Invoices::signedUrl()

public function signedUrl(Invoice $invoice, int $ttl = 2592000): string

The invoice's address for whoever holds the link (a mail, a page): signed, valid $ttl seconds.

Invoices::send()

public function send(Invoice $invoice, ?string $to = null): void

Sent to its buyer, the PDF attached: through the omnibill gateway when there is one (its statuses then kept on the invoice), by this bundle's own e-mail otherwise. Marked sent.

Pickups class

class Pickups Pickups.php:27

Handing an order over without the post, or beside it (Entity\Order\Pickup): which ways the shop offers (marketplace.pickup.modes), where it brings things itself (zip_codes: "67000", or "67*" for all that start so), the days and the slots it gives, then the hand-over opened on an order and moved along until it is done.

What may travel how is the trade's business - a caterer's chilled dishes, a florist's bouquets: the application (or its trade's bundle) filters the modes before calling open().

Pickups::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PickupRepository $pickups, readonly EventDispatcherInterface $dispatcher, readonly UrlGeneratorInterface $router, readonly array $modes = ['pickup'], readonly array $zipCodes = [], readonly array $slots = ['from' => '11:00', 'to' => '19:00', 'step' => 30], readonly int $notice = 60, readonly int $horizon = 14, readonly ?string $timezone = null)

Pickups::modes()

public function modes(): array
Returns

the ways this shop hands orders over

Pickups::offers()

public function offers(PickupMode $mode): bool

Pickups::deliversTo()

public function deliversTo(?string $postcode, ?array $zipCodes = null): bool

Whether the shop brings orders to this postcode itself. No list: nowhere.

Pickups::now()

public function now(): \DateTimeImmutable

The present, on the shop's clock (marketplace.pickup.timezone; PHP's zone without one).

Pickups::slots()

public function slots(\DateTimeImmutable $day, ?\DateTimeImmutable $now = null): array

The slots of a day, "12:00-12:30": every step minutes between from and to, those already gone today (and the notice the shop needs) left out.

Pickups::days()

public function days(?\DateTimeImmutable $now = null): array
Returns

the days an order may be for: from today (while a slot is left) to the horizon

Pickups::of()

public function of(Order $order): ?Pickup

Pickups::open()

public function open(Order $order, PickupMode $mode, \DateTimeImmutable $day, array $details = [], bool $check = true): Pickup

The hand-over of an order, opened (or opened again while it is still a cart): the mode, the day, and who - $details holds contactName, email, phone, slot, address, postcode, city, country, note, token.

Throws

CartException with a key of the marketplace translations (pickup.error.*)

Pickups::move()

public function move(Pickup $pickup, PickupStatus $status, bool $flush = true): Pickup

Moves a hand-over along and tells the application (PickupChangedEvent); the same status again is nothing.

Pickups::trackingUrl()

public function trackingUrl(Pickup $pickup, int $referenceType = UrlGeneratorInterface::ABSOLUTE_URL): string

The page that follows it, for whoever holds the link.

Pricing class

final class Pricing implements ResetInterface Pricing.php:41

Prices a cart: the promotions running now, then the coupons the member entered, through the discounts' own rules, scopes and actions.

rules must all hold for the order (a minimum total, a product in the cart, a quantity...) - compliesWith() scopes which lines a line-level action touches (a store, a product, a taxon...) - contains(); no scope means every line actions what comes off (a percentage, a fixed amount) - apply(); an action applying to items cuts each line in scope, otherwise it cuts the order

A coupon for "individual use" stands alone: no promotion, no other coupon. Nothing is ever cut below zero. Paid orders are never repriced.

Prices are stored before VAT; each line's VAT is the most specific rate whose scopes hold its product - see vatRateFor() - unless the order is exempt (VatExemptionInterface: a reverse charge, an export).

Pricing::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly iterable $exemptions = [])

Pricing::reset()

public function reset(): void

Pricing::reprice()

public function reprice(Order $order): void

Pricing::vatRateFor()

public function vatRateFor(Product $product, ?Region $region = null, ?Order $order = null): float

The VAT rate a product sells at (0.055 for 5.5 %): the most specific VAT whose scopes hold it, else the one of the region given (or the order's). 0 when none does, and in an order exempt from VAT.

Pricing::vatRatesOf()

public function vatRatesOf(Order $order): array

The VAT rates an order's lines sell at, each once, lowest first (none for an exempt order): "TVA (20 %)" on a receipt when there is one.

Pricing::priceWithVat()

public function priceWithVat(Product $product, ?Region $region = null, ?Order $order = null): int

A product's unit price with its VAT, in cents: what a buyer is shown.

Without an order, the VAT is the product's own (an anonymous visitor sees prices VAT included); in an exempt order, none.

Pricing::applyCoupon()

public function applyCoupon(Order $order, string $code, ?object $customer): Coupon

Add a coupon to a cart.

Throws

CartException coupon.error.*

Pricing::removeCoupon()

public function removeCoupon(Order $order, Coupon $coupon): void

ProductOptions class

class ProductOptions ProductOptions.php:15

Checks what a buyer chose among a product's options (Product\OptionGroup): each option is one of the product's and can be had, a single-choice group holds one, every group holds between its minimum and its maximum. A group left untouched takes its preselected options.

ProductOptions::select()

public function select(Product $product, iterable $chosen = []): OptionSelection
$chosen

option ids (or the options)

Throws

CartException options.error.unknown, .unavailable, .single, .minimum, .maximum

QuickOrder class

class QuickOrder QuickOrder.php:35

An order in one step, with no account to open and no basket to fill: products, an e-mail address, the payment.

The address becomes the order's customer - the member it already belongs to, or a new one whose password nobody knows - because an order has one; nobody is signed in. Checkout::settle() takes the payment on that customer's behalf, with the first payment method able to (the shop's default gateway first); the provider's return and its webhook confirm it (QuickOrderController, PaymentController), and OrderPaidEvent delivers as for any order.

The buyer then follows the order on a page of its own (doneUrl()): a signed link, shown after the payment and good to mail - whoever holds it sees the order, so what an application adds to that page (QuickOrderDoneEvent: files to download, a pickup time) is for the holder of the link.

QuickOrder::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly RegionResolver $regions, readonly Pricing $pricing, readonly Checkout $checkout, readonly UriSigner $signer, readonly UrlGeneratorInterface $router, readonly bool $enabled = true, readonly int $linkTtl = 2592000, readonly ?LoggerInterface $logger = null)

QuickOrder::isEnabled()

public function isEnabled(): bool

QuickOrder::buy()

public function buy(array|Product $lines, string $email, ?User $signedIn = null): QuickPayment

One order per call, for one store: the lines, priced, and its payment begun.

Throws

CartException with a key of the marketplace translations (quick.error.*)

QuickOrder::doneUrl()

public function doneUrl(Order $order): string

The page of this order for whoever holds the link: signed, valid marketplace.quick_order.link_ttl seconds.

QuoteStatusGuard class

final class QuoteStatusGuard QuoteStatusGuard.php:10

Small predicates on a quote's life the controllers and the voter share.

QuoteStatusGuard::isAwaitingPayment()

public static function isAwaitingPayment(AbstractQuote $quote): bool

Accepted, its order (or one-off product) made, not paid yet: going back to checkout is allowed.

QuoteToOrder class

class QuoteToOrder QuoteToOrder.php:30

The client accepts a quote: it becomes an order of its own, at the quote's prices - each line a product of the catalogue (or a one-off product for a free line), its lots counted in units, the quote's discount in each price - delivered where the quote says (an export's order carries no VAT: Pricing\ExportExemption), waiting in the client's carts to be paid like any other (a transfer, a card).

omnibase/forge extends it: a studio's quote becomes one HourPack.

QuoteToOrder::__construct()

public function __construct(protected readonly EntityManagerInterface $entityManager, protected readonly ?Pricing $pricing = null, protected readonly ?RegionResolver $regions = null, protected readonly ?string $storeSlug = null)

QuoteToOrder::accept()

public function accept(AbstractQuote $quote, User $client): Order
Throws

DomainException quote.error.not_acceptable

QuoteToOrder::storeOf()

public function storeOf(Quote $quote): Store

The store the order is made in: the quote's, its first product's, else marketplace.quotes.store.

QuoteToOrder::itemsOf()

public function itemsOf(Quote $quote): array

The order's lines: [product, quantity, unit price after the discount, comment] - pure, for the tests and the page.

ReferralException class

class ReferralException extends RuntimeException ReferralException.php:6

A referral that cannot be: its own code, an unknown one, a member already referred. The reason is its message.

Referrals class

class Referrals Referrals.php:41

Referrals, for any shop: each member has a code; somebody who signs up through it is their referee and gets a welcome coupon; once the referee's first order is paid and has held for the cooling-off period, the referrer is rewarded - a coupon, or credits.

Against abuse: no referral of oneself (the same account, the same e-mail address once its "+tag" and a Gmail's dots are taken off, the same card when the provider's fingerprint is known), a ceiling of rewards per month, a refunded order qualifies nothing, and any referral may be rejected in review before its reward leaves.

The coupons are made on the shop's own discount adapters (a scope, an action, by their codes): without them in the database, no coupon.

Referrals::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Credits $credits, readonly ?EventDispatcherInterface $dispatcher = null, readonly bool $enabled = true, readonly int $coolingDays = 14, readonly int $monthlyCap = 10, readonly array $referee = [], readonly array $referrer = [])

Referrals::isEnabled()

public function isEnabled(): bool

Referrals::codeFor()

public function codeFor(User $member): ReferralCode

A member's code, made the first time it is asked.

Referrals::find()

public function find(string $code): ?ReferralCode

Referrals::referralOf()

public function referralOf(User $referee): ?Referral

Referrals::attribute()

public function attribute(string $code, User $referee): Referral

A new member came through a code: they are its owner's referee, and get their welcome (a coupon, when configured).

Throws

ReferralException disabled, unknown, self, email, already, customer

Referrals::onOrderPaid()

public function onOrderPaid(Order $order): ?Referral

An order is paid: when it is the first of a referee whose referral waits, the referral qualifies - or is refused.

Referrals::release()

public function release(?\DateTimeImmutable $now = null): array

The referrals whose order has held for the cooling-off period: their referrers are rewarded - unless the order was refunded meanwhile, or the referrer reached the month's ceiling.

Referrals::reject()

public function reject(Referral $referral, string $reason = 'review'): void

In review, before its reward leaves.

Referrals::rewardsOf()

public function rewardsOf(User $beneficiary): array

Referrals::referralsBy()

public function referralsBy(User $referrer): array
Returns

those who came through this member's code

Referrals::canonicalEmail()

public static function canonicalEmail(string $email): string

"Lea.Martin+promo@GoogleMail.com" and "leamartin@gmail.com" are one person.

RegionResolver class

class RegionResolver RegionResolver.php:16

Every order belongs to a sales region (taxes, shipping and currency rules hang off it). A store that sells everywhere in one currency has no reason to configure one, so: the store's first region, else one region per currency, created the first time it is needed.

RegionResolver::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly string $defaultCurrency = 'EUR')

RegionResolver::for()

public function for(?Store $store): Region

Shipping class

final class Shipping Shipping.php:38

Posting physical goods: whether an order needs it, the methods that can carry it and what each costs, the address it goes to, and the shipment staff record when it leaves.

Rates: a flat rate costs its unit price once per order; a priority rate costs its unit price per shipping unit (weight-based when products have one, else one per item); an international rate is flat. A method in a currency other than the order's is not offered. What the buyer pays is set by hand on the method - the shop's price - whatever the carrier charges the shop.

The carrier itself is glitchr/omnibus's: a ShippingMethod names a gateway configured under omnibus.gateways (gatewayName), and when that package is installed the shipment is booked there (book(): the label, the tracking number on the Shipment) and followed (track()). The sender is marketplace.shipping.sender.

const OUT_OF_ZONE = 'shipping.error.out_of_zone'

What apply() answers for a country none of the store's regions holds: the buyer asks for a quote instead.

Shipping::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly ?ParameterBagInterface $parameters = null, readonly ?Carriers $carriers = null)

Shipping::deliversTo()

public function deliversTo(Order $order, string $country): bool

Whether the shop sells by post to this country: one of its store's regions (or the order's) lists it - or none lists any country, and the shop goes everywhere. A quote's order goes where its quote says.

Shipping::needsShipping()

public function needsShipping(Order $order): bool

Shipping::optionsFor()

public function optionsFor(Order $order): array

Shipping::chargeFor()

public function chargeFor(ShippingMethod $method, Order $order): int

Shipping::addressOf()

public function addressOf(Order $order): array

The address the order goes to, or the member's last one, as form values.

Shipping::apply()

public function apply(Order $order, array $fields, int $methodId): ?string

Put the address and the chosen method on the order.

Returns

an error key (shipping.error.*), or null when all is set

Shipping::ship()

public function ship(Order $order, string $trackingNumber): Shipment

Staff send the parcel: a shipment with its tracking number, the order marked shipped.

Shipping::queue()

public function queue(): array
Returns

paid orders with an address that have not left yet

Shipping::trackingUrl()

public static function trackingUrl(?ShippingMethod $method, ?string $number): ?string

Shipping::carrierFor()

public function carrierFor(?ShippingMethod $method): ?Carrier

The omnibus carrier the method names (its gatewayName), when that package is installed and the gateway configured.

Shipping::consignmentFor()

public function consignmentFor(Order $order, ?ShippingMethod $method = null): Consignment

The order as a carrier sees it: from the shop's sender to the buyer's address, one parcel.

Shipping::ratesFor()

public function ratesFor(Order $order, ShippingMethod $method): array

What the carrier's own tariff says for the order, for information: the buyer pays chargeFor().

Shipping::book()

public function book(Shipment $shipment): Label

The shipment booked with its carrier: the label, the tracking number on the shipment.

Shipping::track()

public function track(Shipment $shipment, string $locale = 'fr'): ?Tracking

Where the carrier says the shipment is; null when it names no carrier.

Shipping::parcelFor()

public function parcelFor(Order $order): Parcel

The parcel: the shippable items' weights (grams) and the order's value.

Shipping::sender()

public function sender(): Address

The shop's address, marketplace.shipping.sender.

Subscriptions class

class Subscriptions Subscriptions.php:25

The subscriptions' life: what the provider tells (a renewal, a payment that failed, an end) is applied to the Subscription kept here, a subscriber stops theirs or opens the provider's portal, and marketplace:subscriptions announces the rights that end - a pass run out or a subscription stopped alike.

Subscriptions::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly PaymentGatewayRegistry $gateways, readonly ?EventDispatcherInterface $dispatcher = null, readonly ?Credits $credits = null, readonly int $reminderDays = 7)

Subscriptions::find()

public function find(string $gateway, string $providerReference): ?Subscription

Subscriptions::apply()

public function apply(string $gateway, ProviderSubscription $remote): ?Subscription

The provider's subscription as it stands, applied to ours; null when we do not know it.

Subscriptions::refresh()

public function refresh(Subscription $subscription): Subscription

Asks the provider where it stands and applies it.

Subscriptions::cancel()

public function cancel(Subscription $subscription, bool $atPeriodEnd = true): Subscription

Stops it: at the end of the period paid (what was paid for is kept until then), or at once.

Subscriptions::portalUrl()

public function portalUrl(Subscription $subscription, string $returnUrl, ?string $locale = null): string

The provider's page where the subscriber changes their card, reads their invoices, stops.

Subscriptions::sweep()

public function sweep(?\DateTimeImmutable $now = null): array

The rights that have ended and were not told yet: each is announced once (EntitlementEndedEvent). And those that end within marketplace.plans.reminder_days: announced once too (EntitlementEndingEvent).

Supply class

class Supply Supply.php:29

What is made to order, handed to who makes it. Once an order is paid, its lines whose product names a supplier are grouped by supplier and by recipient - each line may have its own (OrderItem::$recipient: a card sent to each guest), else the order's shipping address - and each group is one SupplyJob submitted to its supplier. The jobs then follow what the suppliers say (their webhook, a workshop's page, sync()).

A supplier that fails does not undo the payment: its job is kept FAILED with the reason, to be sent again (resubmit()).

Supply::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly SupplierRegistry $suppliers, readonly ?EventDispatcherInterface $dispatcher = null, readonly ?LoggerInterface $logger = null)

Supply::dispatch()

public function dispatch(Order $order, bool $draft = false): array

The jobs of an order, made and submitted; none when nothing in it is made to order, or when they exist already.

Supply::resubmit()

public function resubmit(SupplyJob $job, bool $draft = false): SupplyJob

A job that failed, sent again.

Supply::confirm()

public function confirm(SupplyJob $job): SupplyJob

A draft launched.

Supply::sync()

public function sync(SupplyJob $job): SupplyJob

Asks its supplier where it stands.

Supply::cancel()

public function cancel(SupplyJob $job): SupplyJob

Supply::apply()

public function apply(SupplyResult $result): ?SupplyJob

A supplier's word (its webhook, its page): applied to the job it is about, when we know it.

Supply::jobsOf()

public function jobsOf(Order $order): array

Supply::find()

public function find(string $reference): ?SupplyJob

VatNumbers class

class VatNumbers VatNumbers.php:21

Intra-EU VAT numbers - a customer's, a store's - checked with the European Commission's VIES through Omnistate (glitchr/omnistate, omnistate/vies) when they are given, never while a page is built. A SIREN or a SIRET is enough for a French business: its VAT number is its SIREN with a key.

Asked with the shop's own VAT number (omnistate.requester), VIES answers a consultation number: the proof a reverse-charge invoice was checked. Nothing is flushed here.

const CONFIRMED = 'confirmed'
const REMOVED = 'removed'
const NOT_A_NUMBER = 'not_a_number'
const UNKNOWN = 'unknown'
const UNAVAILABLE = 'unavailable'

VatNumbers::__construct()

public function __construct(readonly Omnistate $omnistate)

VatNumbers::check()

public function check(string $typed): array

What VIES says of a number as typed.

Returns

CONFIRMED, NOT_A_NUMBER (no member state writes it that way: VIES is not asked), UNKNOWN, or UNAVAILABLE (VIES, or the member state's register, did not answer: not the number's fault); $number as VIES writes it ("DE123456789"), null when it is not one

VatNumbers::confirm()

public function confirm(VatCustomerInterface $customer, ?string $typed): array

A customer's number: set when VIES knows it, taken away when $typed is empty, left as it was otherwise.

Returns

as check(), or REMOVED

Base\Marketplace\Settings

PaymentKeysSection class

final class PaymentKeysSection implements SettingsSectionInterface PaymentKeysSection.php:16

The shop's keys on omnibase/admin's API keys page: Stripe's, when the "stripe" gateway of glitchr/omnitrade is there. Typed there, they win over the configuration (api.payment_method.<gateway>.<option>, read by Payment\Omnitrade\OmnitradeGateways) - the applications no longer list them in a SystemController of their own.

PaymentKeysSection::__construct()

public function __construct(readonly ?\Omnitrade\Registry $gateways = null)

PaymentKeysSection::getPage()

public function getPage(): string

PaymentKeysSection::getFields()

public function getFields(): array

Base\Marketplace\Supply

GelatoSupplier class

class GelatoSupplier implements SupplierInterface GelatoSupplier.php:34

Gelato, print on demand: cards, mugs, tote bags, textile, photo books, made near their recipient. Its Order API v4 (https://order.gelatoapis.com, the key in X-API-KEY): an order has one shipping address, items naming a productUid and the files to print (public addresses Gelato fetches), and is sent launched ("order") or as a "draft" confirmed later.

marketplace: supply: gelato: { api_key: '%env(GELATO_API_KEY)%', webhook_secret: '%env(GELATO_WEBHOOK_SECRET)%' }

A Product's supplierReference is the productUid ("cards_pf_a5_pt_350-gsm-coated-silk_cl_4-4_ver").

The webhook (order_status_updated) is checked against webhook_secret when one is set: Gelato sends what you configure as the endpoint's authorization header; compared to it as given.

const ORDER_API = 'https://order.gelatoapis.com'
const PRODUCT_API = 'https://product.gelatoapis.com'
const SETTING = 'api.supply.gelato.api_key'

GelatoSupplier::__construct()

public function __construct(readonly HttpClientInterface $http, readonly ?string $apiKey = null, readonly ?string $webhookSecret = null, readonly string $catalog = 'cards', readonly ?SettingBagInterface $settings = null)

GelatoSupplier::name()

public static function name(): string

GelatoSupplier::isConfigured()

public function isConfigured(): bool

GelatoSupplier::products()

public function products(?string $query = null): array

GelatoSupplier::quote()

public function quote(SupplyOrder $order): SupplyQuote

GelatoSupplier::submit()

public function submit(SupplyOrder $order, bool $draft = false): SupplyResult

GelatoSupplier::confirm()

public function confirm(string $reference): SupplyResult

GelatoSupplier::fetch()

public function fetch(string $reference): SupplyResult

GelatoSupplier::cancel()

public function cancel(string $reference): SupplyResult

GelatoSupplier::notify()

public function notify(string $body, array $headers = []): ?SupplyResult

GelatoSupplier::result()

public function result(array $order): SupplyResult

Gelato's order (or its status event) as a SupplyResult.

GelatoSupplier::status()

public static function status(string $fulfillment, string $orderType = 'order'): SupplyStatus

OfflineSupplier class

class OfflineSupplier implements SupplierInterface OfflineSupplier.php:34

A supplier without an API: the shop's partner workshop, a local printer.

An order reaches them as a brief by e-mail - what to make, from which files, for whom - with a signed link to a page where they accept it, say where it stands and give the parcel's tracking (Controller\Client\ SupplyController); nothing to install on their side.

marketplace:
    supply:
        offline: { email: 'atelier@example.org', name: 'Atelier Dupont', link_ttl: 7776000 }

What it makes is whatever the shop's products say: a Product's supplierReference is the workshop's own name for it.

OfflineSupplier::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly UrlGeneratorInterface $urls, readonly UriSigner $signer, readonly ?MailerInterface $mailer = null, readonly ?string $email = null, readonly ?string $partner = null, readonly int $linkTtl = 7776000, readonly ?TranslatorInterface $translator = null)

OfflineSupplier::name()

public static function name(): string

OfflineSupplier::isConfigured()

public function isConfigured(): bool

OfflineSupplier::products()

public function products(?string $query = null): array

OfflineSupplier::quote()

public function quote(SupplyOrder $order): SupplyQuote

OfflineSupplier::submit()

public function submit(SupplyOrder $order, bool $draft = false): SupplyResult

OfflineSupplier::confirm()

public function confirm(string $reference): SupplyResult

OfflineSupplier::fetch()

public function fetch(string $reference): SupplyResult

What the workshop last said on its page: kept on the job.

OfflineSupplier::cancel()

public function cancel(string $reference): SupplyResult

OfflineSupplier::notify()

public function notify(string $body, array $headers = []): ?SupplyResult
public function link(string $reference): string

The workshop's page for a job: signed, valid marketplace.supply.offline.link_ttl seconds (90 days).

SupplierInterface interface

interface SupplierInterface SupplierInterface.php:20

Somebody who makes what the shop sells and sends it to the buyer - a print-on-demand service, a local workshop. A Product names its supplier (Product::$supplier) and its reference there; once an order is paid, Service\Supply hands its lines to their suppliers.

Services implementing this interface are tagged marketplace.supplier and found by SupplierRegistry: an application adds a supplier by writing a class. One that does not do something throws SupplyException.

SupplierInterface::name()

public static function name(): string

What a Product's supplier holds: "gelato", "offline".

SupplierInterface::isConfigured()

public function isConfigured(): bool

Whether it has what it needs to run (a key, an address).

SupplierInterface::products()

public function products(?string $query = null): array
Returns

what it makes, matching a search when given

SupplierInterface::quote()

public function quote(SupplyOrder $order): SupplyQuote

What the order would cost the shop.

SupplierInterface::submit()

public function submit(SupplyOrder $order, bool $draft = false): SupplyResult

Sends the order: launched, or as a draft the supplier keeps until confirmed.

SupplierInterface::confirm()

public function confirm(string $reference): SupplyResult

Launches a draft.

SupplierInterface::fetch()

public function fetch(string $reference): SupplyResult

SupplierInterface::cancel()

public function cancel(string $reference): SupplyResult

SupplierInterface::notify()

public function notify(string $body, array $headers = []): ?SupplyResult

A webhook of the supplier's, read; null when it concerns no order.

SupplierRegistry class

class SupplierRegistry SupplierRegistry.php:8

The suppliers, by name: the bundle's (gelato, offline) and the application's.

SupplierRegistry::__construct()

public function __construct(iterable $suppliers)

SupplierRegistry::get()

public function get(?string $name): ?SupplierInterface

SupplierRegistry::names()

public function names(): array

SupplierRegistry::configured()

public function configured(): array
Returns

those that can run

SupplyException class

class SupplyException extends RuntimeException SupplyException.php:6

A supplier refused, did not answer, or does not do what was asked.

public readonly string $supplier

SupplyException::__construct()

public function __construct(public readonly string $supplier, string $message, ?\Throwable $previous = null)

Base\Marketplace\Supply\Model

SupplyLine class

final readonly class SupplyLine SupplyLine.php:10

One thing to make: the supplier's own product (a Gelato productUid, a partner's reference), how many, and the files it is printed from - one per printable side, as public addresses the supplier fetches.

public string $reference

Ours: the order item's id.

public string $productReference
public int $quantity
public array $files

addresses of the print files (PDF, PNG)

public ?string $title
public array $options

the personalisation in words: a text, a monogram, a paper

SupplyLine::__construct()

public function __construct(public string $reference, public string $productReference, public int $quantity = 1, public array $files = [], public ?string $title = null, public array $options = [])
$files

addresses of the print files (PDF, PNG)

$options

the personalisation in words: a text, a monogram, a paper

SupplyOrder class

final readonly class SupplyOrder SupplyOrder.php:6

What a supplier is asked: lines, for one recipient.

public string $reference

Ours, unique: the supplier keeps it and gives it back ("CMD-1042-1").

public array $lines
public SupplyRecipient $recipient
public string $currency
public ?string $shippingMethod

The supplier's shipping method, when one is insisted on; else its cheapest.

public ?string $customerReference

Who the order is for, for the supplier's records.

public array $metadata

SupplyOrder::__construct()

public function __construct(public string $reference, public array $lines, public SupplyRecipient $recipient, public string $currency = 'EUR', public ?string $shippingMethod = null, public ?string $customerReference = null, public array $metadata = [])

SupplyProduct class

final readonly class SupplyProduct SupplyProduct.php:6

Something a supplier makes: its reference there (what a Product's supplierReference holds) and its name.

public string $reference
public string $title
public array $raw

SupplyProduct::__construct()

public function __construct(public string $reference, public string $title, public array $raw = [])

SupplyQuote class

final readonly class SupplyQuote SupplyQuote.php:6

What a supply order would cost the shop, in minor units: the making, the posting.

public int $products
public int $shipping
public string $currency
public ?int $minDays

Days until it is delivered, when the supplier says.

public ?int $maxDays
public ?string $shippingMethod
public array $raw

SupplyQuote::__construct()

public function __construct(public int $products, public int $shipping, public string $currency = 'EUR', public ?int $minDays = null, public ?int $maxDays = null, public ?string $shippingMethod = null, public array $raw = [])

SupplyQuote::total()

public function total(): int

SupplyRecipient class

final readonly class SupplyRecipient SupplyRecipient.php:6

Who receives what is made: one address per supply order (a batch for the buyer, or each guest's own).

public string $name
public array $street
public string $postcode
public string $city
public string $country
public ?string $email
public ?string $phone
public ?string $company
public ?string $state

SupplyRecipient::__construct()

public function __construct(public string $name, public array $street, public string $postcode, public string $city, public string $country = 'FR', public ?string $email = null, public ?string $phone = null, public ?string $company = null, public ?string $state = null)

SupplyRecipient::fromArray()

public static function fromArray(array $data): self

SupplyRecipient::toArray()

public function toArray(): array

SupplyRecipient::firstName()

public function firstName(): string

"Marie" of "Marie Dupont de la Tour".

SupplyRecipient::lastName()

public function lastName(): string

SupplyRecipient::isComplete()

public function isComplete(): bool

SupplyRecipient::key()

public function key(): string

What tells two recipients apart: lines for the same one travel together.

SupplyResult class

final readonly class SupplyResult SupplyResult.php:8

Where a supply order stands, as its supplier says: its reference there, its state, its parcel.

public string $supplier
public string $reference

The supplier's id for it.

public SupplyStatus $status
public ?string $trackingNumber
public ?string $trackingUrl
public ?string $carrier
public ?string $message
public ?string $orderReference

Ours, when the supplier gives it back.

public array $raw

SupplyResult::__construct()

public function __construct(public string $supplier, public string $reference, public SupplyStatus $status, public ?string $trackingNumber = null, public ?string $trackingUrl = null, public ?string $carrier = null, public ?string $message = null, public ?string $orderReference = null, public array $raw = [])

Base\Marketplace\Twig

CatalogueTwigExtension class

final class CatalogueTwigExtension extends AbstractExtension CatalogueTwigExtension.php:25

The catalogue's pages from any template:

{% if marketplace_age_gate(product) %}{% include '@Marketplace/client/_age_gate.html.twig' %}{% endif %} {{ marketplace_age_minimum() }} 18, 20 in Japanese... {{ marketplace_age_notice() }} the health notice, or null {% for row in marketplace_attributes(product) %}{{ row.label }}: {{ row.value }}{% endfor %} {% for a in marketplace_associations(product, 'pairing') %}{{ a.target }} - {{ a.note(app.request.locale) }}{% endfor %} {% for product in marketplace_products_of(post) %}…{% endfor %} a blog post's wines

CatalogueTwigExtension::__construct()

public function __construct(readonly AgeGate $ageGate, readonly AttributeSetRepository $sets, readonly EntityManagerInterface $entityManager)

CatalogueTwigExtension::getFunctions()

public function getFunctions(): array

CatalogueTwigExtension::attributes()

public function attributes(Product $product, ?string $locale = null): array

A product's sheet: the visible fields of its set, in order, with their value in this language (a variant's own, else its principal's).

CatalogueTwigExtension::associations()

public function associations(Product $product, string|AssociationType|null $type = null): array
Returns

what a product leads to, of a type when given ("pairing", "cross_sell", "upsell")

CatalogueTwigExtension::productsOf()

public function productsOf(Thread $thread): array

The products a thread (a blog post, an event) features: those it names among its connexes, and those naming it among theirs.

InvoiceTwigExtension class

final class InvoiceTwigExtension extends AbstractExtension InvoiceTwigExtension.php:24

What an invoice's page prints its amounts with: an integer in the currency's smallest unit, written as the seller's language writes money.

{{ invoice.total|invoice_money(invoice.currency) }} 1 234,56 € {{ line.rate|invoice_rate }} 20 % / 5,5 %

And an order's invoices and credit notes, oldest first, for its page:

{% for invoice in marketplace_order_invoices(order) %}...{% endfor %}

InvoiceTwigExtension::__construct()

public function __construct(readonly ?EntityManagerInterface $entityManager = null)

InvoiceTwigExtension::getFunctions()

public function getFunctions(): array

InvoiceTwigExtension::ofOrder()

public function ofOrder(Order $order): array

InvoiceTwigExtension::getFilters()

public function getFilters(): array

InvoiceTwigExtension::money()

public function money(int|float|null $amount, string $currency, string $locale = 'fr_FR'): string

InvoiceTwigExtension::rate()

public function rate(int|float|null $rate, string $locale = 'fr_FR'): string

MarketplaceTwigExtension class

final class MarketplaceTwigExtension extends AbstractExtension MarketplaceTwigExtension.php:21

What the shop's pages need from any template: the number of lines waiting in the visitor's carts, for the badge next to the cart link; and prices as a buyer is shown them, VAT included (prices are stored before VAT).

{{ marketplace_price_with_vat(product)|... }} cents, VAT included {{ marketplace_vat_rate(product) }} 0.055 for 5.5 % {{ marketplace_vat_rates(order) }} an order's rates, each once {{ marketplace_price_tax() }} the mention after a price (marketplace.price_tax): 'excl', 'incl' or null

MarketplaceTwigExtension::__construct()

public function __construct(readonly Cart $cart, readonly Pricing $pricing, readonly ?string $priceTax = null)

MarketplaceTwigExtension::priceTax()

public function priceTax(): ?string

MarketplaceTwigExtension::getFunctions()

public function getFunctions(): array

QuickOrderTwigExtension class

final class QuickOrderTwigExtension extends AbstractExtension QuickOrderTwigExtension.php:26

The quick order's form (Form\QuickOrderType), for a product, wherever a template shows one: {% set form = marketplace_quick_order_form(product) %} {% set form = marketplace_quick_order_form(product, '/carte') %} where a refusal brings the buyer back @Marketplace/client/_quick_order.html.twig prints it.

QuickOrderTwigExtension::__construct()

public function __construct(readonly FormFactoryInterface $forms, readonly UrlGeneratorInterface $router, readonly RequestStack $requests, readonly ?Security $security = null)

QuickOrderTwigExtension::getFunctions()

public function getFunctions(): array

QuickOrderTwigExtension::view()

public function view(Product $product, ?string $back = null): FormView

QuickOrderTwigExtension::form()

public function form(Product $product, ?string $back = null): FormInterface

The form for that product: posted to marketplace_quick_order, asking an address of a visitor signed out.

ShippingTwigExtension class

final class ShippingTwigExtension extends AbstractExtension ShippingTwigExtension.php:10

marketplace_tracking_url(method, number): where a parcel can be followed.

ShippingTwigExtension::getFunctions()

public function getFunctions(): array

Base\Marketplace\Validator

CompanyNumber class

final class CompanyNumber extends Constraint CompanyNumber.php:12

A SIREN or SIRET that exists: well formed, and known to the State's register (Service\CompanyRegistry). A register that does not answer lets it through - the request is then marked unchecked, not refused.

public string $invalid = 'company.invalid'
public string $unknown = 'company.unknown'

CompanyNumberValidator class

final class CompanyNumberValidator extends ConstraintValidator CompanyNumberValidator.php:9

CompanyNumberValidator::__construct()

public function __construct(readonly CompanyRegistry $registry)

CompanyNumberValidator::validate()

public function validate(mixed $value, Constraint $constraint): void

VatNumber class

final class VatNumber extends Constraint VatNumber.php:12

An intra-EU VAT number VIES knows (Service\VatNumbers): well formed - a French one with its key - and valid at the European Commission. VIES that does not answer lets a well-formed number through rather than refuse it.

public string $invalid = 'vat_number.invalid'
public string $unknown = 'vat_number.unknown'

VatNumberValidator class

final class VatNumberValidator extends ConstraintValidator VatNumberValidator.php:9

VatNumberValidator::__construct()

public function __construct(readonly VatNumbers $numbers)

VatNumberValidator::validate()

public function validate(mixed $value, Constraint $constraint): void

Base\Marketplace\Wishlist

Contributions class

class Contributions Contributions.php:33

Money given to a list. The giver pays on the provider's page; the payment is a destination charge to the owner's payout account (Stripe Connect), the platform keeping its fee: the gift is never the platform's money, and so is no order of its shop.

start() the contribution, and where to send the giver; confirm() on their return (or the webhook): asks the provider, marks it paid, dispatches ContributionPaidEvent - once.

Contributions::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly OmnitradeGateways $gateways, readonly ?EventDispatcherInterface $dispatcher = null, readonly float $feeRate = 0.03, readonly int $feeFixed = 0, readonly int $minimum = 500)

Contributions::fee()

public function fee(int $amount): int

The platform's fee on a gift of that amount, before any listener's word.

Contributions::start()

public function start(Item $item, int $amount, string $name, string $returnUrl, ?string $cancelUrl = null, array $options = []): Contribution
Returns

pending, its getRedirectUrl() the page to pay on

Throws

WishlistException wishlist.error.closed, .not_fund, .no_payout, .minimum, .too_much, .payment

Contributions::find()

public function find(string $reference): ?Contribution

Contributions::findByProviderReference()

public function findByProviderReference(string $gateway, string $providerReference): ?Contribution

Contributions::confirm()

public function confirm(Contribution $contribution): Contribution

Where it stands at the provider, applied: paid, cancelled, or still pending.

Contributions::apply()

public function apply(Contribution $contribution, ?Status $status): Contribution

A provider's word on it (its return page's fetch, its webhook).

PayoutAccounts class

class PayoutAccounts PayoutAccounts.php:20

The connected accounts contributions are paid to: one per owner, opened at the provider named by marketplace.wishlist.payout_gateway (an Express account at Stripe), completed by its holder on the provider's own page, kept up to date from its webhook (account.updated) or on demand.

PayoutAccounts::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly OmnitradeGateways $gateways, readonly string $gateway = 'stripe')

PayoutAccounts::isAvailable()

public function isAvailable(): bool

Whether the provider is configured and opens accounts at all.

PayoutAccounts::for()

public function for(User $owner): ?PayoutAccount

PayoutAccounts::open()

public function open(User $owner, string $country = 'FR'): PayoutAccount

The owner's account, opened at the provider when they have none yet.

PayoutAccounts::onboardingUrl()

public function onboardingUrl(PayoutAccount $account, string $returnUrl, string $refreshUrl): string

The provider's page where its holder gives their identity and bank account: valid a few minutes, used once.

PayoutAccounts::refresh()

public function refresh(PayoutAccount $account): PayoutAccount

Asks the provider where it stands (on the holder's return).

PayoutAccounts::applyRemote()

public function applyRemote(string $gateway, Account $remote): ?PayoutAccount

The provider's account, as a webhook carries it: applied to ours when we know it.

ProductLookup class

class ProductLookup ProductLookup.php:19

An address pasted into a list, read: the omnitrade gateways named in marketplace.wishlist.lookup are asked in order (amazon before web: the shop's own API before its page's markup), the first that knows the product answers. The affiliate link is asked the same way - a gateway may write it without being able to read the product (Amazon with its tag alone).

ProductLookup::__construct()

public function __construct(readonly OmnitradeGateways $bridges, readonly array $gateways = ['amazon', 'web'])

ProductLookup::lookup()

public function lookup(string $url): ?array
public function affiliateLink(string $url): ?string

The address with the site's affiliate tag, when one of the gateways has a programme for it.

Reservations class

class Reservations Reservations.php:20

An object promised leaves the list for the others. The item's row is locked while what is left is counted - from the database, not from memory -, so two givers cannot both take the last one. A reservation is cancelled with the token handed to its author (only its hash is kept), and lapses after marketplace.wishlist.reservation_days unless confirmed.

Reservations::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly int $days = 30)

Reservations::reserve()

public function reserve(Item $item, int $quantity, string $name, ?string $email = null, ?string $giverReference = null, ?string $message = null): array
Returns

the token cancels it: send it to its author

Throws

WishlistException wishlist.error.closed, .not_reservable, .taken

Reservations::find()

public function find(string $token): ?Reservation

Reservations::cancel()

public function cancel(string $token): ?Reservation

By its author: the object goes back on the list.

Reservations::confirm()

public function confirm(Reservation $reservation): Reservation

Bought: it no longer lapses.

Reservations::expire()

public function expire(?\DateTimeImmutable $now = null): int

The promises that lapsed, marked so; their objects are back on their lists.

WishlistException class

class WishlistException extends RuntimeException WishlistException.php:6

Something a giver or an owner asked cannot be done; the message is a key of the marketplace translations (wishlist.error.*).

public readonly array $parameters

WishlistException::__construct()

public function __construct(string $key, public readonly array $parameters = [])

Wishlists class

class Wishlists Wishlists.php:20

Lists and their wishes: made, filled from a pasted address (read through glitchr/omnitrade when it is installed), from this shop's catalogue or by hand, and their prices read again when they are old.

Wishlists::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly ?ProductLookup $lookup = null, readonly int $priceTtl = 86400)

Wishlists::create()

public function create(User $owner, string $title, WishlistKind $kind = WishlistKind::GIFTS, ?WishlistHolderInterface $holder = null): Wishlist

Wishlists::addFromUrl()

public function addFromUrl(Wishlist $wishlist, string $url, WishlistItemKind $kind = WishlistItemKind::OBJECT): Item

A wish from the address of its page, in any shop: what a gateway reads there fills it (title, picture, price, merchant); nothing read, it is kept with its address alone, for its owner to complete.

Throws

WishlistException when it is not an address

Wishlists::addProduct()

public function addProduct(Wishlist $wishlist, Product $product, int $quantity = 1): Item

A wish that is one of this shop's products: its price is the shop's, it is bought here.

Wishlists::addFund()

public function addFund(Wishlist $wishlist, string $title, ?int $goal = null, WishlistItemKind $kind = WishlistItemKind::FUND, ?string $description = null): Item

A pot (FUND; $goal shown, no ceiling) or an object shared between givers (SHARE; $goal its price).

Wishlists::refreshPrices()

public function refreshPrices(?\DateTimeImmutable $now = null, int $limit = 200): int

The prices read longer ago than marketplace.wishlist.price_ttl, read again (shown with their date: a price is the page's at the time).

Returns

how many were read

Wishlists::read()

public function read(Item $item, bool $priceOnly = false): bool

Fills a wish from its page; on a refresh only its price, availability's date and link move.