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é.
DemoControllerclassThe 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
UserclassThe 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
DemoGatewayclassAn 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
UserRepositoryclass
MarketplaceBundleclass3 methods
OrderReferenceclassA human order reference, generated once on the first flush:
5 methods
CatalogueNotificationListenerclassA 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
InventorySynchronizerclassThe stock levels alone, more often than the whole catalogue: every linked variant's count read from the platform (FetchInventory) and written here.
3 methods
PlatformSynchronizerclassThe 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
CatalogueSyncCommandclassmarketplace: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
InvoiceIssueCommandclassmarketplace: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
ReferralsCommandclassmarketplace:referrals: every night from the cron container - the referrers whose referee's order held are rewarded.
1 method
StripeWebhookCommandclassMakes 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
SubscriptionsCommandclassmarketplace: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
WishlistRefreshCommandclassmarketplace:wishlist:refresh-prices: every night from the cron container.
1 method
Base\Marketplace\Controller\Admin
AbstractMarketplaceCrudControllerclassEvery 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.
MarketplaceAdminTraittraitThe 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
QuotePipelineControllerclassThe 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
AttributeSetCrudControllerclassThe 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
BarcodeStandardCrudControllerclassThe barcode standards products can be identified with (EAN-13, UPC...): one per standard, used by the product identifiers and the feeds.
2 methods
BrandCrudControllerclassThe brands: the estates and houses, the makers - their story, logo, place and pictures.
3 methods
ChannelCrudControllerclassThe sales channels a product is published on (the storefront, a product feed, an export): a product appears where its channels say.
3 methods
CouponCrudControllerclassCoupons: 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
ExchangeRateCrudControllerclassThe 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
FeatureCrudControllerclassThe 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
FeeCrudControllerclassAdditional fees on an order (handling, small-order surcharge...): where they apply (scopes), when (rules) and how much (actions).
3 methods
InvoiceCrudControllerclassThe 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
OptionGroupCrudControllerclassThe 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
OrderCrudControllerclassAdmin 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
PaymentMethodCrudControllerclassAdmin 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
ProductCrudControllerclassAdmin CRUD for the products. Prices are integers in the currency's smallest unit (cents, or one pepette); an empty stock means unlimited.
4 methods
ProductIdentifierCrudControllerclassA 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
ProductTaxonCrudControllerclassThe product categories of a store: base-bundle's taxonomy, with the store they belong to.
1 method
PromotionCrudControllerclassPromotions 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
QuoteCrudControllerclassThe 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
RegionCrudControllerclassThe 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
ReviewCrudControllerclassCustomer 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
ReviewTaxonCrudControllerclassThe review categories of a store: base-bundle's taxonomy, with the store they belong to.
1 method
ShipmentCrudControllerclassThe parcels sent for an order: their tracking number, method and the items they hold. Kept once sent - a shipment is not deleted.
5 methods
ShippingMethodCrudControllerclassShipping 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
StoreCrudControllerclassAdmin CRUD for the stores: a name, the currency it trades in, open or shut.
5 methods
TaxRateCrudControllerclassEvery 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
TransactionCrudControllerclassThe payments recorded against orders, as the gateways reported them. A record of what happened: read, never written or deleted from here.
5 methods
VatCrudControllerclassThe 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
AgeGateControllerclassThe 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
AttachmentControllerclassDownloading 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
CartControllerclassThe carts and the checkout. Every change is a POST with a CSRF token; nothing needs JavaScript.
6 methods
CompanyControllerclassWhat 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
CompanySearchControllerclassOmnistate'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.
CouponControllerclassA coupon code entered in the cart, or taken back out.
3 methods
InvoiceControllerclassAn 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
InvoiceWebhookControllerclassAn 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
OrderControllerclassThe member's orders - carts excluded - and one order's receipt.
3 methods
PaymentControllerclassWhere 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
PickupControllerclassFollowing 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
QuickOrderControllerclassA 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
QuoteControllerclassBusiness 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
ShipmentControllerclassThe 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
StoreControllerclassBrowsing: 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
SupplyControllerclassThe 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
MarketplaceConfigurationclass1 method
MarketplaceExtensionclass3 methods · 1 constant
AttachmentclassA 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
BrandclassWho 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
CreditclassA 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
EntitlementclassA 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
InvoiceclassAn 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
Orderclass116 methods
Productclass118 methods · 1 constant
QuoteclassA 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
Reviewclass22 methods
Storeclass30 methods
UsageclassA 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
PlatformLinkclassA 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
OrderItemclass39 methods
PickupclassHow 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
Shipmentclass17 methods
SubscriptionclassA 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
SupplyJobclassPart 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
Transactionclass35 methods
Base\Marketplace\Entity\Order\Address
BillingAddressclass2 methods
ShippingAddressclass2 methods
Base\Marketplace\Entity\Order\Method
PaymentMethodclass27 methods
ShippingMethodclass39 methods
Base\Marketplace\Entity\Product
AssociationclassOne 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
Attributeclass3 methods
AttributeSetclassThe 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
Featureclass7 methods
Identifierclass10 methods
Imageclass4 methods
OptionclassOne 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
OptionGroupclassA 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
Taxonclass7 methods
Variantclass22 methods
Base\Marketplace\Entity\Product\AttributeSet
FieldclassOne 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
BarcodeAdapterclass6 methods
AbstractQuoteclassWhat 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
QuoteLineclassOne 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
Taxonclass4 methods
Base\Marketplace\Entity\Sales\Attribute
DiscountActionclass6 methods
DiscountRuleclass5 methods
DiscountScopeclass5 methods
FeeActionclass6 methods
FeeRuleclass5 methods
FeeScopeclass5 methods
PaymentMethodRuleclass5 methods
PaymentMethodScopeclass5 methods
ShippingMethodRuleclass5 methods
ShippingMethodScopeclass5 methods
TaxScopeclass5 methods
Base\Marketplace\Entity\Sales\Attribute\Action
FixedAmountAdapterclass9 methods
PercentageAmountAdapterclass7 methods
Base\Marketplace\Entity\Sales\Attribute\Rule
CartContainsAdapterclass6 methods
CartQuantityAdapterclass8 methods
TotalPriceAdapterclass10 methods
Base\Marketplace\Entity\Sales\Attribute\Scope
OrderAdapterclass6 methods
ProductAdapterclass6 methods
RegionAdapterclass6 methods
StoreAdapterclass6 methods
TaxonAdapterclass6 methods
UserAdapterclass6 methods
Base\Marketplace\Entity\Sales\Referral
ReferralclassSomebody 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
ReferralCodeclassA member's referral code: one each, the part of the link they share (an application route: /p/{code}).
10 methods
RewardclassWhat 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
Vatclass2 methods
Base\Marketplace\Entity\Wishlist
ContributionclassMoney 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
ItemclassA 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
PayoutAccountclassWhere 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
ReservationclassSomebody 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
WishlistclassA 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
AssociationTypeenumHow one product leads to another on its page.
3 cases
Barcodeclass2 methods · 14 constants
ContributionStatusenum4 cases
IncotermenumWho 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
OrderStateclass4 methods · 16 constants
PaymentStateclass2 methods · 8 constants
PickupModeenumHow 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
PickupStatusenumWhere a hand-over stands, in the order the shop moves it along:
3 methods · 10 cases
ProductAvailabilityclass2 methods · 10 constants
ProductKindenumWhat a product is, for what happens once it is paid:
3 cases
QuoteStatusenumA quote's life, the same for every trade (a négociant's export offer, a studio's hours):
3 methods · 6 cases
ReferralStatusenum4 cases
ReservationStatusenum1 method · 4 cases
ShippingRateclassHow a shipping method prices a parcel: one flat rate, priority, or international.
2 methods · 3 constants
SubscriptionStatusenumWhere a subscription stands; the values are glitchr/omnitrade's (Model\Subscription).
1 method · 7 cases
SupplyStatusenumWhere something made to order stands at its supplier.
1 method · 8 cases
TradeDirectionenumWhich way the goods of a trade quote travel, seen from the seller.
3 cases
WishlistItemKindenumHow a wish is fulfilled:
1 method · 3 cases
WishlistKindenumWhat a list is for: gifts wished for (a wedding, a birthday), a birth list, or a fund alone (a honeymoon).
3 cases
CatalogueNotificationEventclassA 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
ContributionPaidEventclassA contribution has just been paid: dispatched once. The application thanks, notes the gift, tells the owner.
1 method · 1 property
ContributionPreparingEventclassA 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
EntitlementEndedEventclassA 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
EntitlementEndingEventclassA right ends within marketplace.plans.reminder_days: dispatched once, for the application to tell its holder.
1 method · 1 property
EntitlementGrantedEventclassA right has just been granted - a plan paid, a gift made: the application opens what it opens.
1 method · 2 properties
OrderPaidEventclassAn 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
PaymentCancelledEventclassA 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
PaymentNotificationEventclassA 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
PaymentPreparingEventclassAn order is about to be handed to a glitchr/omnitrade gateway: the last moment to say how. A listener may
2 methods · 14 properties
PickupChangedEventclassA 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
QuickOrderDoneEventclassThe 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
ReferralQualifyingEventclassA 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
ReferralRewardedEventclassA reward was granted (the referee's welcome, the referrer's thanks): the application tells its beneficiary.
1 method · 1 property
SubscriptionChangedEventclassA subscription's state moved (renewed, past due, set to stop, ended), as the provider told.
1 method · 2 properties
SupplyJobChangedEventclassA supplier's job moved (accepted, in production, shipped with its tracking, failed): the application tells the buyer.
1 method · 2 properties
Base\Marketplace\EventListener
InvoiceOnPaymentListenerclassmarketplace.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
PickupPaidListenerclassAn order with a hand-over is paid: the shop has received it (saved with the confirmation's own flush).
2 methods
PlanPurchaseListenerclassAn 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
QuickOrderReturnListenerclassA 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
QuotePaidListenerclassA quote's order is paid: the quote is marked paid, the order named on it.
2 methods
ReferralListenerclassAn order is paid: a referee's first one qualifies their referral.
2 methods
SubscriptionNotificationListenerclassA subscription's event from a provider's webhook: applied to the Subscription kept here.
2 methods
SupplyListenerclassAn order is paid: what in it is made to order goes to its suppliers.
2 methods
WishlistNotificationListenerclassThe 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
AssociationTypeclassOne pairing, cross-sell or upsell of a product in the back office, with its note in each language of the site.
2 methods
AttributeSetFieldTypeclassOne attribute of a set in the back office: which, required, filtered on and how, shown.
2 methods
ProductOptionTypeclassOne option of a group in the back office: its label, what it adds to the price (cents, before VAT), preselected, available.
2 methods
QuickOrderTypeclassA 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
QuoteLineTypeclassOne 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
QuoteRequestTypeclassWhat 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
FacturXclassAn 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
InvoiceComposerclassWhat 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
InvoiceNumberingclassThe 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
InvoiceStatusCommandclassmarketplace: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
InvoiceStatusStoreclassWhere 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
InvoiceTransmissionclassThe 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
TransmissionExceptionclassA 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
InvoiceFlowclassWhere 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
CompanyRecordclassA 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
MerchantInterfaceinterfaceWhoever sells the thing.
1 method
OptionSelectionclassThe 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
PlanTermsclassWhat 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
QuickPaymentclassWhat QuickOrder::buy() hands back: the order made, and where its payment stands.
1 method · 2 properties
QuoteRequestclassWhat 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
ShippingUnitInterfaceinterface1 method
VatCustomerInterfaceinterfaceA 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
VatCustomerTraittraitVatCustomerInterface on an app's User entity: the number, when VIES confirmed it and its consultation number.
7 methods
WishlistHolderInterfaceinterfaceWhat 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
DevGatewayclassPaid 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
ManualGatewayclassPaid 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
PaymentGatewayInterfaceinterfaceOne way of taking money for an order.
3 methods
PaymentGatewayRegistryclassEvery 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
PaymentResultclassWhat a gateway's pay() came to - see PaymentGatewayInterface.
8 methods · 4 constants
Base\Marketplace\Payment\Omnitrade
OmnitradeGatewayclassA 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
OmnitradeGatewaysclassThe bridges to glitchr/omnitrade's configured gateways, one per name.
5 methods · 1 constant
TrialGatewayFactoryInterfaceinterfaceA 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.
ExportExemptionclassGoods 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
ReverseChargeclassThe 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
StoreVatRegimeclassThe 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
VatExemptionInterfaceinterfaceWhether 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
QuoteRepositoryTraittraitWhat 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
QuoteSignaturesclassA 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
AttachmentRepositoryclass1 method
BrandRepositoryclass1 method
CreditRepositoryclass1 method
EntitlementRepositoryclass1 method
InvoiceRepositoryclass3 methods
OrderRepositoryclassProductRepositoryclassQuoteRepositoryclassThe business quotes, numbered D-<year>-<n> (saveNumbered()), a client's (findForClient()), by status (pipeline()).
1 method
ReviewRepositoryclassStoreRepositoryclassUsageRepositoryclass1 method
Base\Marketplace\Repository\Catalogue
PlatformLinkRepositoryclass5 methods
Base\Marketplace\Repository\Order
OrderItemRepositoryclassPickupRepositoryclassThe hand-overs: an order's, a tracking page's (by its token), a day's.
4 methods
ShipmentRepositoryclassSubscriptionRepositoryclass1 method
SupplyJobRepositoryclass1 method
TransactionRepositoryclass
Base\Marketplace\Repository\Order\Method
PaymentMethodRepositoryclassShippingMethodRepositoryclass
Base\Marketplace\Repository\Product
AttributeRepositoryclassAttributeSetRepositoryclass3 methods
FeatureRepositoryclassIdentifierRepositoryclassImageRepositoryclassTaxonRepositoryclassVariantRepositoryclass
Base\Marketplace\Repository\Product\Attribute
BarcodeRepositoryclassHyperlinkRepositoryclass
Base\Marketplace\Repository\Product\Attribute\Adapter
BarcodeAdapterRepositoryclass
Base\Marketplace\Repository\Review
TaxonRepositoryclass
Base\Marketplace\Repository\Sales
ChannelRepositoryclassDiscountRepositoryclassFeeRepositoryclassForexRepositoryclassRegionRepositoryclassTaxRepositoryclass
Base\Marketplace\Repository\Sales\Attribute
DiscountActionRepositoryclassDiscountRuleRepositoryclassDiscountScopeRepositoryclassFeeActionRepositoryclassFeeRuleRepositoryclassFeeScopeRepositoryclassTaxScopeRepositoryclass
Base\Marketplace\Repository\Sales\Attribute\Scope
OrderAdapterRepositoryclassProductAdapterRepositoryclassRegionAdapterRepositoryclassStoreAdapterRepositoryclassTaxonAdapterRepositoryclassUserAdapterRepositoryclass
Base\Marketplace\Repository\Sales\Discount
CouponRepositoryclassPromotionRepositoryclass
Base\Marketplace\Repository\Sales\Referral
ReferralCodeRepositoryclass1 method
ReferralRepositoryclass1 method
Base\Marketplace\Repository\Sales\Tax
VatRepositoryclass
Base\Marketplace\Repository\Wishlist
ContributionRepositoryclass1 method
PayoutAccountRepositoryclass1 method
WishlistRepositoryclass3 methods
InvoiceVoterclassWho 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
MarketplaceVoterclassWho reaches the marketplace in the back office:
2 methods · 3 constants
AgeGateclassThe 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
AttachmentsclassThe 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
AttributeFiltersclassThe 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
CartclassThe 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
CartExceptionclassSomething the buyer should read; the message is a key in the "marketplace" domain.
2 methods
CheckoutclassFrom 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
CompanyRegistryclassWho 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
CreditExceptionclassNot enough credit of that kind for what is asked.
1 method · 3 properties
CreditsclassSomebody'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
EntitlementExceptionclassWhat was asked is not granted, or none is left: the application offers an upgrade.
1 method · 1 property
EntitlementsclassWhat somebody may do, from the rights they hold (Entity\Entitlement).
12 methods
ExchangeRatesclassThe 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
ExchangeRatesExceptionclassWhy the exchange rates were not refreshed: no key, too soon, the provider's refusal.
InvoicesclassThe 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
PickupsclassHanding 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
PricingclassPrices a cart: the promotions running now, then the coupons the member entered, through the discounts' own rules, scopes and actions.
8 methods
ProductOptionsclassChecks 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
QuickOrderclassAn order in one step, with no account to open and no basket to fill: products, an e-mail address, the payment.
4 methods
QuoteStatusGuardclassSmall predicates on a quote's life the controllers and the voter share.
1 method
QuoteToOrderclassThe 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
ReferralExceptionclassA referral that cannot be: its own code, an unknown one, a member already referred. The reason is its message.
ReferralsclassReferrals, 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
RegionResolverclassEvery 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
ShippingclassPosting 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
SubscriptionsclassThe 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
SupplyclassWhat 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
VatNumbersclassIntra-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
PaymentKeysSectionclassThe 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
GelatoSupplierclassGelato, 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
OfflineSupplierclassA supplier without an API: the shop's partner workshop, a local printer.
11 methods
SupplierInterfaceinterfaceSomebody 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
SupplierRegistryclassThe suppliers, by name: the bundle's (gelato, offline) and the application's.
4 methods
SupplyExceptionclassA supplier refused, did not answer, or does not do what was asked.
1 method · 1 property
SupplyLineclassOne 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
SupplyOrderclassWhat a supplier is asked: lines, for one recipient.
1 method · 7 properties
SupplyProductclassSomething a supplier makes: its reference there (what a Product's supplierReference holds) and its name.
1 method · 3 properties
SupplyQuoteclassWhat a supply order would cost the shop, in minor units: the making, the posting.
2 methods · 7 properties
SupplyRecipientclassWho receives what is made: one address per supply order (a batch for the buyer, or each guest's own).
7 methods · 9 properties
SupplyResultclassWhere a supply order stands, as its supplier says: its reference there, its state, its parcel.
1 method · 9 properties
CatalogueTwigExtensionclassThe catalogue's pages from any template:
5 methods
InvoiceTwigExtensionclassWhat 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
MarketplaceTwigExtensionclassWhat 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
QuickOrderTwigExtensionclassThe 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
ShippingTwigExtensionclass`marketplace_tracking_url(method, number)`: where a parcel can be followed.
1 method
CompanyNumberclassA 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
CompanyNumberValidatorclass2 methods
VatNumberclassAn 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
VatNumberValidatorclass2 methods
ContributionsclassMoney 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
PayoutAccountsclassThe 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
ProductLookupclassAn 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
ReservationsclassAn 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
WishlistExceptionclassSomething a giver or an owner asked cannot be done; the message is a key of the marketplace translations (wishlist.error.*).
1 method · 1 property
WishlistsclassLists 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(): ResponseApp\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(): ?stringUser::setUsername()
public function setUsername(string $username): selfUser::__toString()
public function __toString(): stringApp\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(): stringDemoGateway::supports()
public function supports(Order $order, PaymentMethod $method): boolDemoGateway::pay()
public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResultApp\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(): stringModern 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): voidBase\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): boolOrderReference::generate()
public function generate(): stringOrderReference::unique()
public function unique(OnFlushEventArgs $event, mixed $entity, string $property): stringA 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): voidInventorySynchronizer 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): boolWhether 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(): arrayPlatformSynchronizer::resetStats()
public function resetStats(): voidPlatformSynchronizer::gateway()
public function gateway(string $name): GatewayInterface- Throws
LogicException without glitchr/omnitrade, and in a demonstration (glitchr/omnibase's
demoenvironment): 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): arrayEvery 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.
$progresstold of each product and what became of it
- Returns
the counters
PlatformSynchronizer::synchronize()
public function synchronize(string $gatewayName, RemoteProduct $remote, bool $dryRun = false): stringOne 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): intThe product is gone from the platform: taken off sale, never deleted.
PlatformSynchronizer::updateStock()
public function updateStock(string $gatewayName, Stock $stock): boolA stock level the platform counted: by the variant's id there, or its counted item's.
PlatformSynchronizer::flush()
public function flush(): voidPlatformSynchronizer::fingerprint()
public function fingerprint(RemoteProduct $remote, RemoteVariant $variant): stringWhat 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 listenthere): 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): CrudMarketplaceAdminTrait::configureActions()
public function configureActions(Actions $actions): ActionsQuotePipelineController 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(): ResponseBase\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(): stringAttributeSetCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringAttributeSetCrudController::configureFields()
public function configureFields(string $pageName): iterableBarcodeStandardCrudController 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(): stringBarcodeStandardCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringBrandCrudController 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(): stringBrandCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringBrandCrudController::configureFields()
public function configureFields(string $pageName): iterableChannelCrudController 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(): stringChannelCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringChannelCrudController::configureFields()
public function configureFields(string $pageName): iterableCouponCrudController 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(): stringCouponCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringCouponCrudController::configureFields()
public function configureFields(string $pageName): iterableExchangeRateCrudController 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): ActionsExchangeRateCrudController::refreshRates()
public function refreshRates(): ResponseOne request for every pair; at most once an hour (ExchangeRates::MIN_INTERVAL).
ExchangeRateCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringExchangeRateCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringExchangeRateCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersExchangeRateCrudController::configureFields()
public function configureFields(string $pageName): iterableFeatureCrudController 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(): stringFeatureCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringFeatureCrudController::isDeletable()
public function isDeletable(object $entity): boolFeatureCrudController::configureFields()
public function configureFields(string $pageName): iterableFeeCrudController 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(): stringFeeCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringFeeCrudController::configureFields()
public function configureFields(string $pageName): iterableInvoiceCrudController 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): voidInvoiceCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringInvoiceCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringInvoiceCrudController::isDeletable()
public function isDeletable(object $entity): boolInvoiceCrudController::configureCrud()
public function configureCrud(Crud $crud): CrudInvoiceCrudController::configureActions()
public function configureActions(Actions $actions): ActionsInvoiceCrudController::new()
public function new(Request $request): ResponseInvoiceCrudController::edit()
public function edit(Request $request, string $entityId): ResponseInvoiceCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersInvoiceCrudController::configureFields()
public function configureFields(string $pageName): iterableInvoiceCrudController::send()
public function send(string $entityId): ResponseInvoiceCrudController::refresh()
public function refresh(string $entityId): ResponseInvoiceCrudController::markPaid()
public function markPaid(string $entityId): ResponseInvoiceCrudController::credit()
public function credit(string $entityId): ResponseOptionGroupCrudController 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(): stringOptionGroupCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringOptionGroupCrudController::configureFields()
public function configureFields(string $pageName): iterableOrderCrudController 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): voidOrderCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringOrderCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringOrderCrudController::configureActions()
public function configureActions(Actions $actions): ActionsOrders 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): ResponseOrderCrudController::new()
public function new(Request $request): ResponseA 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): ResponseOrderCrudController::configureRecordNote()
public function configureRecordNote(object $entity): ?stringOrderCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersOrderCrudController::configureFields()
public function configureFields(string $pageName): iterablePaymentMethodCrudController 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(): stringPaymentMethodCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringPaymentMethodCrudController::isDeletable()
public function isDeletable(object $entity): boolA method orders were paid with stays: they point to it.
PaymentMethodCrudController::configureRecordNote()
public function configureRecordNote(object $entity): ?stringWhether its gateway is installed, and how many of its settings are filled (marketplace.gateways.<slug>).
PaymentMethodCrudController::configureFields()
public function configureFields(string $pageName): iterableProductCrudController 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(): stringProductCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringProductCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersProductCrudController::configureFields()
public function configureFields(string $pageName): iterableProductIdentifierCrudController 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(): stringProductIdentifierCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringProductIdentifierCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersProductIdentifierCrudController::configureFields()
public function configureFields(string $pageName): iterableProductTaxonCrudController 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(): stringPromotionCrudController 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(): stringPromotionCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringPromotionCrudController::configureFields()
public function configureFields(string $pageName): iterableQuoteCrudController 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): voidThe 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): voidQuoteCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringQuoteCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringQuoteCrudController::configureCrud()
public function configureCrud(Crud $crud): CrudQuoteCrudController::configureActions()
public function configureActions(Actions $actions): ActionsQuoteCrudController::configureFields()
public function configureFields(string $pageName): iterableQuoteCrudController::createEntity()
public function createEntity(string $entityFqcn): objectQuoteCrudController::persistEntity()
public function persistEntity(EntityManagerInterface $entityManager, object $entity): voidNumbered when saved, not when the form opens: two forms open took the same number.
QuoteCrudController::send()
public function send(string $entityId): ResponseSent: 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(): stringRegionCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringRegionCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersRegionCrudController::isDeletable()
public function isDeletable(object $entity): boolRegionCrudController::configureFields()
public function configureFields(string $pageName): iterableReviewCrudController 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(): stringReviewCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringReviewCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersReviewCrudController::configureFields()
public function configureFields(string $pageName): iterableReviewTaxonCrudController 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(): stringShipmentCrudController 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(): stringShipmentCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringShipmentCrudController::isDeletable()
public function isDeletable(object $entity): boolShipmentCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersShipmentCrudController::configureFields()
public function configureFields(string $pageName): iterableShippingMethodCrudController 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(): stringShippingMethodCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringShippingMethodCrudController::isDeletable()
public function isDeletable(object $entity): boolA method orders were shipped with stays: they point to it.
ShippingMethodCrudController::configureRecordNote()
public function configureRecordNote(object $entity): ?stringThe carrier behind it and how many of its settings are filled (omnibus.<slug>).
ShippingMethodCrudController::configureFields()
public function configureFields(string $pageName): iterableStoreCrudController 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(): stringStoreCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringStoreCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersStoreCrudController::isDeletable()
public function isDeletable(object $entity): boolA store orders were placed in stays: they point to it.
StoreCrudController::configureFields()
public function configureFields(string $pageName): iterableTaxRateCrudController 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(): stringTaxRateCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringTaxRateCrudController::configureFields()
public function configureFields(string $pageName): iterableTransactionCrudController 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(): stringTransactionCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringTransactionCrudController::configureActions()
public function configureActions(Actions $actions): ActionsTransactionCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersTransactionCrudController::configureFields()
public function configureFields(string $pageName): iterableVatCrudController 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(): stringVatCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringBase\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): RedirectResponseAttachmentController 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): ResponseCartController 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): ResponseCartController::Add()
public function Add(Request $request, int $id): ResponseCartController::Update()
public function Update(Request $request, int $order, int $item): ResponseCartController::Checkout()
public function Checkout(Request $request, int $order, Pricing $pricing, Shipping $shipping): ResponseCartController::Files()
public function Files(Request $request, int $order, int $item, \Base\Marketplace\Service\Attachments $attachments): ResponseThe 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): JsonResponseCompanySearchController 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): ResponseCouponController::Remove()
public function Remove(Request $request, int $order, int $coupon): ResponseInvoiceController 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): ResponseInvoiceWebhookController 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): JsonResponseOrderController 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): ResponseOrderController::Show()
public function Show(string $reference): ResponsePaymentController 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): ResponsePaymentController::Webhook()
public function Webhook(Request $request, string $gateway): JsonResponsePickupController 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): ResponseQuickOrderController 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): ResponseQuickOrderController::Back()
public function Back(Request $request, int $order, string $gateway, PaymentGatewayRegistry $gateways, Checkout $checkout): ResponseBack 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): ResponseQuoteController 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): ResponseQuoteController::Show()
public function Show(string $token, QuoteToOrder $quoteToOrder): ResponseQuoteController::Accept()
public function Accept(Request $request, string $token, QuoteToOrder $quoteToOrder): ResponseQuoteController::Signed()
public function Signed(string $token): ResponseBack 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): ResponseThe signed quote ("document") or its evidence ("preuve"): for its client and the shop's staff.
QuoteController::Decline()
public function Decline(Request $request, string $token): ResponseQuoteController::Mine()
public function Mine(): ResponseShipmentController 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(): ResponseShipmentController::LegacyQueue()
public function LegacyQueue(): ResponseThe 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): ResponseShipmentController::Deliver()
public function Deliver(Request $request, string $reference): ResponseStoreController 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(): ResponseStoreController::Store()
public function Store(Request $request, string $slug): ResponseStoreController::Product()
public function Product(string $store, string $slug): ResponseSupplyController 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): ResponseSupplyController::Webhook()
public function Webhook(Request $request, SupplierRegistry $suppliers, string $supplier): JsonResponseBase\Marketplace\DependencyInjection
MarketplaceConfiguration class
class MarketplaceConfiguration extends AbstractBaseConfiguration MarketplaceConfiguration.php:8
MarketplaceConfiguration::getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilderMarketplaceExtension 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): MarketplaceConfigurationMarketplaceExtension::prepend()
public function prepend(ContainerBuilder $container): voidTwo 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): voidBase\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(): stringAttachment::getId()
public function getId(): ?intAttachment::getQuote()
public function getQuote(): ?QuoteAttachment::setQuote()
public function setQuote(?Quote $quote): selfAttachment::getOrderItem()
public function getOrderItem(): ?OrderItemAttachment::setOrderItem()
public function setOrderItem(?OrderItem $orderItem): selfAttachment::getPath()
public function getPath(): stringAttachment::getName()
public function getName(): stringAttachment::getMimeType()
public function getMimeType(): stringAttachment::getSize()
public function getSize(): intAttachment::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableAttachment::isImage()
public function isImage(): boolBrand 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(): ?arrayBrand::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringThe 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(): CollectionBrand::getLogo()
public function getLogo()Brand::getLogoFile()
public function getLogoFile()Brand::setLogo()
public function setLogo($logo): selfBrand::getGallery()
public function getGallery(): arrayThe pictures of the place: the vineyard, the cellar, the people.
Brand::setGallery()
public function setGallery($gallery): selfBrand::getCountry()
public function getCountry(): ?stringBrand::setCountry()
public function setCountry(?string $country): selfBrand::getRegion()
public function getRegion(): ?stringBrand::setRegion()
public function setRegion(?string $region): selfBrand::getWebsite()
public function getWebsite(): ?stringBrand::setWebsite()
public function setWebsite(?string $website): selfCredit 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(): ?intCredit::getHolder()
public function getHolder(): ?UserCredit::getKind()
public function getKind(): stringCredit::getQuantity()
public function getQuantity(): intCredit::isGrant()
public function isGrant(): boolCredit::getReason()
public function getReason(): ?stringCredit::getOrderReference()
public function getOrderReference(): ?stringCredit::setOrderReference()
public function setOrderReference(?string $orderReference): selfCredit::getResourceType()
public function getResourceType(): ?stringCredit::getResourceId()
public function getResourceId(): ?stringCredit::setResource()
public function setResource(?string $type, int|string|null $id): selfCredit::getExpiresAt()
public function getExpiresAt(): ?\DateTimeImmutableCredit::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableEntitlement 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(): stringEntitlement::getId()
public function getId(): ?intEntitlement::getHolder()
public function getHolder(): ?UserEntitlement::getCode()
public function getCode(): stringEntitlement::getGrants()
public function getGrants(): arrayEntitlement::setGrants()
public function setGrants(array $grants): selfEntitlement::getGrant()
public function getGrant(string $key, mixed $default = null): mixedEntitlement::getLevel()
public function getLevel(): intEntitlement::setLevel()
public function setLevel(int $level): selfEntitlement::getResourceType()
public function getResourceType(): ?stringEntitlement::getResourceId()
public function getResourceId(): ?stringEntitlement::setResource()
public function setResource(?string $type, int|string|null $id): selfEntitlement::isFor()
public function isFor(?string $type, int|string|null $id): boolEntitlement::getProduct()
public function getProduct(): ?ProductEntitlement::setProduct()
public function setProduct(?Product $product): selfEntitlement::getOrderReference()
public function getOrderReference(): ?stringEntitlement::setOrderReference()
public function setOrderReference(?string $orderReference): selfEntitlement::getSubscription()
public function getSubscription(): ?SubscriptionEntitlement::setSubscription()
public function setSubscription(?Subscription $subscription): selfEntitlement::getStartsAt()
public function getStartsAt(): \DateTimeImmutableEntitlement::getExpiresAt()
public function getExpiresAt(): ?\DateTimeImmutableEntitlement::setExpiresAt()
public function setExpiresAt(?\DateTimeImmutable $expiresAt): selfEntitlement::getRevokedAt()
public function getRevokedAt(): ?\DateTimeImmutableEntitlement::revoke()
public function revoke(?\DateTimeImmutable $at = null): selfEntitlement::getEndedAt()
public function getEndedAt(): ?\DateTimeImmutableEntitlement::markEnded()
public function markEnded(): selfEntitlement::getRemindedAt()
public function getRemindedAt(): ?\DateTimeImmutableEntitlement::markReminded()
public function markReminded(): selfEntitlement::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableEntitlement::isActive()
public function isActive(?\DateTimeImmutable $at = null): boolHeld 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(): stringInvoice::refuseChanges()
public function refuseChanges(PreUpdateEventArgs $event): voidIssued, nothing but its state changes: an update of anything else is refused.
Invoice::getId()
public function getId(): ?intInvoice::getType()
public function getType(): stringInvoice::isCreditNote()
public function isCreditNote(): boolInvoice::getSeries()
public function getSeries(): stringInvoice::getYear()
public function getYear(): intInvoice::getSequence()
public function getSequence(): intInvoice::getNumber()
public function getNumber(): stringInvoice::getIssuedAt()
public function getIssuedAt(): \DateTimeImmutableInvoice::getSoldAt()
public function getSoldAt(): ?\DateTimeImmutableInvoice::getDueAt()
public function getDueAt(): ?\DateTimeImmutableInvoice::getOrder()
public function getOrder(): ?OrderInvoice::getOrderReference()
public function getOrderReference(): ?stringInvoice::getCredited()
public function getCredited(): ?InvoiceInvoice::getCreditNote()
public function getCreditNote(): ?InvoiceInvoice::getCurrency()
public function getCurrency(): stringInvoice::getSeller()
public function getSeller(): arrayInvoice::getBuyer()
public function getBuyer(): arrayInvoice::getLines()
public function getLines(): arrayInvoice::getTotals()
public function getTotals(): arrayInvoice::getTotal()
public function getTotal(): intInvoice::getMentions()
public function getMentions(): arrayInvoice::getState()
public function getState(): stringInvoice::isCancelled()
public function isCancelled(): boolInvoice::isPaid()
public function isPaid(): boolInvoice::getSentAt()
public function getSentAt(): ?\DateTimeImmutableInvoice::getPaidAt()
public function getPaidAt(): ?\DateTimeImmutableInvoice::getCancelledAt()
public function getCancelledAt(): ?\DateTimeImmutableInvoice::markSent()
public function markSent(\DateTimeImmutable $at = new \DateTimeImmutable()): staticInvoice::markPaid()
public function markPaid(\DateTimeImmutable $at = new \DateTimeImmutable()): staticInvoice::cancelBy()
public function cancelBy(Invoice $creditNote, \DateTimeImmutable $at = new \DateTimeImmutable()): staticCancelled by that credit note: Service\Invoices::credit().
Order class
class Order implements IconizeInterface, LinkableInterface Order.php:33
Order::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringOrder::__iconize()
public function __iconize(): ?arrayOrder::__iconizeStatic()
public static function __iconizeStatic(): ?arrayOrder::__toString()
public function __toString(): stringOrder::__construct()
public function __construct(?Store $store = null)Order::getId()
public function getId()Order::getManager()
public function getManager(): ?MerchantInterfaceOrder::getManagers()
public function getManagers(): CollectionOrder::addManager()
public function addManager(MerchantInterface $manager): selfOrder::removeManager()
public function removeManager(MerchantInterface $manager): selfOrder::getReference()
public function getReference()Order::getStore()
public function getStore(): ?StoreOrder::setStore()
public function setStore(?Store $store): selfOrder::getCustomer()
public function getCustomer(): ?UserOrder::isCustomer()
public function isCustomer(mixed $user): boolWhether $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): selfOrder::getState()
public function getState(): stringOrder::setState()
public function setState(string $state): selfOrder::markAsConfirmed()
public function markAsConfirmed(): selfOrder::markAsBeingProcessed()
public function markAsBeingProcessed(): selfOrder::markAsPending()
public function markAsPending(): selfOrder::markAsShipped()
public function markAsShipped(): selfOrder::markAsCompleted()
public function markAsCompleted(): selfOrder::markAsCancelled()
public function markAsCancelled(): selfOrder::markAsRefunded()
public function markAsRefunded(): selfOrder::markAsCart()
public function markAsCart(): selfOrder::markAsAbandoned()
public function markAsAbandoned(): selfOrder::getShipments()
public function getShipments(): CollectionOrder::addShipment()
public function addShipment(Shipment $shipment): selfOrder::removeShipment()
public function removeShipment(Shipment $shipment): selfOrder::isEmpty()
public function isEmpty(): boolOrder::getUniqueProducts()
public function getUniqueProducts(): arrayEvery 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): arrayOrder::getItem()
public function getItem(int $i): ?OrderItemOrder::getItems()
public function getItems(): CollectionOrder::getAttachments()
public function getAttachments(): array- Returns
the files the buyer gave for its lines
Order::addItem()
public function addItem(OrderItem $item): selfOrder::removeItem()
public function removeItem(OrderItem $item): selfOrder::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceOrder::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceOrder::getPaidAt()
public function getPaidAt(): ?\DateTimeInterfaceOrder::getRegion()
public function getRegion(): ?RegionOrder::setRegion()
public function setRegion(?Region $region): selfOrder::getPaymentMethod()
public function getPaymentMethod(): ?PaymentMethodOrder::setPaymentMethod()
public function setPaymentMethod(?PaymentMethod $paymentMethod): selfOrder::getShippingMethod()
public function getShippingMethod(): ?ShippingMethodOrder::setShippingMethod()
public function setShippingMethod(?ShippingMethod $shippingMethod): selfOrder::getShippingUnits()
public function getShippingUnits(): intOrder::notify()
public function notify(): ?boolOrder::setNotify()
public function setNotify(bool $notify): selfOrder::getDiscounts()
public function getDiscounts(): CollectionOrder::getCoupons()
public function getCoupons(): arrayOrder::getPromotions()
public function getPromotions(): arrayOrder::addDiscount()
public function addDiscount(Discount $discount): selfOrder::removeDiscount()
public function removeDiscount(Discount $discount): selfOrder::getAdditionalFees()
public function getAdditionalFees(): CollectionOrder::addAdditionalFee()
public function addAdditionalFee(Fee $additionalFee): selfOrder::removeAdditionalFee()
public function removeAdditionalFee(Fee $additionalFee): selfOrder::getAdditionalTaxes()
public function getAdditionalTaxes(): CollectionOrder::addAdditionalTax()
public function addAdditionalTax(Tax $additionalTax): selfOrder::removeAdditionalTax()
public function removeAdditionalTax(Tax $additionalTax): selfOrder::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(): stringOrder::setCurrency()
public function setCurrency(string $currency)Order::getGrossPrice()
public function getGrossPrice(): intOrder::getSalePrice()
public function getSalePrice(): intOrder::getVatCharge()
public function getVatCharge(): intOrder::getVatExemption()
public function getVatExemption(): ?stringOrder::setVatExemption()
public function setVatExemption(?string $vatExemption): selfOrder::isVatExempt()
public function isVatExempt(): boolOrder::getQuoteReference()
public function getQuoteReference(): ?stringOrder::setQuoteReference()
public function setQuoteReference(?string $quoteReference): selfOrder::isQuoted()
public function isQuoted(): boolOrder::getNetPrice()
public function getNetPrice(): intOrder::getTotalPaid()
public function getTotalPaid(): intOrder::getBalanceDue()
public function getBalanceDue(): intOrder::getAdditionalTaxCharge()
public function getAdditionalTaxCharge(): intOrder::setAdditionalTaxCharge()
public function setAdditionalTaxCharge(float|int $additionalTaxCharge, ?string $currency = null): selfOrder::getShippingCharge()
public function getShippingCharge(): intOrder::setShippingCharge()
public function setShippingCharge(float|int $shippingCharge, ?string $currency = null): selfOrder::getServiceCharge()
public function getServiceCharge(): intOrder::setServiceCharge()
public function setServiceCharge(float|int $serviceCharge, ?string $currency = null): selfOrder::getDiscountCharge()
public function getDiscountCharge(): intOrder::setDiscountCharge()
public function setDiscountCharge(float|int $discountCharge, ?string $currency = null): selfOrder::getBillingAddress()
public function getBillingAddress(): ?BillingAddressOrder::setBillingAddress()
public function setBillingAddress(?BillingAddress $billingAddress): selfOrder::getShippingAddress()
public function getShippingAddress(): ?ShippingAddressOrder::setShippingAddress()
public function setShippingAddress(?ShippingAddress $shippingAddress): selfOrder::getReviews()
public function getReviews(): CollectionOrder::addReview()
public function addReview(Review $review): selfOrder::removeReview()
public function removeReview(Review $review): selfOrder::isAbandonable()
public function isAbandonable(): boolOrder::getAbandonDelay()
public static function getAbandonDelay(): intOrder::getAbandonTime()
public function getAbandonTime(): ?intOrder::getAbandonTimeStr()
public function getAbandonTimeStr(): ?stringOrder::isDeletable()
public function isDeletable(): boolOrder::getDeleteDelay()
public static function getDeleteDelay(): intOrder::getDeleteTime()
public function getDeleteTime(): ?intOrder::getDeleteTimeStr()
public function getDeleteTimeStr(): ?stringOrder::getTransactions()
public function getTransactions(): CollectionOrder::addTransaction()
public function addTransaction(Transaction $transaction): selfOrder::markAsPaidAt()
public function markAsPaidAt(?\DateTimeInterface $at = null): selfWhen 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): selfProduct class
class Product extends Thread implements TranslatableInterface, AutocompleteInterface, LinkableInterface, ShippingUnitInterface Product.php:48
const INHERITS_FROM = true
Product::__toKey()
public function __toKey(mixed ...$variadic): stringProduct::__typesense()
public function __typesense(): ?stringProduct::__iconize()
public function __iconize(): ?arrayProduct::__iconizeStatic()
public static function __iconizeStatic(): ?arrayProduct::__autocomplete()
public function __autocomplete(): stringProduct::__autocompleteData()
public function __autocompleteData(): arrayProduct::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringProduct::getRouteIdentifierClass()
public function getRouteIdentifierClass(): stringWhich 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): ?stringProduct::getCategories()
public function getCategories(): ?arrayProduct::getBrands()
public function getBrands(): ?arrayProduct::getReference()
public function getReference(int $chrLength = 3, int $numLength = 4): ?stringProduct::setStore()
public function setStore(?Store $store)Product::getStore()
public function getStore(): ?StoreProduct::isShippable()
public function isShippable(): boolSomething to send: goods. A plan or a pack of credits is delivered as a right, with no address asked.
Product::getMaxQuantity()
public function getMaxQuantity(): ?intProduct::isVariant()
public static function isVariant()Product::getVariants()
public function getVariants(): CollectionProduct::addVariant()
public function addVariant(Product $variant): selfProduct::removeVariant()
public function removeVariant(Product $variant): selfProduct::removeAllVariants()
public function removeAllVariants(): selfProduct::getPriceRange()
public function getPriceRange(): arrayThe 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(): ?intProduct::setPriceFrom()
public function setPriceFrom(?int $priceFrom): selfProduct::getStartingPrice()
public function getStartingPrice(): ?intThe 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(): boolWhether that price is a "from": typed as one, or the lowest of several.
Product::getPrice()
public function getPrice()Product::getUnitPrice()
public function getUnitPrice(): ?intProduct::setUnitPrice()
public function setUnitPrice(?int $unitPrice): selfA 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(): ?stringProduct::setCurrency()
public function setCurrency(string $currency): selfProduct::getColors()
public function getColors(): arrayProduct::getWeight()
public function getWeight(): ?intProduct::getWeightUnit()
public function getWeightUnit(): ?stringProduct::getWidth()
public function getWidth(): ?intProduct::getWidthUnit()
public function getWidthUnit(): ?stringProduct::getHeight()
public function getHeight(): ?intProduct::getHeightUnit()
public function getHeightUnit(): ?stringProduct::getLength()
public function getLength(): ?intProduct::getLengthUnit()
public function getLengthUnit(): ?stringProduct::getDimensions()
public function getDimensions(): arrayProduct::getShippingUnits()
public function getShippingUnits(): floatProduct::getStock()
public function getStock(): ?intProduct::setStock()
public function setStock(?int $stock): selfProduct::isForSell()
public function isForSell()Product::getAvailability()
public function getAvailability()Product::setAvailability()
public function setAvailability($availability): selfAn 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): CollectionProduct::getAttribute()
public function getAttribute(string $code, ?string $abstractAttributeClassName = null): ?AttributeProduct::addAttribute()
public function addAttribute(Attribute $attribute): selfProduct::removeAttribute()
public function removeAttribute(Attribute $attribute): selfProduct::getExports()
public function getExports(?string $code = null): CollectionProduct::getExport()
public function getExport(string $code): mixedProduct::addExport()
public function addExport(Hyperlink $attribute): selfProduct::removeExport()
public function removeExport(Hyperlink $attribute): selfProduct::getFeatures()
public function getFeatures(): CollectionProduct::addFeature()
public function addFeature(Feature $feature): selfProduct::removeFeature()
public function removeFeature(Feature $feature): selfProduct::getOrderItems()
public function getOrderItems(): CollectionProduct::addOrderItem()
public function addOrderItem(OrderItem $orderItem): selfProduct::removeOrderItem()
public function removeOrderItem(OrderItem $orderItem): selfProduct::getIdentifiers()
public function getIdentifiers(): CollectionProduct::getSku()
public function getSku(): ?stringIts 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): selfProduct::getAuthor()
public function getAuthor(int $i = 0)Product::getAuthors()
public function getAuthors(): CollectionThe 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): CollectionProduct::getEAN()
public function getEAN(): ?stringProduct::getBarcodes()
public function getBarcodes(string $std): CollectionProduct::removeIdentifier()
public function removeIdentifier(Identifier $identifier): selfProduct::getImage()
public function getImage(?int $i = null): ?ImageProduct::getImages()
public function getImages(): CollectionProduct::getImageCrop()
public function getImageCrop(string $slug, ?int $i = null): ?ImageCropProduct::addImage()
public function addImage(Image $image): selfProduct::removeImage()
public function removeImage(Image $image): selfProduct::getImageMarketplaces()
public function getImageMarketplaces()Product::getImageMarketplaceFiles()
public function getImageMarketplaceFiles()Product::setImageMarketplaces()
public function setImageMarketplaces($imageMarketplaces)Product::getReviews()
public function getReviews(): CollectionProduct::addReview()
public function addReview(Review $review): selfProduct::removeReview()
public function removeReview(Review $review): selfProduct::getChannels()
public function getChannels(): CollectionProduct::addChannel()
public function addChannel(Channel $channel): selfProduct::removeChannel()
public function removeChannel(Channel $channel): selfProduct::getBrand()
public function getBrand(): ?BrandProduct::setBrand()
public function setBrand(?Brand $brand): selfProduct::getPackSize()
public function getPackSize(): intProduct::getOwnPackSize()
public function getOwnPackSize(): ?intProduct::setPackSize()
public function setPackSize(?int $packSize): selfProduct::getMinimumQuantity()
public function getMinimumQuantity(): intProduct::getOwnMinimumQuantity()
public function getOwnMinimumQuantity(): ?intProduct::setMinimumQuantity()
public function setMinimumQuantity(?int $minimumQuantity): selfProduct::boundQuantity()
public function boundQuantity(int $wanted, ?int $max = null): intA 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\ProductKindProduct::setKind()
public function setKind(\Base\Marketplace\Enum\ProductKind|string $kind): selfProduct::isPlan()
public function isPlan(): boolProduct::isCreditPack()
public function isCreditPack(): boolProduct::getPlan()
public function getPlan(): ?arrayProduct::setPlan()
public function setPlan(\Base\Marketplace\Model\PlanTerms|array|null $plan): selfProduct::getPlanTerms()
public function getPlanTerms(): \Base\Marketplace\Model\PlanTermsProduct::getSupplier()
public function getSupplier(): ?stringProduct::setSupplier()
public function setSupplier(?string $supplier): selfProduct::getSupplierReference()
public function getSupplierReference(): ?stringProduct::setSupplierReference()
public function setSupplierReference(?string $supplierReference): selfProduct::isAgeRestricted()
public function isAgeRestricted(): boolProduct::getAgeRestricted()
public function getAgeRestricted(): boolProduct::setAgeRestricted()
public function setAgeRestricted(bool $ageRestricted): selfProduct::getAssociations()
public function getAssociations(?AssociationType $type = null): CollectionProduct::addAssociation()
public function addAssociation(Association $association): selfProduct::removeAssociation()
public function removeAssociation(Association $association): selfProduct::associate()
public function associate(Product $target, AssociationType $type = AssociationType::PAIRING, array $notes = []): AssociationA 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(): boolProduct::addOptionGroup()
public function addOptionGroup(OptionGroup $group): selfProduct::removeOptionGroup()
public function removeOptionGroup(OptionGroup $group): selfProduct::getAttributeValue()
public function getAttributeValue(string $code, ?string $locale = null): mixedIts 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(): ?stringQuote::setCompanyName()
public function setCompanyName(?string $companyName): staticQuote::getPhone()
public function getPhone(): ?stringQuote::setPhone()
public function setPhone(?string $phone): staticQuote::getAttachments()
public function getAttachments(): CollectionQuote::addAttachment()
public function addAttachment(Attachment $attachment): staticQuote::getVatNumber()
public function getVatNumber(): ?stringQuote::setVatNumber()
public function setVatNumber(?string $vatNumber): staticQuote::getDirection()
public function getDirection(): ?TradeDirectionQuote::setDirection()
public function setDirection(?TradeDirection $direction): staticQuote::getIncoterm()
public function getIncoterm(): ?IncotermQuote::setIncoterm()
public function setIncoterm(?Incoterm $incoterm): staticQuote::getPlace()
public function getPlace(): ?stringQuote::setPlace()
public function setPlace(?string $place): staticQuote::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(): ?stringQuote::setCountry()
public function setCountry(?string $country): staticQuote::getDeliveryAddress()
public function getDeliveryAddress(): ?stringQuote::setDeliveryAddress()
public function setDeliveryAddress(?string $deliveryAddress): staticQuote::getVolume()
public function getVolume(): ?stringQuote::setVolume()
public function setVolume(?string $volume): staticQuote::getTargetDate()
public function getTargetDate(): ?\DateTimeImmutableQuote::setTargetDate()
public function setTargetDate(?\DateTimeImmutable $targetDate): staticQuote::getStore()
public function getStore(): ?StoreQuote::setStore()
public function setStore(?Store $store): staticQuote::getOrder()
public function getOrder(): ?OrderQuote::setOrder()
public function setOrder(?Order $order): staticQuote::getLines()
public function getLines(): CollectionQuote::addLine()
public function addLine(QuoteLine $line): staticQuote::removeLine()
public function removeLine(QuoteLine $line): staticQuote::getSubtotal()
public function getSubtotal(): intQuote::getUnits()
public function getUnits(): intHow 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): stringReview::__iconizeStatic()
public static function __iconizeStatic(): ?arrayReview::__typesense()
public function __typesense(): ?stringReview::__autocompleteData()
public function __autocompleteData(): arrayReview::__autocomplete()
public function __autocomplete(): stringReview::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringReview::__construct()
public function __construct(?User $reviewer = null, $rating = 1.0, array $pictures = [])Review::getRating()
public function getRating(): ?floatReview::setRating()
public function setRating(float $rating): selfReview::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(): ?ProductReview::setProduct()
public function setProduct(?Product $product): selfReview::getColors()
public function getColors(): arrayReview::getAuthor()
public function getAuthor(int $i = 0)Review::getAuthors()
public function getAuthors(): CollectionReview::getStore()
public function getStore(): ?StoreReview::setStore()
public function setStore(?Store $store): selfReview::getOrder()
public function getOrder(): ?OrderReview::setOrder()
public function setOrder(?Order $order): selfStore class
class Store extends Thread implements TranslatableInterface, LinkableInterface Store.php:27
Store::__iconizeStatic()
public static function __iconizeStatic(): ?arrayStore::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringStore::__construct()
public function __construct(?MerchantInterface $merchant = null)Store::getProducts()
public function getProducts(): CollectionStore::addProduct()
public function addProduct(Product $product): selfStore::removeProduct()
public function removeProduct(Product $product): selfStore::getRegions()
public function getRegions(): CollectionStore::addRegion()
public function addRegion(Region $region): selfStore::removeRegion()
public function removeRegion(Region $region): selfStore::getOrders()
public function getOrders(): CollectionStore::addOrder()
public function addOrder(Order $order): selfStore::removeOrder()
public function removeOrder(Order $order): selfStore::getReviews()
public function getReviews(): CollectionStore::addReview()
public function addReview(Review $review): selfStore::removeReview()
public function removeReview(Review $review): selfStore::getCurrency()
public function getCurrency(): ?stringStore::setCurrency()
public function setCurrency(string $currency): selfStore::chargesVat()
public function chargesVat(): boolStore::setChargesVat()
public function setChargesVat(bool $chargesVat): selfStore::getVatNumber()
public function getVatNumber(): ?stringStore::setVatNumber()
public function setVatNumber(?string $vatNumber): selfStore::validateVat()
public function validateVat(ExecutionContextInterface $context): voidStore::getProductTaxa()
public function getProductTaxa(): CollectionStore::addProductTaxon()
public function addProductTaxon(ProductTaxon $productTaxon): selfStore::removeProductTaxon()
public function removeProductTaxon(ProductTaxon $productTaxon): selfStore::getReviewTaxa()
public function getReviewTaxa(): CollectionStore::addReviewTaxon()
public function addReviewTaxon(ReviewTaxon $reviewTaxon): selfStore::removeReviewTaxon()
public function removeReviewTaxon(ReviewTaxon $reviewTaxon): selfStore::isOpen()
public function isOpen(): ?boolStore::setOpen()
public function setOpen(bool $open): selfUsage 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(): ?intUsage::getEntitlement()
public function getEntitlement(): EntitlementUsage::getKey()
public function getKey(): stringUsage::getQuantity()
public function getQuantity(): intUsage::getResourceType()
public function getResourceType(): ?stringUsage::getResourceId()
public function getResourceId(): ?stringUsage::getUsedAt()
public function getUsedAt(): \DateTimeImmutableUsage::getReleasedAt()
public function getReleasedAt(): ?\DateTimeImmutableUsage::isReleased()
public function isReleased(): boolUsage::release()
public function release(): selfBase\Marketplace\Entity\Catalogue
PlatformLink class
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).
PlatformLink::__construct()
public function __construct(Product $product, string $gateway, string $remoteProduct, string $remoteVariant)PlatformLink::getId()
public function getId(): ?intPlatformLink::getProduct()
public function getProduct(): ProductPlatformLink::getGateway()
public function getGateway(): stringPlatformLink::getRemoteProduct()
public function getRemoteProduct(): stringPlatformLink::getRemoteVariant()
public function getRemoteVariant(): stringPlatformLink::getRemoteItem()
public function getRemoteItem(): ?stringPlatformLink::setRemoteItem()
public function setRemoteItem(?string $remoteItem): selfPlatformLink::getSku()
public function getSku(): ?stringPlatformLink::setSku()
public function setSku(?string $sku): selfPlatformLink::getFingerprint()
public function getFingerprint(): stringPlatformLink::isOrphaned()
public function isOrphaned(): boolPlatformLink::setOrphaned()
public function setOrphaned(bool $orphaned): selfPlatformLink::getRemoteUpdatedAt()
public function getRemoteUpdatedAt(): ?\DateTimeImmutablePlatformLink::getSyncedAt()
public function getSyncedAt(): \DateTimeImmutablePlatformLink::synced()
public function synced(string $fingerprint, ?\DateTimeImmutable $remoteUpdatedAt = null): selfWritten 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(): ?RegionOrderItem::getCustomer()
public function getCustomer(): ?UserOrderItem::getOrder()
public function getOrder(): ?OrderOrderItem::setOrder()
public function setOrder(?Order $order): selfOrderItem::getProduct()
public function getProduct(): ?ProductOrderItem::setProduct()
public function setProduct(?Product $product): selfOrderItem::getRecipient()
public function getRecipient(): ?arrayOrderItem::setRecipient()
public function setRecipient(?array $recipient): selfOrderItem::getPersonalisation()
public function getPersonalisation(): ?arrayOrderItem::setPersonalisation()
public function setPersonalisation(?array $personalisation): selfOrderItem::getOptions()
public function getOptions(): arrayOrderItem::applyOptions()
public function applyOptions(\Base\Marketplace\Model\OptionSelection $selection, ?string $locale = null): selfThe 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(): intWhat 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(): stringWhich options, whatever their order: two lines of a product differ by it.
OrderItem::getAttachments()
public function getAttachments(): CollectionOrderItem::getComment()
public function getComment(): ?stringOrderItem::setComment()
public function setComment(?string $comment): selfOrderItem::getQuantity()
public function getQuantity(): ?intOrderItem::setQuantity()
public function setQuantity(int $quantity): selfOrderItem::getCurrency()
public function getCurrency(): stringOrderItem::setCurrency()
public function setCurrency(string $currency)OrderItem::getGrossPrice()
public function getGrossPrice(): intOrderItem::getSalePrice()
public function getSalePrice(): intOrderItem::getSalePricePerUnit()
public function getSalePricePerUnit(): intOrderItem::getVAT()
public function getVAT(): floatOrderItem::getNetPrice()
public function getNetPrice(): intOrderItem::getUnitPrice()
public function getUnitPrice(): intOrderItem::setUnitPrice()
public function setUnitPrice(float|int $unitPrice, ?string $currency = null): selfOrderItem::getDiscountCharge()
public function getDiscountCharge(): intOrderItem::setDiscountCharge()
public function setDiscountCharge(float|int $discountCharge, ?string $currency = null): selfOrderItem::getVatCharge()
public function getVatCharge(): intOrderItem::setVatCharge()
public function setVatCharge(float|int $vatCharge, ?string $currency = null): selfOrderItem::getShipments()
public function getShipments(): CollectionOrderItem::addShipment()
public function addShipment(Shipment $shipment): selfOrderItem::removeShipment()
public function removeShipment(Shipment $shipment): selfPickup 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(): string32 random bytes, URL-safe: nobody guesses a tracking page.
Pickup::getId()
public function getId(): ?intPickup::getOrder()
public function getOrder(): OrderPickup::getToken()
public function getToken(): stringPickup::getMode()
public function getMode(): PickupModePickup::setMode()
public function setMode(PickupMode $mode): selfPickup::isPickup()
public function isPickup(): boolPickup::isDelivery()
public function isDelivery(): boolPickup::isShipping()
public function isShipping(): boolPickup::getStatus()
public function getStatus(): PickupStatusPickup::setStatus()
public function setStatus(PickupStatus $status): selfPickup::isAtCheckout()
public function isAtCheckout(): boolPickup::isOpen()
public function isOpen(): boolPickup::getFlow()
public function getFlow(): array- Returns
the steps of its tracking page
Pickup::getStep()
public function getStep(): intWhere it stands among its steps; -1 once cancelled, refused or refunded.
Pickup::getContactName()
public function getContactName(): ?stringPickup::setContactName()
public function setContactName(?string $contactName): selfPickup::getEmail()
public function getEmail(): ?stringPickup::setEmail()
public function setEmail(?string $email): selfPickup::getPhone()
public function getPhone(): ?stringPickup::setPhone()
public function setPhone(?string $phone): selfPickup::getDay()
public function getDay(): \DateTimeImmutablePickup::setDay()
public function setDay(\DateTimeImmutable $day): selfPickup::getSlot()
public function getSlot(): ?stringPickup::setSlot()
public function setSlot(?string $slot): selfPickup::getReadyAt()
public function getReadyAt(): ?\DateTimeImmutablePickup::setReadyAt()
public function setReadyAt(?\DateTimeImmutable $readyAt): selfPickup::getAddress()
public function getAddress(): ?stringPickup::setAddress()
public function setAddress(?string $address): selfPickup::getPostcode()
public function getPostcode(): ?stringPickup::setPostcode()
public function setPostcode(?string $postcode): selfPickup::getCity()
public function getCity(): ?stringPickup::setCity()
public function setCity(?string $city): selfPickup::getCountry()
public function getCountry(): ?stringPickup::setCountry()
public function setCountry(?string $country): selfPickup::getNote()
public function getNote(): ?stringPickup::setNote()
public function setNote(?string $note): selfPickup::getTrackingNumber()
public function getTrackingNumber(): ?stringPickup::setTrackingNumber()
public function setTrackingNumber(?string $trackingNumber): selfPickup::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableShipment class
class Shipment implements IconizeInterface, LinkableInterface Shipment.php:17
Shipment::__toString()
public function __toString()Shipment::__toLink()
public function __toLink(array $routeParameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): ?stringShipment::__iconize()
public function __iconize(): ?arrayShipment::__iconizeStatic()
public static function __iconizeStatic(): ?arrayShipment::getId()
public function getId()Shipment::__construct()
public function __construct()Shipment::getOrder()
public function getOrder(): ?OrderShipment::setOrder()
public function setOrder(?Order $order): selfShipment::getMethod()
public function getMethod(): ?ShippingMethodShipment::setMethod()
public function setMethod(?ShippingMethod $method): selfShipment::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceShipment::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceShipment::getItems()
public function getItems(): CollectionShipment::addItem()
public function addItem(OrderItem $item): selfShipment::removeItem()
public function removeItem(OrderItem $item): selfShipment::getNumber()
public function getNumber(): ?stringShipment::setNumber()
public function setNumber(string $number): selfSubscription 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(): stringSubscription::getId()
public function getId(): ?intSubscription::getSubscriber()
public function getSubscriber(): ?UserSubscription::getProduct()
public function getProduct(): ?ProductSubscription::setProduct()
public function setProduct(?Product $product): selfSubscription::getOrder()
public function getOrder(): ?OrderSubscription::getGateway()
public function getGateway(): stringSubscription::getProviderReference()
public function getProviderReference(): stringSubscription::getProviderCustomer()
public function getProviderCustomer(): ?stringSubscription::setProviderCustomer()
public function setProviderCustomer(?string $providerCustomer): selfSubscription::getStatus()
public function getStatus(): SubscriptionStatusSubscription::setStatus()
public function setStatus(SubscriptionStatus $status): selfSubscription::getInterval()
public function getInterval(): stringSubscription::setInterval()
public function setInterval(string $interval): selfSubscription::getCurrentPeriodEnd()
public function getCurrentPeriodEnd(): ?\DateTimeImmutableSubscription::setCurrentPeriodEnd()
public function setCurrentPeriodEnd(?\DateTimeImmutable $currentPeriodEnd): selfSubscription::isCancelAtPeriodEnd()
public function isCancelAtPeriodEnd(): boolSubscription::setCancelAtPeriodEnd()
public function setCancelAtPeriodEnd(bool $cancelAtPeriodEnd): selfSubscription::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableSubscription::getEndedAt()
public function getEndedAt(): ?\DateTimeImmutableSubscription::isRunning()
public function isRunning(): boolWhat 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(): stringSupplyJob::getId()
public function getId(): ?intSupplyJob::getOrder()
public function getOrder(): OrderSupplyJob::getSupplier()
public function getSupplier(): stringSupplyJob::getReference()
public function getReference(): stringSupplyJob::getSupplierReference()
public function getSupplierReference(): ?stringSupplyJob::getStatus()
public function getStatus(): SupplyStatusSupplyJob::getLines()
public function getLines(): arraySupplyJob::getRecipient()
public function getRecipient(): arraySupplyJob::getTrackingNumber()
public function getTrackingNumber(): ?stringSupplyJob::getTrackingUrl()
public function getTrackingUrl(): ?stringSupplyJob::getCarrier()
public function getCarrier(): ?stringSupplyJob::getMessage()
public function getMessage(): ?stringSupplyJob::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableSupplyJob::getUpdatedAt()
public function getUpdatedAt(): \DateTimeImmutableSupplyJob::update()
public function update(SupplyStatus $status, ?string $supplierReference = null, ?string $trackingNumber = null, ?string $trackingUrl = null, ?string $carrier = null, ?string $message = null): boolWhat the supplier says, kept; true when something moved.
Transaction class
class Transaction implements IconizeInterface Transaction.php:13
Transaction::__iconize()
public function __iconize(): ?arrayTransaction::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTransaction::__construct()
public function __construct()Transaction::getNumber()
public function getNumber(): ?stringTransaction::setNumber()
public function setNumber(?string $number): selfTransaction::getDescription()
public function getDescription(): ?stringTransaction::setDescription()
public function setDescription(?string $description): selfTransaction::getClientEmail()
public function getClientEmail(): ?stringTransaction::setClientEmail()
public function setClientEmail(?string $clientEmail): selfTransaction::getClientId()
public function getClientId(): ?stringTransaction::setClientId()
public function setClientId(?string $clientId): selfTransaction::getTotalAmount()
public function getTotalAmount(): intTransaction::setTotalAmount()
public function setTotalAmount(int $totalAmount): selfTransaction::getCurrencyCode()
public function getCurrencyCode(): ?stringTransaction::setCurrencyCode()
public function setCurrencyCode(?string $currencyCode): selfTransaction::getDetails()
public function getDetails(): arrayTransaction::setDetails()
public function setDetails(array $details): selfTransaction::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): selfTransaction::markAsPaid()
public function markAsPaid()Transaction::markAsCancelled()
public function markAsCancelled()Transaction::markAsRefunded()
public function markAsRefunded()Transaction::getComment()
public function getComment(): ?stringTransaction::setComment()
public function setComment(string $comment): selfTransaction::getWebhook()
public function getWebhook(): ?stringTransaction::setWebhook()
public function setWebhook(?string $webhook): selfTransaction::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceTransaction::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceTransaction::getOrder()
public function getOrder(): ?OrderTransaction::setOrder()
public function setOrder(?Order $order): selfBase\Marketplace\Entity\Order\Address
BillingAddress class
class BillingAddress extends Address BillingAddress.php:12
BillingAddress::getOrder()
public function getOrder(): ?OrderBillingAddress::setOrder()
public function setOrder(?Order $order): selfShippingAddress class
class ShippingAddress extends Address ShippingAddress.php:12
ShippingAddress::getOrder()
public function getOrder(): ?OrderShippingAddress::setOrder()
public function setOrder(?Order $order): selfBase\Marketplace\Entity\Order\Method
PaymentMethod class
class PaymentMethod implements IconizeInterface PaymentMethod.php:20
PaymentMethod::__toString()
public function __toString()PaymentMethod::__iconize()
public function __iconize(): ?arrayPaymentMethod::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPaymentMethod::__construct()
public function __construct()PaymentMethod::getId()
public function getId()PaymentMethod::getSlug()
public function getSlug(): ?stringPaymentMethod::setSlug()
public function setSlug(string $slug): selfPaymentMethod::getLabel()
public function getLabel(): ?stringPaymentMethod::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(): CollectionPaymentMethod::addOrder()
public function addOrder(Order $order): selfPaymentMethod::removeOrder()
public function removeOrder(Order $order): selfPaymentMethod::getRefundFee()
public function getRefundFee(): ?FeePaymentMethod::setRefundFee()
public function setRefundFee(?Fee $refundFee): selfPaymentMethod::getGatewayFactory()
public function getGatewayFactory(): ?stringPaymentMethod::setGatewayFactory()
public function setGatewayFactory(string $gatewayFactory): selfPaymentMethod::getGatewayConfig()
public function getGatewayConfig(): arrayPaymentMethod::getGatewayParameters()
public function getGatewayParameters(): arrayThe gateway's own settings, from the marketplace.gateways.<slug> parameter.
PaymentMethod::getScopes()
public function getScopes(): CollectionPaymentMethod::addScope()
public function addScope(PaymentMethodScope $scope): selfPaymentMethod::removeScope()
public function removeScope(PaymentMethodScope $scope): selfPaymentMethod::getRules()
public function getRules(): CollectionPaymentMethod::addRule()
public function addRule(PaymentMethodRule $rule): selfPaymentMethod::removeRule()
public function removeRule(PaymentMethodRule $rule): selfShippingMethod class
class ShippingMethod implements IconizeInterface ShippingMethod.php:21
ShippingMethod::__toString()
public function __toString()ShippingMethod::__iconize()
public function __iconize(): ?arrayShippingMethod::__iconizeStatic()
public static function __iconizeStatic(): ?arrayShippingMethod::__construct()
public function __construct()ShippingMethod::getId()
public function getId()ShippingMethod::getOrders()
public function getOrders(): CollectionShippingMethod::addOrder()
public function addOrder(Order $order): selfShippingMethod::removeOrder()
public function removeOrder(Order $order): selfShippingMethod::getGatewayParameters()
public function getGatewayParameters(): arrayShippingMethod::hasCarrier()
public function hasCarrier(): boolWhether a carrier takes it: false for a pickup at the shop, the shop's own round.
ShippingMethod::getGatewayName()
public function getGatewayName(): ?stringShippingMethod::setGatewayName()
public function setGatewayName(?string $gatewayName): selfShippingMethod::getSlug()
public function getSlug(): ?stringShippingMethod::setSlug()
public function setSlug(string $slug): selfShippingMethod::getLabel()
public function getLabel(): ?stringShippingMethod::setLabel()
public function setLabel(?string $label)ShippingMethod::getShippingDelay()
public function getShippingDelay(): ?intShippingMethod::setShippingDelay()
public function setShippingDelay(?int $shippingDelay): selfShippingMethod::getDeliveryTime()
public function getDeliveryTime(): ?intShippingMethod::setDeliveryTime()
public function setDeliveryTime(?int $deliveryTime): selfShippingMethod::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): selfShippingMethod::getUnitPrice()
public function getUnitPrice(): ?intShippingMethod::setUnitPrice()
public function setUnitPrice(?int $unitPrice): selfShippingMethod::getCurrency()
public function getCurrency(): ?stringShippingMethod::setCurrency()
public function setCurrency(string $currency): selfShippingMethod::getServiceFee()
public function getServiceFee(): ?FeeShippingMethod::setServiceFee()
public function setServiceFee(?Fee $serviceFee): selfShippingMethod::getTrackingUrl()
public function getTrackingUrl(): ?stringShippingMethod::setTrackingUrl()
public function setTrackingUrl(?string $trackingUrl): selfShippingMethod::getScopes()
public function getScopes(): CollectionShippingMethod::addScope()
public function addScope(ShippingMethodScope $scope): selfShippingMethod::removeScope()
public function removeScope(ShippingMethodScope $scope): selfShippingMethod::getRules()
public function getRules(): CollectionShippingMethod::addRule()
public function addRule(ShippingMethodRule $rule): selfShippingMethod::removeRule()
public function removeRule(ShippingMethodRule $rule): selfBase\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(): stringAssociation::getId()
public function getId(): ?intAssociation::getProduct()
public function getProduct(): ?ProductAssociation::setProduct()
public function setProduct(?Product $product): selfAssociation::getTarget()
public function getTarget(): ?ProductAssociation::setTarget()
public function setTarget(?Product $target): selfAssociation::getType()
public function getType(): AssociationTypeAssociation::setType()
public function setType(AssociationType $type): selfAssociation::getNotes()
public function getNotes(): arrayAssociation::setNotes()
public function setNotes(array $notes): selfAssociation::getNote()
public function getNote(?string $locale = null): ?stringThe note in this language, else in the first one written.
Association::setNote()
public function setNote(string $locale, ?string $note): selfAssociation::getPosition()
public function getPosition(): intAssociation::setPosition()
public function setPosition(int $position): selfAttribute class
class Attribute extends Attribute implements IconizeInterface Attribute.php:12
Attribute::__iconizeStatic()
public static function __iconizeStatic(): ?arrayAttribute::getProduct()
public function getProduct(): ?ProductAttribute::setProduct()
public function setProduct(?Product $product): selfAttributeSet 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(): stringAttributeSet::getId()
public function getId(): ?intAttributeSet::getName()
public function getName(): stringAttributeSet::setName()
public function setName(string $name): selfAttributeSet::getTaxon()
public function getTaxon(): ?TaxonAttributeSet::setTaxon()
public function setTaxon(?Taxon $taxon): selfAttributeSet::getFields()
public function getFields(): CollectionAttributeSet::addField()
public function addField(Field $field): selfAttributeSet::removeField()
public function removeField(Field $field): selfAttributeSet::getFilterableFields()
public function getFilterableFields(): array- Returns
those the list filters on
AttributeSet::getField()
public function getField(string $code): ?FieldThe 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(): ?arrayFeature::getProducts()
public function getProducts(): CollectionFeature::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): selfIdentifier class
class Identifier Identifier.php:15
Identifier::__iconize()
public function __iconize(): ?arrayIdentifier::__iconizeStatic()
public static function __iconizeStatic(): ?arrayIdentifier::__construct()
public function __construct()Identifier::getId()
public function getId(): ?intIdentifier::getProduct()
public function getProduct(): ?ProductIdentifier::setProduct()
public function setProduct(?Product $product): selfIdentifier::getBarcodes()
public function getBarcodes(): CollectionIdentifier::getBarcode()
public function getBarcode($std): ?BarcodeIdentifier::addBarcode()
public function addBarcode(Barcode $barcode): selfIdentifier::removeBarcode()
public function removeBarcode(Barcode $barcode): selfImage class
class Image extends Image implements IconizeInterface Image.php:12
Image::__iconize()
public function __iconize(): ?arrayImage::__iconizeStatic()
public static function __iconizeStatic(): ?arrayImage::getProduct()
public function getProduct(): ?ProductImage::setProduct()
public function setProduct(?Product $product): selfOption 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(): stringOption::getId()
public function getId(): ?intOption::getGroup()
public function getGroup(): ?OptionGroupOption::setGroup()
public function setGroup(?OptionGroup $group): selfOption::getLabel()
public function getLabel(?string $locale = null): stringOption::setLabel()
public function setLabel(string $label): selfOption::getLabels()
public function getLabels(): arrayOption::setLabels()
public function setLabels(array $labels): selfOption::getPrice()
public function getPrice(): intOption::setPrice()
public function setPrice(int $price): selfOption::isDefault()
public function isDefault(): boolOption::setDefault()
public function setDefault(bool $default): selfOption::isAvailable()
public function isAvailable(): boolOption::setAvailable()
public function setAvailable(bool $available): selfOption::getPosition()
public function getPosition(): intOption::setPosition()
public function setPosition(int $position): selfOptionGroup 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(): stringOptionGroup::getId()
public function getId(): ?intOptionGroup::getProduct()
public function getProduct(): ?ProductOptionGroup::setProduct()
public function setProduct(?Product $product): selfOptionGroup::getLabel()
public function getLabel(?string $locale = null): stringThe label in this language, else the one it was written in.
OptionGroup::setLabel()
public function setLabel(string $label): selfOptionGroup::getLabels()
public function getLabels(): arrayOptionGroup::setLabels()
public function setLabels(array $labels): selfOptionGroup::isMultiple()
public function isMultiple(): boolOptionGroup::setMultiple()
public function setMultiple(bool $multiple): selfOptionGroup::getMinimum()
public function getMinimum(): intOptionGroup::setMinimum()
public function setMinimum(int $minimum): selfOptionGroup::isRequired()
public function isRequired(): boolOptionGroup::getMaximum()
public function getMaximum(): ?intOne for a single choice; the group's own for a multiple one (null: no ceiling).
OptionGroup::setMaximum()
public function setMaximum(?int $maximum): selfOptionGroup::getPosition()
public function getPosition(): intOptionGroup::setPosition()
public function setPosition(int $position): selfOptionGroup::getOptions()
public function getOptions(): CollectionOptionGroup::getAvailableOptions()
public function getAvailableOptions(): array- Returns
those that can be chosen now
OptionGroup::addOption()
public function addOption(Option $option): selfOptionGroup::removeOption()
public function removeOption(Option $option): selfOptionGroup::option()
public function option(string $label, int $price = 0, bool $default = false, array $labels = []): selfShorthand 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(): ?arrayTaxon::__construct()
public function __construct(?string $label = null, ?string $slug = null, ?Store $store = null)Taxon::getStore()
public function getStore(): ?StoreTaxon::setStore()
public function setStore(?Store $store): selfTaxon::isAgeRestricted()
public function isAgeRestricted(): boolTaxon::getAgeRestricted()
public function getAgeRestricted(): boolTaxon::setAgeRestricted()
public function setAgeRestricted(bool $ageRestricted): selfVariant class
class Variant extends Product implements TranslatableInterface Variant.php:18
Variant::__iconizeStatic()
public static function __iconizeStatic(): ?arrayVariant::__construct()
public function __construct(?Product $product = null, int $unitPrice = 0, ?string $currency = null)Variant::isVariant()
public static function isVariant()Variant::getPrincipal()
public function getPrincipal(): ?ProductVariant::setPrincipal()
public function setPrincipal(?Product $wallpaper)Variant::getImage()
public function getImage(?int $i = null, $inheritIfNotSet = !Product::INHERITS_FROM): ?ImageVariant::getImageCrop()
public function getImageCrop(string $slug, ?int $i = null, $inheritIfNotSet = !Product::INHERITS_FROM): ?ImageCropVariant::getImages()
public function getImages($inheritIfNotSet = !Product::INHERITS_FROM): CollectionVariant::getImageMarketplaces()
public function getImageMarketplaces($inheritIfNotSet = !Product::INHERITS_FROM)Variant::getTitle()
public function getTitle(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?stringVariant::getHeadline()
public function getHeadline(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?stringVariant::getExcerpt()
public function getExcerpt(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?stringVariant::getContent()
public function getContent(?string $locale = null, int $inheritanceDepthIfNotSet = 1): ?stringVariant::getKeywords()
public function getKeywords(?string $locale = null, int $inheritanceDepthIfNotSet = 1): arrayVariant::getStore()
public function getStore(): ?StoreVariant::setStore()
public function setStore(?Store $store)Variant::getTaxa()
public function getTaxa($inheritIfNotSet = Product::INHERITS_FROM): CollectionVariant::getTags()
public function getTags($inheritIfNotSet = Product::INHERITS_FROM): CollectionVariant::getOwner()
public function getOwner(int $i = 0, $inheritIfNotSet = Product::INHERITS_FROM)Variant::getOwners()
public function getOwners($inheritIfNotSet = Product::INHERITS_FROM): CollectionVariant::getAuthor()
public function getAuthor(int $i = 0, $inheritIfNotSet = Product::INHERITS_FROM)Variant::getAuthors()
public function getAuthors($inheritIfNotSet = Product::INHERITS_FROM): CollectionBase\Marketplace\Entity\Product\Attribute
Barcode class
class Barcode extends AbstractAttribute Barcode.php:16
Barcode::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBarcode::__construct()
public function __construct(BarcodeAdapter $adapter, mixed $value = null)Barcode::get()
public function get(?string $locale = null): mixedBarcode::set()
public function set(...$args): selfBarcode::resolve()
public function resolve(?string $locale = null): mixedBarcode::getIdentifier()
public function getIdentifier(): ?IdentifierBarcode::setIdentifier()
public function setIdentifier(?Identifier $identifier): selfBarcode::getValue()
public function getValue(): ?stringBarcode::setValue()
public function setValue($value)Barcode::getAdapter()
public function getAdapter(): ?BarcodeAdapterBarcode::setAdapter()
public function setAdapter(?AbstractAdapter $adapter): selfBarcode::getStandard()
public function getStandard(): ?stringHyperlink class
class Hyperlink extends Hyperlink Hyperlink.php:11
Hyperlink::__iconizeStatic()
public static function __iconizeStatic(): ?arrayHyperlink::getProduct()
public function getProduct(): ?ProductHyperlink::setProduct()
public function setProduct(?Product $product): selfBase\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(): stringField::getId()
public function getId(): ?intField::getAttributeSet()
public function getAttributeSet(): ?AttributeSetField::setAttributeSet()
public function setAttributeSet(?AttributeSet $attributeSet): selfField::getAdapter()
public function getAdapter(): ?AbstractAdapterField::setAdapter()
public function setAdapter(?AbstractAdapter $adapter): selfField::getCode()
public function getCode(): ?stringThe attribute's code ("appellation"), the key the filters read in the query string.
Field::getPosition()
public function getPosition(): intField::setPosition()
public function setPosition(int $position): selfField::isRequired()
public function isRequired(): boolField::setRequired()
public function setRequired(bool $required): selfField::isFilterable()
public function isFilterable(): boolField::setFilterable()
public function setFilterable(bool $filterable): selfField::getFilter()
public function getFilter(): stringField::setFilter()
public function setFilter(string $filter): selfField::getUnit()
public function getUnit(): ?stringField::setUnit()
public function setUnit(?string $unit): selfField::isVisible()
public function isVisible(): boolField::setVisible()
public function setVisible(bool $visible): selfBase\Marketplace\Entity\Product\Attribute\Adapter
BarcodeAdapter class
class BarcodeAdapter extends AbstractAdapter implements IconizeInterface BarcodeAdapter.php:13
BarcodeAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBarcodeAdapter::getType()
public static function getType(): stringBarcodeAdapter::getOptions()
public function getOptions(): arrayBarcodeAdapter::resolve()
public function resolve(mixed $value): mixedBarcodeAdapter::getStandard()
public function getStandard()BarcodeAdapter::setStandard()
public function setStandard($standard): selfBase\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(): stringAbstractQuote::getLines()
abstract public function getLines(): Collection- Returns
its lines, in order
AbstractQuote::getSubtotal()
abstract public function getSubtotal(): intBefore the discount, in cents.
AbstractQuote::getId()
public function getId(): ?intAbstractQuote::getReference()
public function getReference(): stringAbstractQuote::setReference()
public function setReference(string $reference): staticAbstractQuote::getToken()
public function getToken(): stringAbstractQuote::getClient()
public function getClient(): ?UserAbstractQuote::setClient()
public function setClient(?User $client): staticAbstractQuote::getSiret()
public function getSiret(): ?stringAbstractQuote::setSiret()
public function setSiret(?string $siret): staticAbstractQuote::getCompany()
public function getCompany(): ?arrayAbstractQuote::setCompanyCheck()
public function setCompanyCheck(array $lookup): staticRecords the register's answer: FOUND with the company, or why not.
AbstractQuote::setCompanyRecord()
public function setCompanyRecord(?array $company): staticRecords a company checked elsewhere (VIES for a foreign one): its name, its number, the source.
AbstractQuote::getCompanyBadge()
public function getCompanyBadge(): ?stringFor the back office: verified, closed, unknown, unchecked.
AbstractQuote::getCompanyName()
public function getCompanyName(): ?stringThe company's name as the register has it, else null.
AbstractQuote::getEmail()
public function getEmail(): stringAbstractQuote::setEmail()
public function setEmail(string $email): staticAbstractQuote::getContactName()
public function getContactName(): stringAbstractQuote::setContactName()
public function setContactName(string $contactName): staticAbstractQuote::getTitle()
public function getTitle(): stringAbstractQuote::setTitle()
public function setTitle(string $title): staticAbstractQuote::getRequest()
public function getRequest(): ?stringAbstractQuote::setRequest()
public function setRequest(?string $request): staticAbstractQuote::getMessage()
public function getMessage(): ?stringAbstractQuote::setMessage()
public function setMessage(?string $message): staticAbstractQuote::getStatus()
public function getStatus(): QuoteStatusAbstractQuote::setStatus()
public function setStatus(QuoteStatus $status): staticAbstractQuote::getDiscountPercent()
public function getDiscountPercent(): intAbstractQuote::setDiscountPercent()
public function setDiscountPercent(int $discountPercent): staticAbstractQuote::getCurrency()
public function getCurrency(): stringAbstractQuote::setCurrency()
public function setCurrency(string $currency): staticAbstractQuote::getValidUntil()
public function getValidUntil(): ?\DateTimeImmutableAbstractQuote::setValidUntil()
public function setValidUntil(?\DateTimeImmutable $validUntil): staticAbstractQuote::isExpired()
public function isExpired(?\DateTimeImmutable $at = null): boolAbstractQuote::hasSomethingToSell()
public function hasSomethingToSell(): boolWhether there is anything to sell in it: a total above zero.
AbstractQuote::isAcceptable()
public function isAcceptable(): boolWhether the client may accept it now.
AbstractQuote::getDiscountAmount()
public function getDiscountAmount(): intAbstractQuote::getTotal()
public function getTotal(): intWhat the client pays before VAT, in cents.
AbstractQuote::getOrderReference()
public function getOrderReference(): ?stringAbstractQuote::setOrderReference()
public function setOrderReference(?string $orderReference): staticAbstractQuote::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableAbstractQuote::getAcceptedAt()
public function getAcceptedAt(): ?\DateTimeImmutableAbstractQuote::accept()
public function accept(): staticAbstractQuote::markPaid()
public function markPaid(?string $orderReference = null): staticPaid: 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(): stringQuoteLine::getId()
public function getId(): ?intQuoteLine::getQuote()
public function getQuote(): ?QuoteQuoteLine::setQuote()
public function setQuote(?Quote $quote): selfQuoteLine::getProduct()
public function getProduct(): ?ProductQuoteLine::setProduct()
public function setProduct(?Product $product): selfQuoteLine::isFree()
public function isFree(): boolQuoteLine::getLabel()
public function getLabel(): stringQuoteLine::setLabel()
public function setLabel(?string $label): selfQuoteLine::getQuantity()
public function getQuantity(): intQuoteLine::setQuantity()
public function setQuantity(int $quantity): selfQuoteLine::getLotSize()
public function getLotSize(): intQuoteLine::setLotSize()
public function setLotSize(int $lotSize): selfQuoteLine::getLotPrice()
public function getLotPrice(): intQuoteLine::setLotPrice()
public function setLotPrice(int $lotPrice): selfQuoteLine::getPosition()
public function getPosition(): intQuoteLine::setPosition()
public function setPosition(int $position): selfQuoteLine::getUnits()
public function getUnits(): intHow many units the line holds.
QuoteLine::getAmount()
public function getAmount(): intThe 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(): ?arrayTaxon::__construct()
public function __construct(?string $label = null, ?string $slug = null, ?Store $store = null)Taxon::getStore()
public function getStore(): ?StoreTaxon::setStore()
public function setStore(?Store $store): selfBase\Marketplace\Entity\Sales
Channel class
class Channel extends Tag implements IconizeInterface Channel.php:16
Channel::__iconizeStatic()
public static function __iconizeStatic(): ?arrayChannel::__construct()
public function __construct()Channel::getProducts()
public function getProducts(): CollectionChannel::addProduct()
public function addProduct(Product $product): selfChannel::removeProduct()
public function removeProduct(Product $product): selfDiscount class
class Discount implements IconizeInterface Discount.php:18
Discount::__toString()
public function __toString()Discount::__construct()
public function __construct()Discount::__iconize()
public function __iconize(): ?arrayDiscount::__iconizeStatic()
public static function __iconizeStatic(): ?arrayDiscount::getId()
public function getId()Discount::getLabel()
public function getLabel(): ?stringDiscount::setLabel()
public function setLabel(?string $label)Discount::getValidAt()
public function getValidAt(): ?\DateTimeInterfaceDiscount::setValidAt()
public function setValidAt(?\DateTimeInterface $validAt): selfDiscount::getExpiredAt()
public function getExpiredAt(): ?\DateTimeInterfaceDiscount::setExpiredAt()
public function setExpiredAt(?\DateTimeInterface $expiredAt): selfDiscount::getCountOrders()
public function getCountOrders(): intDiscount::setCountOrders()
public function setCountOrders(mixed $countOrder): selfDiscount::getOrders()
public function getOrders(): CollectionDiscount::addOrder()
public function addOrder(Order $order): selfDiscount::removeOrder()
public function removeOrder(Order $order): selfDiscount::getRules()
public function getRules(): CollectionDiscount::addRule()
public function addRule(DiscountRule $rule): selfDiscount::removeRule()
public function removeRule(DiscountRule $rule): selfDiscount::getActions()
public function getActions(): CollectionDiscount::getFormattedActions()
public function getFormattedActions(): stringDiscount::addAction()
public function addAction(DiscountAction $action): selfDiscount::removeAction()
public function removeAction(DiscountAction $action): selfDiscount::getScopes()
public function getScopes(): CollectionDiscount::addScope()
public function addScope(DiscountScope $scope): selfDiscount::removeScope()
public function removeScope(DiscountScope $scope): selfFee class
class Fee implements IconizeInterface Fee.php:16
Fee::__toString()
public function __toString()Fee::__iconize()
public function __iconize(): ?arrayFee::__iconizeStatic()
public static function __iconizeStatic(): ?arrayFee::__construct()
public function __construct()Fee::getId()
public function getId()Fee::getLabel()
public function getLabel(): ?stringFee::setLabel()
public function setLabel(?string $label)Fee::getScopes()
public function getScopes(): CollectionFee::addScope()
public function addScope(FeeScope $scope): selfFee::removeScope()
public function removeScope(FeeScope $scope): selfFee::getRules()
public function getRules(): CollectionFee::addRule()
public function addRule(FeeRule $rule): selfFee::removeRule()
public function removeRule(FeeRule $rule): selfFee::getActions()
public function getActions(): CollectionFee::addAction()
public function addAction(FeeAction $action): selfFee::removeAction()
public function removeAction(FeeAction $action): selfForex class
class Forex implements IconizeInterface Forex.php:11
Forex::__iconize()
public function __iconize(): ?arrayForex::__iconizeStatic()
public static function __iconizeStatic(): ?arrayForex::getId()
public function getId()Forex::getSource()
public function getSource(): ?stringForex::setSource()
public function setSource(string $source): selfForex::getTarget()
public function getTarget(): ?stringForex::setTarget()
public function setTarget(string $target): selfForex::getProvider()
public function getProvider(): ?stringForex::getRate()
public function getRate(): ?floatForex::setProvider()
public function setProvider(?string $provider): selfForex::setRate()
public function setRate(float $rate, ?string $provider = null): selfThe rate, and where it comes from: a provider's name, or null for one set by hand.
Forex::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceForex::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceRegion class
class Region extends Tag implements IconizeInterface Region.php:17
Region::__iconize()
public function __iconize(): ?arrayRegion::__iconizeStatic()
public static function __iconizeStatic(): ?arrayRegion::__construct()
public function __construct()Region::getStores()
public function getStores(): CollectionRegion::addStore()
public function addStore(Store $stores): selfRegion::removeStore()
public function removeStore(Store $stores): selfRegion::getCurrency()
public function getCurrency(): ?stringRegion::setCurrency()
public function setCurrency(string $currency): selfRegion::isEnabled()
public function isEnabled(): ?boolRegion::setEnabled()
public function setEnabled(bool $enabled): selfRegion::getCountries()
public function getCountries(): ?arrayRegion::setCountries()
public function setCountries(array $countries): selfRegion::getOrders()
public function getOrders(): CollectionRegion::addOrder()
public function addOrder(Order $order): selfRegion::removeOrder()
public function removeOrder(Order $order): selfTax class
class Tax implements IconizeInterface Tax.php:15
Tax::__iconize()
public function __iconize(): ?arrayTax::__iconizeStatic()
public static function __iconizeStatic(): ?arrayTax::__construct()
public function __construct()Tax::getId()
public function getId()Tax::getLabel()
public function getLabel(): ?stringTax::setLabel()
public function setLabel(?string $label)Tax::getScopes()
public function getScopes(): CollectionTax::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): selfTax::getRate()
public function getRate(): ?floatTax::setRate()
public function setRate(float $rate): selfBase\Marketplace\Entity\Sales\Attribute
DiscountAction class
class DiscountAction extends AbstractAction DiscountAction.php:12
DiscountAction::get()
public function get(?string $locale = null): mixedDiscountAction::set()
public function set(...$args): selfDiscountAction::resolve()
public function resolve(?string $locale = null): mixedDiscountAction::getDiscount()
public function getDiscount(): ?DiscountDiscountAction::setDiscount()
public function setDiscount(?Discount $discount): selfDiscountAction::appliesToItems()
public function appliesToItems(): boolDiscountRule class
class DiscountRule extends AbstractRule DiscountRule.php:12
DiscountRule::get()
public function get(?string $locale = null): mixedDiscountRule::set()
public function set(...$args): selfDiscountRule::resolve()
public function resolve(?string $locale = null): mixedDiscountRule::getDiscount()
public function getDiscount(): ?DiscountDiscountRule::setDiscount()
public function setDiscount(?Discount $discount): selfDiscountScope class
class DiscountScope extends AbstractScope DiscountScope.php:12
DiscountScope::get()
public function get(?string $locale = null): mixedDiscountScope::set()
public function set(...$args): selfDiscountScope::resolve()
public function resolve(?string $locale = null): mixedDiscountScope::getDiscount()
public function getDiscount(): ?DiscountDiscountScope::setDiscount()
public function setDiscount(?Discount $discount): selfFeeAction class
class FeeAction extends AbstractAction FeeAction.php:12
FeeAction::get()
public function get(?string $locale = null): mixedFeeAction::set()
public function set(...$args): selfFeeAction::resolve()
public function resolve(?string $locale = null): mixedFeeAction::getFee()
public function getFee(): ?FeeFeeAction::setFee()
public function setFee(?Fee $fee): selfFeeAction::appliesToItems()
public function appliesToItems(): boolFeeRule class
class FeeRule extends AbstractRule FeeRule.php:12
FeeRule::get()
public function get(?string $locale = null): mixedFeeRule::set()
public function set(...$args): selfFeeRule::resolve()
public function resolve(?string $locale = null): mixedFeeRule::getFee()
public function getFee(): ?FeeFeeRule::setFee()
public function setFee(?Fee $fee): selfFeeScope class
class FeeScope extends AbstractScope FeeScope.php:12
FeeScope::get()
public function get(?string $locale = null): mixedFeeScope::set()
public function set(...$args): selfFeeScope::resolve()
public function resolve(?string $locale = null): mixedFeeScope::getFee()
public function getFee(): ?FeeFeeScope::setFee()
public function setFee(?Fee $fee): selfPaymentMethodRule class
class PaymentMethodRule extends AbstractRule PaymentMethodRule.php:12
PaymentMethodRule::get()
public function get(?string $locale = null): mixedPaymentMethodRule::set()
public function set(...$args): selfPaymentMethodRule::resolve()
public function resolve(?string $locale = null): mixedPaymentMethodRule::getPaymentMethod()
public function getPaymentMethod(): ?PaymentMethodPaymentMethodRule::setPaymentMethod()
public function setPaymentMethod(?PaymentMethod $paymentMethod): selfPaymentMethodScope class
class PaymentMethodScope extends AbstractScope PaymentMethodScope.php:12
PaymentMethodScope::get()
public function get(?string $locale = null): mixedPaymentMethodScope::set()
public function set(...$args): selfPaymentMethodScope::resolve()
public function resolve(?string $locale = null): mixedPaymentMethodScope::getPaymentMethod()
public function getPaymentMethod(): ?PaymentMethodPaymentMethodScope::setPaymentMethod()
public function setPaymentMethod(?PaymentMethod $paymentMethod): selfShippingMethodRule class
class ShippingMethodRule extends AbstractRule ShippingMethodRule.php:12
ShippingMethodRule::get()
public function get(?string $locale = null): mixedShippingMethodRule::set()
public function set(...$args): selfShippingMethodRule::resolve()
public function resolve(?string $locale = null): mixedShippingMethodRule::getShippingMethod()
public function getShippingMethod(): ?ShippingMethodShippingMethodRule::setShippingMethod()
public function setShippingMethod(?ShippingMethod $shippingMethod): selfShippingMethodScope class
class ShippingMethodScope extends AbstractScope ShippingMethodScope.php:12
ShippingMethodScope::get()
public function get(?string $locale = null): mixedShippingMethodScope::set()
public function set(...$args): selfShippingMethodScope::resolve()
public function resolve(?string $locale = null): mixedShippingMethodScope::getShippingMethod()
public function getShippingMethod(): ?ShippingMethodShippingMethodScope::setShippingMethod()
public function setShippingMethod(?ShippingMethod $shippingMethod): selfTaxScope class
class TaxScope extends AbstractScope TaxScope.php:12
TaxScope::get()
public function get(?string $locale = null): mixedTaxScope::set()
public function set(...$args): selfTaxScope::resolve()
public function resolve(?string $locale = null): mixedTaxScope::getTax()
public function getTax(): ?TaxTaxScope::setTax()
public function setTax(?Tax $tax): selfBase\Marketplace\Entity\Sales\Attribute\Action
FixedAmountAdapter class
class FixedAmountAdapter extends AbstractActionAdapter FixedAmountAdapter.php:16
FixedAmountAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayFixedAmountAdapter::getType()
public static function getType(): stringFixedAmountAdapter::getOptions()
public function getOptions(): arrayFixedAmountAdapter::resolve()
public function resolve(mixed $value): mixedFixedAmountAdapter::apply()
public function apply(mixed $value, mixed $subject): mixedFixedAmountAdapter::getCurrency()
public function getCurrency(): stringFixedAmountAdapter::setCurrency()
public function setCurrency(string $currency)FixedAmountAdapter::appliesToItems()
public function appliesToItems(): ?boolFixedAmountAdapter::setAppliesToItems()
public function setAppliesToItems(bool $appliesToItems): selfPercentageAmountAdapter class
class PercentageAmountAdapter extends AbstractActionAdapter PercentageAmountAdapter.php:14
PercentageAmountAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPercentageAmountAdapter::getType()
public static function getType(): stringPercentageAmountAdapter::getOptions()
public function getOptions(): arrayPercentageAmountAdapter::resolve()
public function resolve(mixed $value): mixedPercentageAmountAdapter::apply()
public function apply(mixed $value, mixed $subject): mixedPercentageAmountAdapter::appliesToItems()
public function appliesToItems(): ?boolPercentageAmountAdapter::setAppliesToItems()
public function setAppliesToItems(bool $appliesToItems): selfBase\Marketplace\Entity\Sales\Attribute\Rule
CartContainsAdapter class
class CartContainsAdapter extends AbstractRuleAdapter CartContainsAdapter.php:13
CartContainsAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayCartContainsAdapter::getType()
public static function getType(): stringCartContainsAdapter::getOptions()
public function getOptions(): arrayCartContainsAdapter::resolve()
public function resolve(mixed $value): mixedCartContainsAdapter::supports()
public function supports(mixed $value): boolCartContainsAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolCartQuantityAdapter class
class CartQuantityAdapter extends AbstractRuleAdapter CartQuantityAdapter.php:14
CartQuantityAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayCartQuantityAdapter::getType()
public static function getType(): stringCartQuantityAdapter::getOptions()
public function getOptions(): arrayCartQuantityAdapter::resolve()
public function resolve(mixed $value): mixedCartQuantityAdapter::supports()
public function supports(mixed $value): boolCartQuantityAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolCartQuantityAdapter::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(): ?arrayTotalPriceAdapter::getType()
public static function getType(): stringTotalPriceAdapter::getOptions()
public function getOptions(): arrayTotalPriceAdapter::resolve()
public function resolve(mixed $value): mixedTotalPriceAdapter::supports()
public function supports(mixed $value): boolTotalPriceAdapter::compliesWith()
public function compliesWith(mixed $value, mixed $subject): boolTotalPriceAdapter::getCurrency()
public function getCurrency(): stringTotalPriceAdapter::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(): ?arrayOrderAdapter::getType()
public static function getType(): stringOrderAdapter::getOptions()
public function getOptions(): arrayOrderAdapter::resolve()
public function resolve(mixed $value): mixedOrderAdapter::supports()
public function supports(mixed $value): boolOrderAdapter::contains()
public function contains(mixed $value, mixed $subject): boolProductAdapter class
class ProductAdapter extends AbstractScopeAdapter ProductAdapter.php:14
ProductAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayProductAdapter::getType()
public static function getType(): stringProductAdapter::getOptions()
public function getOptions(): arrayProductAdapter::resolve()
public function resolve(mixed $value): mixedProductAdapter::supports()
public function supports(mixed $value): boolProductAdapter::contains()
public function contains(mixed $value, mixed $subject): boolRegionAdapter class
class RegionAdapter extends AbstractScopeAdapter RegionAdapter.php:18
RegionAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayRegionAdapter::getType()
public static function getType(): stringRegionAdapter::getOptions()
public function getOptions(): arrayRegionAdapter::resolve()
public function resolve(mixed $value): mixedRegionAdapter::supports()
public function supports(mixed $value): boolRegionAdapter::contains()
public function contains(mixed $value, mixed $subject): boolStoreAdapter class
class StoreAdapter extends AbstractScopeAdapter StoreAdapter.php:17
StoreAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayStoreAdapter::getType()
public static function getType(): stringStoreAdapter::getOptions()
public function getOptions(): arrayStoreAdapter::resolve()
public function resolve(mixed $value): mixedStoreAdapter::supports()
public function supports(mixed $value): boolStoreAdapter::contains()
public function contains(mixed $value, mixed $subject): boolThe 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(): ?arrayTaxonAdapter::getType()
public static function getType(): stringTaxonAdapter::getOptions()
public function getOptions(): arrayTaxonAdapter::resolve()
public function resolve(mixed $value): mixedTaxonAdapter::supports()
public function supports(mixed $value): boolTaxonAdapter::contains()
public function contains(mixed $value, mixed $subject): boolUserAdapter class
class UserAdapter extends AbstractScopeAdapter UserAdapter.php:14
UserAdapter::__iconizeStatic()
public static function __iconizeStatic(): ?arrayUserAdapter::getType()
public static function getType(): stringUserAdapter::getOptions()
public function getOptions(): arrayUserAdapter::resolve()
public function resolve(mixed $value): mixedUserAdapter::supports()
public function supports(mixed $value): boolUserAdapter::contains()
public function contains(mixed $value, mixed $subject): boolBase\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(): ?arrayCoupon::__iconizeStatic()
public static function __iconizeStatic(): ?arrayCoupon::getCode()
public function getCode(): ?stringCoupon::setCode()
public function setCode(string $code): selfCoupon::getQuota()
public function getQuota(): ?intCoupon::setQuota()
public function setQuota(?int $quota): selfCoupon::getQuotaPerCustomer()
public function getQuotaPerCustomer(): ?intCoupon::setQuotaPerCustomer()
public function setQuotaPerCustomer(?int $quotaPerCustomer): selfCoupon::isIndividualUse()
public function isIndividualUse(): ?boolCoupon::setIndividualUse()
public function setIndividualUse(bool $individualUse): selfCoupon::getOwner()
public function getOwner(): ?UserCoupon::setOwner()
public function setOwner(?User $owner): selfPromotion class
class Promotion extends Discount implements IconizeInterface Promotion.php:12
Promotion::__toString()
public function __toString()Promotion::__iconize()
public function __iconize(): ?arrayPromotion::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPromotion::getPriority()
public function getPriority(): ?intPromotion::setPriority()
public function setPriority(int $priority): selfBase\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(): ?intReferral::getCode()
public function getCode(): ReferralCodeReferral::getReferrer()
public function getReferrer(): ?UserReferral::getReferee()
public function getReferee(): ?UserReferral::getStatus()
public function getStatus(): ReferralStatusReferral::getOrderReference()
public function getOrderReference(): ?stringReferral::getFingerprint()
public function getFingerprint(): ?stringReferral::getRejection()
public function getRejection(): ?stringReferral::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableReferral::getQualifiedAt()
public function getQualifiedAt(): ?\DateTimeImmutableReferral::getRewardedAt()
public function getRewardedAt(): ?\DateTimeImmutableReferral::qualify()
public function qualify(string $orderReference, ?string $fingerprint = null, ?\DateTimeImmutable $at = null): selfReferral::markRewarded()
public function markRewarded(): selfReferral::reject()
public function reject(string $reason): selfself, 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): stringReferralCode::normalize()
public static function normalize(string $code): stringReferralCode::__toString()
public function __toString(): stringReferralCode::getId()
public function getId(): ?intReferralCode::getOwner()
public function getOwner(): ?UserReferralCode::getCode()
public function getCode(): stringReferralCode::isEnabled()
public function isEnabled(): boolReferralCode::setEnabled()
public function setEnabled(bool $enabled): selfReferralCode::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableReward 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(): ?intReward::getReferral()
public function getReferral(): ReferralReward::getBeneficiary()
public function getBeneficiary(): ?UserReward::getRole()
public function getRole(): stringReward::getCoupon()
public function getCoupon(): ?CouponReward::setCoupon()
public function setCoupon(?Coupon $coupon): selfReward::getCreditKind()
public function getCreditKind(): ?stringReward::getCreditQuantity()
public function getCreditQuantity(): ?intReward::setCredit()
public function setCredit(string $kind, int $quantity): selfReward::getGrantedAt()
public function getGrantedAt(): \DateTimeImmutableBase\Marketplace\Entity\Sales\Tax
Vat class
class Vat extends Tax implements IconizeInterface Vat.php:12
Vat::__iconize()
public function __iconize(): ?arrayVat::__iconizeStatic()
public static function __iconizeStatic(): ?arrayBase\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(): ?intContribution::getItem()
public function getItem(): ItemContribution::getWishlist()
public function getWishlist(): ?WishlistContribution::getReference()
public function getReference(): stringContribution::getAmount()
public function getAmount(): intThe gift, in minor units.
Contribution::getFee()
public function getFee(): intContribution::isFeeCovered()
public function isFeeCovered(): boolContribution::setFee()
public function setFee(int $fee, bool $covered): selfContribution::getCharged()
public function getCharged(): intWhat the giver pays: the gift, plus the fee when they cover it.
Contribution::getReceived()
public function getReceived(): intWhat the owner receives: the gift, less the fee unless the giver covered it.
Contribution::getCurrency()
public function getCurrency(): stringContribution::getName()
public function getName(): stringContribution::getEmail()
public function getEmail(): ?stringContribution::getMessage()
public function getMessage(): ?stringContribution::setMessage()
public function setMessage(?string $message): selfContribution::getGiverReference()
public function getGiverReference(): ?stringContribution::setGiverReference()
public function setGiverReference(?string $giverReference): selfContribution::getStatus()
public function getStatus(): ContributionStatusContribution::isPaid()
public function isPaid(): boolContribution::getGateway()
public function getGateway(): ?stringContribution::getProviderReference()
public function getProviderReference(): ?stringContribution::setProvider()
public function setProvider(string $gateway, ?string $reference): selfContribution::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableContribution::getPaidAt()
public function getPaidAt(): ?\DateTimeImmutableContribution::markPaid()
public function markPaid(): selfContribution::markCancelled()
public function markCancelled(): selfContribution::markRefunded()
public function markRefunded(): selfContribution::getRedirectUrl()
public function getRedirectUrl(): ?stringContribution::setRedirectUrl()
public function setRedirectUrl(?string $redirectUrl): selfItem 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(): stringItem::getId()
public function getId(): ?intItem::getWishlist()
public function getWishlist(): ?WishlistItem::setWishlist()
public function setWishlist(?Wishlist $wishlist): selfItem::getKind()
public function getKind(): WishlistItemKindItem::setKind()
public function setKind(WishlistItemKind $kind): selfItem::getTitle()
public function getTitle(): stringItem::setTitle()
public function setTitle(string $title): selfItem::getDescription()
public function getDescription(): ?stringItem::setDescription()
public function setDescription(?string $description): selfItem::getImageUrl()
public function getImageUrl(): ?stringItem::setImageUrl()
public function setImageUrl(?string $imageUrl): selfItem::getPrice()
public function getPrice(): ?intItem::setPrice()
public function setPrice(?int $price, ?\DateTimeImmutable $fetchedAt = null): selfItem::getCurrency()
public function getCurrency(): stringItem::setCurrency()
public function setCurrency(string $currency): selfItem::getQuantity()
public function getQuantity(): intItem::setQuantity()
public function setQuantity(int $quantity): selfItem::getProduct()
public function getProduct(): ?ProductItem::setProduct()
public function setProduct(?Product $product): selfItem::getGateway()
public function getGateway(): ?stringItem::getProductReference()
public function getProductReference(): ?stringItem::setSource()
public function setSource(?string $gateway, ?string $productReference): selfItem::getUrl()
public function getUrl(): ?stringItem::setUrl()
public function setUrl(?string $url): selfItem::getAffiliateUrl()
public function getAffiliateUrl(): ?stringItem::setAffiliateUrl()
public function setAffiliateUrl(?string $affiliateUrl): selfItem::getBuyUrl()
public function getBuyUrl(): ?stringWhere a giver is sent to buy it: the affiliate link when there is one.
Item::getMerchant()
public function getMerchant(): ?stringItem::setMerchant()
public function setMerchant(?string $merchant): selfItem::getPriceFetchedAt()
public function getPriceFetchedAt(): ?\DateTimeImmutableItem::getPosition()
public function getPosition(): intItem::setPosition()
public function setPosition(int $position): selfItem::isHidden()
public function isHidden(): boolItem::setHidden()
public function setHidden(bool $hidden): selfItem::getReservations()
public function getReservations(): CollectionItem::getContributions()
public function getContributions(): CollectionItem::getReserved()
public function getReserved(?\DateTimeImmutable $at = null): intHow many are promised or bought.
Item::getAvailable()
public function getAvailable(?\DateTimeImmutable $at = null): intHow many are still to be offered (an object).
Item::getCollected()
public function getCollected(): intMoney given, paid (the givers' gifts, before the platform's fee).
Item::getRemaining()
public function getRemaining(): ?intWhat a SHARE still lacks; null for a pot without ceiling or an object.
Item::isFulfilled()
public function isFulfilled(): boolNothing 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(): stringPayoutAccount::getId()
public function getId(): ?intPayoutAccount::getOwner()
public function getOwner(): ?UserPayoutAccount::getGateway()
public function getGateway(): stringPayoutAccount::getReference()
public function getReference(): stringPayoutAccount::getCountry()
public function getCountry(): stringPayoutAccount::isDetailsSubmitted()
public function isDetailsSubmitted(): boolPayoutAccount::isChargesEnabled()
public function isChargesEnabled(): boolPayoutAccount::isPayoutsEnabled()
public function isPayoutsEnabled(): boolPayoutAccount::getRequirements()
public function getRequirements(): arrayPayoutAccount::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutablePayoutAccount::getCheckedAt()
public function getCheckedAt(): ?\DateTimeImmutablePayoutAccount::isReady()
public function isReady(): boolContributions may be paid to it.
PayoutAccount::update()
public function update(bool $detailsSubmitted, bool $chargesEnabled, bool $payoutsEnabled, array $requirements = []): selfReservation 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(): ?intReservation::getItem()
public function getItem(): ItemReservation::getQuantity()
public function getQuantity(): intReservation::getName()
public function getName(): stringReservation::getEmail()
public function getEmail(): ?stringReservation::getMessage()
public function getMessage(): ?stringReservation::setMessage()
public function setMessage(?string $message): selfReservation::getGiverReference()
public function getGiverReference(): ?stringReservation::setGiverReference()
public function setGiverReference(?string $giverReference): selfReservation::getStatus()
public function getStatus(): ReservationStatusReservation::setStatus()
public function setStatus(ReservationStatus $status): selfReservation::getTokenHash()
public function getTokenHash(): stringReservation::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableReservation::getExpiresAt()
public function getExpiresAt(): \DateTimeImmutableReservation::holds()
public function holds(?\DateTimeImmutable $at = null): boolIt 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(): stringWishlist::getId()
public function getId(): ?intWishlist::getToken()
public function getToken(): stringWishlist::getOwner()
public function getOwner(): ?UserWishlist::getHolderType()
public function getHolderType(): ?stringWishlist::getHolderId()
public function getHolderId(): ?stringWishlist::setHolder()
public function setHolder(?WishlistHolderInterface $holder): selfWishlist::getTitle()
public function getTitle(): stringWishlist::setTitle()
public function setTitle(string $title): selfWishlist::getMessage()
public function getMessage(): ?stringWishlist::setMessage()
public function setMessage(?string $message): selfWishlist::getKind()
public function getKind(): WishlistKindWishlist::setKind()
public function setKind(WishlistKind $kind): selfWishlist::isSurprise()
public function isSurprise(): boolWishlist::setSurprise()
public function setSurprise(bool $surprise): selfWishlist::getCurrency()
public function getCurrency(): stringWishlist::setCurrency()
public function setCurrency(string $currency): selfWishlist::getShippingAddress()
public function getShippingAddress(): ?stringWishlist::setShippingAddress()
public function setShippingAddress(?string $shippingAddress): selfWishlist::getPayoutAccount()
public function getPayoutAccount(): ?PayoutAccountWishlist::setPayoutAccount()
public function setPayoutAccount(?PayoutAccount $payoutAccount): selfWishlist::isGiverMayCoverFees()
public function isGiverMayCoverFees(): boolWishlist::setGiverMayCoverFees()
public function setGiverMayCoverFees(bool $giverMayCoverFees): selfWishlist::isOpen()
public function isOpen(): boolWishlist::setOpen()
public function setOpen(bool $open): selfWishlist::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableWishlist::takesContributions()
public function takesContributions(): boolMoney may be given: open, and a payout account ready to receive it.
Wishlist::getItems()
public function getItems(): CollectionWishlist::addItem()
public function addItem(Item $item): selfWishlist::removeItem()
public function removeItem(Item $item): selfWishlist::getCollected()
public function getCollected(): intEverything 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(): ?arrayBarcode::__iconizeStatic()
public static function __iconizeStatic(): ?arrayContributionStatus 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(): boolWhether 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(): ?arrayOrderState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayOrderState::__colorize()
public function __colorize(): ?arrayOrderState::__colorizeStatic()
public static function __colorizeStatic(): ?arrayPaymentState class
class PaymentState extends EnumType implements IconizeInterface PaymentState.php:11
const AWAITING = 'PAYMENT_AWAITING'const CANCEL = 'PAYMENT_CANCEL'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(): ?arrayPaymentState::__iconizeStatic()
public static function __iconizeStatic(): ?arrayPickupMode 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(): stringPickupMode::needsAddress()
public function needsAddress(): boolWhether 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(): boolPickupStatus::trans()
public function trans(): stringProductAvailability 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(): ?arrayProductAvailability::__iconizeStatic()
public static function __iconizeStatic(): ?arrayProductKind 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(): boolQuoteStatus::isEditable()
public function isEditable(): boolThe 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(): boolIt 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(): ?arrayShippingRate::__iconizeStatic()
public static function __iconizeStatic(): ?arraySubscriptionStatus 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(): boolWhat 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(): boolTradeDirection 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 FUND = 'fund'
WishlistItemKind::takesMoney()
public function takesMoney(): boolWishlistKind 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 $gatewaypublic readonly Notification $notification
CatalogueNotificationEvent::__construct()
public function __construct(public readonly string $gateway, public readonly Notification $notification)CatalogueNotificationEvent::getOutcome()
public function getOutcome(): ?stringCatalogueNotificationEvent::setOutcome()
public function setOutcome(string $outcome): voidContributionPaidEvent 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 $contributionpublic int $feepublic array $metadatapublic ?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 $entitlementpublic 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 $orderpublic readonly Transaction $transaction
PaymentCancelledEvent::__construct()
public function __construct(public readonly Order $order, public readonly Transaction $transaction)PaymentCancelledEvent::getResponse()
public function getResponse(): ?ResponsePaymentCancelledEvent::setResponse()
public function setResponse(?Response $response): voidPaymentNotificationEvent 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 $gatewayThe 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(): ?stringPaymentNotificationEvent::setOutcome()
public function setOutcome(string $outcome): voidPaymentPreparingEvent 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 = nullpublic ?int $applicationFee = nullpublic ?string $interval = nullpublic int $intervalCount = 1public ?string $price = nullpublic ?int $trialDays = nullpublic ?string $customer = nullpublic readonly Order $orderpublic readonly Transaction $transactionpublic readonly PaymentMethod $methodpublic readonly string $gatewayThe omnitrade gateway's name.
public array $metadatapublic ?string $descriptionpublic ?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(): boolPickupChangedEvent 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 $pickuppublic 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(): ?ResponseQuickOrderDoneEvent::setResponse()
public function setResponse(?Response $response): voidReferralQualifyingEvent 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 = nullpublic readonly Referral $referralpublic readonly Order $orderpublic ?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 $subscriptionpublic 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 $jobpublic 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): voidPickupPaidListener 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): voidPlanPurchaseListener 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): voidPlanPurchaseListener::code()
public static function code(\Base\Marketplace\Entity\Product $product): stringA 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): voidQuotePaidListener 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): voidReferralListener 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): voidSubscriptionNotificationListener 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): voidSupplyListener 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): voidWishlistNotificationListener 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): voidBase\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): voidAssociationType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidAttributeSetFieldType 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): voidAttributeSetFieldType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidProductOptionType 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): voidProductOptionType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidQuickOrderType 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): voidQuickOrderType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidQuickOrderType::getBlockPrefix()
public function getBlockPrefix(): stringQuoteLineType 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): voidQuoteLineType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidQuoteRequestType 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): voidThe 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): voidBase\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(): boolFacturX::xml()
public function xml(Invoice $invoice): stringFacturX::attach()
public function attach(Invoice $invoice, string $pdf): stringThe 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): ?stringThe 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 = [])$sellermarketplace.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): arrayThe 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): arrayThe 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): ?arrayThe 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): stringInvoiceNumbering::issue()
public function issue(string $series, \DateTimeImmutable $issuedAt, callable $make): InvoiceThe 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): StatusStoreInterfaceInvoiceTransmission 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(): boolWhether invoices go through a gateway: one is named, and it can be built.
InvoiceTransmission::name()
public function name(): ?stringInvoiceTransmission::flowOf()
public function flowOf(Invoice $invoice): ?InvoiceFlowWhere the invoice stands on the gateway, if it went through one.
InvoiceTransmission::describe()
public function describe(Invoice $invoice): ?stringIts 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): InvoiceFlowThe 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.
$pdfthe invoice's PDF: Service\Invoices::pdf()
$linkthe invoice's signed address, for the e-mail's text
InvoiceTransmission::refresh()
public function refresh(Invoice $invoice): ?InvoiceFlowAsks 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): voidDeclares 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): boolInvoiceTransmission::notify()
public function notify(string $gateway, string $body, array $headers): Invoice|false|nullA 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): arrayTransmissionException 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(): ?intInvoiceFlow::getInvoice()
public function getInvoice(): InvoiceInvoiceFlow::getGateway()
public function getGateway(): stringInvoiceFlow::getReference()
public function getReference(): stringInvoiceFlow::restart()
public function restart(string $gateway, string $reference): staticSent again, through a gateway: a new transmission, its history afresh.
InvoiceFlow::getStatus()
public function getStatus(): ?stringInvoiceFlow::getHistory()
public function getHistory(): arrayInvoiceFlow::setHistory()
public function setHistory(array $history): staticInvoiceFlow::getUpdatedAt()
public function getUpdatedAt(): \DateTimeImmutableBase\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 $sirenpublic readonly ?string $siretpublic readonly string $namepublic readonly ?string $addresspublic readonly ?string $activitypublic readonly ?string $legalFormpublic readonly bool $activeStill trading: false when the company, or that establishment, is closed.
public readonly ?string $createdOnpublic 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(): arrayCompanyRecord::fromArray()
public static function fromArray(array $data): selfMerchantInterface 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(): ?stringOptionSelection 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 $optionsin the order of their groups
OptionSelection::__construct()
public function __construct(public readonly array $options = [])$optionsin the order of their groups
OptionSelection::isEmpty()
public function isEmpty(): boolOptionSelection::surcharge()
public function surcharge(): intWhat 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(): stringTwo lines of the same product are one line when their options are the same.
OptionSelection::toArray()
public function toArray(?string $locale = null): arrayWhat 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 $billingpublic ?string $intervalpublic ?int $monthspublic array $grantspublic array $creditspublic 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): selfPlanTerms::toArray()
public function toArray(): arrayPlanTerms::isRecurring()
public function isRecurring(): boolPlanTerms::expiry()
public function expiry(\DateTimeImmutable $from): ?\DateTimeImmutableWhen 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): mixedQuickPayment class
final class QuickPayment QuickPayment.php:9
What QuickOrder::buy() hands back: the order made, and where its payment stands.
public readonly Order $orderpublic 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 = nullA number to be called back on.
public ?string $companyName = nullpublic ?string $siret = nullA French company's SIREN or SIRET - checked against the State's register.
public ?string $vatNumber = nullAn EU company's VAT number - checked against VIES.
public string $title = ''public ?TradeDirection $direction = nullpublic ?Incoterm $incoterm = nullpublic ?string $country = nullpublic ?string $place = nullpublic ?string $volume = nullpublic ?\DateTimeImmutable $targetDate = nullpublic ?string $deliveryAddress = nullpublic 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(): floatVatCustomerInterface 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(): ?stringCountry prefix included, as VIES writes it: "DE123456789", "EL...".
VatCustomerInterface::setVatNumber()
public function setVatNumber(?string $vatNumber): staticA number set is not confirmed yet: markVatNumberChecked() says it is.
VatCustomerInterface::getVatNumberCheckedAt()
public function getVatNumberCheckedAt(): ?\DateTimeImmutableVatCustomerInterface::getVatConsultationNumber()
public function getVatConsultationNumber(): ?stringVIES'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): staticVatCustomerInterface::getVatCountry()
public function getVatCountry(): ?stringThe two letters of its country, as VIES writes them ("EL" for Greece).
VatCustomerInterface::hasConfirmedVatNumber()
public function hasConfirmedVatNumber(): boolVatCustomerTrait 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(): ?stringVatCustomerTrait::setVatNumber()
public function setVatNumber(?string $vatNumber): staticVatCustomerTrait::getVatNumberCheckedAt()
public function getVatNumberCheckedAt(): ?\DateTimeImmutableVatCustomerTrait::getVatConsultationNumber()
public function getVatConsultationNumber(): ?stringVatCustomerTrait::markVatNumberChecked()
public function markVatNumberChecked(?\DateTimeImmutable $at = null, ?string $consultationNumber = null): staticVatCustomerTrait::getVatCountry()
public function getVatCountry(): ?stringVatCustomerTrait::hasConfirmedVatNumber()
public function hasConfirmedVatNumber(): boolWishlistHolderInterface 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(): stringA name of the application's for this kind of holder: "occasion".
WishlistHolderInterface::getWishlistHolderId()
public function getWishlistHolderId(): int|string|nullBase\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(): stringDevGateway::supports()
public function supports(Order $order, PaymentMethod $method): boolDevGateway::pay()
public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResultManualGateway 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(): stringManualGateway::supports()
public function supports(Order $order, PaymentMethod $method): boolManualGateway::pay()
public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResultPaymentGatewayInterface 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(): stringThe value a PaymentMethod's gatewayFactory holds to use this gateway.
PaymentGatewayInterface::supports()
public function supports(Order $order, PaymentMethod $method): boolWhether 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): PaymentResultPaymentGatewayRegistry 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): ?PaymentGatewayInterfacePaymentGatewayRegistry::for()
public function for(PaymentMethod $method): ?PaymentGatewayInterfacePaymentGatewayRegistry::names()
public function names(): arrayPaymentGatewayRegistry::usableFor()
public function usableFor(Order $order, iterable $methods): arrayThe 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(): selfPaymentResult::pending()
public static function pending(): selfPaymentResult::redirect()
public static function redirect(string $url): selfPaymentResult::refused()
public static function refused(string $reason, array $parameters = []): selfPaymentResult::isPaid()
public function isPaid(): boolPaymentResult::isPending()
public function isPending(): boolPaymentResult::isRedirect()
public function isRedirect(): boolPaymentResult::isRefused()
public function isRefused(): boolBase\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: cardOne 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)$optionsthe gateway's options as it runs on: configured, and typed in the back office over them
OmnitradeGateway::option()
public function option(string $name): ?stringOne of the options the gateway runs on (api_key, webhook_secret...), null when unset or empty.
OmnitradeGateway::name()
public static function name(): stringEvery bridge answers to this; the registry keys them by their omnitrade gateway's name (getName()).
OmnitradeGateway::getName()
public function getName(): stringThe omnitrade gateway's name: what a PaymentMethod's gatewayFactory holds.
OmnitradeGateway::provider()
public function provider(): stringThe provider behind it: stripe, paypal, shopify, woocommerce.
OmnitradeGateway::gateway()
public function gateway(): GatewayInterfaceOmnitradeGateway::supports()
public function supports(Order $order, PaymentMethod $method): boolOmnitradeGateway::pay()
public function pay(Order $order, Transaction $transaction, PaymentMethod $method): PaymentResultOmnitradeGateway::fetch()
public function fetch(Transaction $transaction): OmnitradeTransactionWhere the provider's payment stands now.
OmnitradeGateway::notify()
public function notify(string $body, array $headers): NotificationA 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): stringPays $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): stringThe 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): PaymentPreparingEventHow 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): PaymentWhat 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(): boolWhether this is a demonstration: only the application's trial gateways answer.
OmnitradeGateways::get()
public function get(string $name): ?OmnitradeGatewayThe 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(): arrayOmnitradeGateways::typed()
public function typed(string $name): arrayThe 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): ?stringExportExemption::inEu()
public static function inEu(string $country): boolWhether 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): ?stringStoreVatRegime 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): ?stringVatExemptionInterface 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): ?stringBase\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): voidNumbers 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 idThis 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 = [])$sellermarketplace.invoice.seller: who the quote is from
QuoteSignatures::isEnabled()
public function isEnabled(): boolWhether accepting a quote asks for a signature: a gateway named, and configured.
QuoteSignatures::latest()
public function latest(Quote $quote): ?EnvelopeThe quote's latest envelope, if it was sent to be signed.
QuoteSignatures::pdf()
public function pdf(Quote $quote): stringThe quote as a PDF: what is signed.
QuoteSignatures::start()
public function start(Quote $quote, string $returnUrl): stringWhere 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): arrayBack 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): voidCompleted, 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'): ?stringThe 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): ?BrandThe 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): intThe last number taken in a series and a year: 0 before the first.
InvoiceRepository::standingFor()
public function standingFor(Order $order): ?InvoiceThe 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): ?PlatformLinkPlatformLinkRepository::findProduct()
public function findProduct(string $gateway, string $remoteProduct): arrayPlatformLinkRepository::findItem()
public function findItem(string $gateway, string $remoteItem): ?PlatformLinkPlatformLinkRepository::lastRemoteUpdate()
public function lastRemoteUpdate(string $gateway): ?\DateTimeImmutableThe 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): ?PickupPickupRepository::byToken()
public function byToken(string $token): array- Returns
the orders made together, oldest first
PickupRepository::onDay()
public function onDay(\DateTimeImmutable $day): arrayWhat 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): ?AttributeSetThe 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): ?AttributeSetThe 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): ?WishlistBase\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(): voidBetween 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)$agesby language ("ja") or country ("JP")
AgeGate::isEnabled()
public function isEnabled(): boolAgeGate::minimumAge()
public function minimumAge(?string $locale = null, ?string $country = null): intThe 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): boolWhether 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): boolWhether 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): boolWhether to show the gate now.
AgeGate::confirmation()
public function confirmation(?int $age = null): CookieThe cookie keeping the visitor's yes: the age they confirmed, for a year.
AgeGate::notice()
public function notice(): ?stringThe 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(): intAttachments::maxSize()
public function maxSize(): intAttachments::extensions()
public function extensions(): arrayAttachments::refusal()
public function refusal(iterable $files, int $already = 0): ?arrayWhy 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): arrayKeeps the files of a quote request.
- Throws
CartException attachment.error.*
Attachments::attachToItem()
public function attachToItem(OrderItem $item, iterable $files): arrayKeeps the files of an order line: the buyer's artwork.
- Throws
CartException attachment.error.*
Attachments::file()
public function file(Attachment $attachment): ?stringThe file on disk; null when it is gone.
Attachments::download()
public function download(Attachment $attachment): BinaryFileResponseA 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): stringA link good for $ttl seconds, for somebody without an account: a supplier fetching an artwork.
Attachments::remove()
public function remove(Attachment $attachment): voidAttributeFilters 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): arrayAttributeFilters::apply()
public function apply(iterable $products, array $selection, ?string $locale = null): arrayThe products every chosen filter holds.
AttributeFilters::valuesOf()
public function valuesOf(Product $product, string $code, ?string $locale = null): arrayA 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(): ?UserCart::of()
public function of(Store $store, bool $create = false): ?OrderThe 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(): intHow many items the member's carts hold, for a badge.
Cart::add()
public function add(Product $product, int $quantity = 1, iterable $options = []): Order$optionsthe 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): voidSet 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(): arrayCheckout 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): PaymentResultpay() 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): voidThe 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): PaymentCancelledEventThe 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'
CompanyRegistry::__construct()
public function __construct(readonly Omnistate $omnistate, readonly ?LoggerInterface $logger = null)CompanyRegistry::normalize()
public static function normalize(?string $number): stringThe digits of a SIREN or SIRET as typed ("552 100 554 00054").
CompanyRegistry::isWellFormed()
public static function isWellFormed(?string $number): boolA 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): ?stringOne 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 $kindpublic readonly int $askedpublic 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): CreditCredits::balance()
public function balance(User $holder, string $kind, ?\DateTimeImmutable $at = null): intCredits::spend()
public function spend(User $holder, string $kind, int $quantity = 1, ?string $reason = null, ?string $resourceType = null, int|string|null $resourceId = null): CreditSpends $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): boolCredits::refund()
public function refund(Credit $spent, ?string $reason = null): ?CreditGives 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 = []): EntitlementEntitlements::active()
public function active(User $holder, ?string $resourceType = null, int|string|null $resourceId = null, ?\DateTimeImmutable $at = null): arrayThe rights held now, the highest level first.
Entitlements::holds()
public function holds(User $holder, string $code, ?string $resourceType = null, int|string|null $resourceId = null): boolWhether 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): boolA 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): mixedThe 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): ?intA 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): intA 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): UsageTakes $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): intGives 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): ?EntitlementThe 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): intWhat 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 = 100const 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(): voidThe table, as Trading's rates: once per request or command.
ExchangeRates::reset()
public function reset(): voidA 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): ?floatThe rate from the store's currency to $target, from the table; null when there is none.
ExchangeRates::refresh()
public function refresh(array $targets = []): arrayAsks 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(): ?\DateTimeImmutableWhen the rates were last asked for (Fixer or the ECB); null before the first time.
ExchangeRates::requestsThisMonth()
public function requestsThisMonth(): intFixer's calls this calendar month, as counted here.
ExchangeRates::usesFixer()
public function usesFixer(): boolWhether 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(): InvoiceRepositoryInvoices::of()
public function of(Order $order): ?InvoiceThe order's invoice that stands, if it has one.
Invoices::issue()
public function issue(Order $order, ?\DateTimeImmutable $at = null): InvoiceThe 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): InvoiceThe 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): voidInvoices::gateway()
public function gateway(): ?stringThe gateway invoices go through (glitchr/omnibill), null when they are mailed by this bundle.
Invoices::lifecycle()
public function lifecycle(Invoice $invoice): ?stringWhere the invoice stands on that gateway, in words ("Encaissée (email)"); null when it went through none.
Invoices::refresh()
public function refresh(Invoice $invoice): boolAsks the gateway where the invoice stands; false when it went through none.
Invoices::html()
public function html(Invoice $invoice): stringThe invoice's page as the PDF prints it (HTML).
Invoices::pdf()
public function pdf(Invoice $invoice): stringThe invoice as a PDF, its Factur-X XML attached when horstoeko/zugferd is installed.
Invoices::xml()
public function xml(Invoice $invoice): stringInvoices::filename()
public function filename(Invoice $invoice): stringInvoices::signedUrl()
public function signedUrl(Invoice $invoice, int $ttl = 2592000): stringThe 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): voidSent 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): boolPickups::deliversTo()
public function deliversTo(?string $postcode, ?array $zipCodes = null): boolWhether the shop brings orders to this postcode itself. No list: nowhere.
Pickups::now()
public function now(): \DateTimeImmutableThe present, on the shop's clock (marketplace.pickup.timezone; PHP's zone without one).
Pickups::slots()
public function slots(\DateTimeImmutable $day, ?\DateTimeImmutable $now = null): arrayThe 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): ?PickupPickups::open()
public function open(Order $order, PickupMode $mode, \DateTimeImmutable $day, array $details = [], bool $check = true): PickupThe 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): PickupMoves 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): stringThe 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(): voidPricing::reprice()
public function reprice(Order $order): voidPricing::vatRateFor()
public function vatRateFor(Product $product, ?Region $region = null, ?Order $order = null): floatThe 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): arrayThe 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): intA 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): CouponAdd a coupon to a cart.
- Throws
CartException coupon.error.*
Pricing::removeCoupon()
public function removeCoupon(Order $order, Coupon $coupon): voidProductOptions 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$chosenoption 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(): boolQuickOrder::buy()
public function buy(array|Product $lines, string $email, ?User $signedIn = null): QuickPaymentOne 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): stringThe 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): boolAccepted, 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): StoreThe store the order is made in: the quote's, its first product's, else marketplace.quotes.store.
QuoteToOrder::itemsOf()
public function itemsOf(Quote $quote): arrayThe 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(): boolReferrals::codeFor()
public function codeFor(User $member): ReferralCodeA member's code, made the first time it is asked.
Referrals::find()
public function find(string $code): ?ReferralCodeReferrals::referralOf()
public function referralOf(User $referee): ?ReferralReferrals::attribute()
public function attribute(string $code, User $referee): ReferralA 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): ?ReferralAn 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): arrayThe 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'): voidIn review, before its reward leaves.
Referrals::rewardsOf()
public function rewardsOf(User $beneficiary): arrayReferrals::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): RegionShipping 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): boolWhether 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): boolShipping::optionsFor()
public function optionsFor(Order $order): arrayShipping::chargeFor()
public function chargeFor(ShippingMethod $method, Order $order): intShipping::addressOf()
public function addressOf(Order $order): arrayThe 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): ?stringPut 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): ShipmentStaff 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): ?stringShipping::carrierFor()
public function carrierFor(?ShippingMethod $method): ?CarrierThe 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): ConsignmentThe 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): arrayWhat the carrier's own tariff says for the order, for information: the buyer pays chargeFor().
Shipping::book()
public function book(Shipment $shipment): LabelThe shipment booked with its carrier: the label, the tracking number on the shipment.
Shipping::track()
public function track(Shipment $shipment, string $locale = 'fr'): ?TrackingWhere the carrier says the shipment is; null when it names no carrier.
Shipping::parcelFor()
public function parcelFor(Order $order): ParcelThe parcel: the shippable items' weights (grams) and the order's value.
Shipping::sender()
public function sender(): AddressThe 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): ?SubscriptionSubscriptions::apply()
public function apply(string $gateway, ProviderSubscription $remote): ?SubscriptionThe provider's subscription as it stands, applied to ours; null when we do not know it.
Subscriptions::refresh()
public function refresh(Subscription $subscription): SubscriptionAsks the provider where it stands and applies it.
Subscriptions::cancel()
public function cancel(Subscription $subscription, bool $atPeriodEnd = true): SubscriptionStops 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): stringThe provider's page where the subscriber changes their card, reads their invoices, stops.
Subscriptions::sweep()
public function sweep(?\DateTimeImmutable $now = null): arrayThe 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): arrayThe 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): SupplyJobA job that failed, sent again.
Supply::confirm()
public function confirm(SupplyJob $job): SupplyJobA draft launched.
Supply::sync()
public function sync(SupplyJob $job): SupplyJobAsks its supplier where it stands.
Supply::cancel()
public function cancel(SupplyJob $job): SupplyJobSupply::apply()
public function apply(SupplyResult $result): ?SupplyJobA 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): arraySupply::find()
public function find(string $reference): ?SupplyJobVatNumbers 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'
VatNumbers::__construct()
public function __construct(readonly Omnistate $omnistate)VatNumbers::check()
public function check(string $typed): arrayWhat 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): arrayA 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(): stringPaymentKeysSection::getFields()
public function getFields(): arrayBase\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(): stringGelatoSupplier::isConfigured()
public function isConfigured(): boolGelatoSupplier::products()
public function products(?string $query = null): arrayGelatoSupplier::quote()
public function quote(SupplyOrder $order): SupplyQuoteGelatoSupplier::submit()
public function submit(SupplyOrder $order, bool $draft = false): SupplyResultGelatoSupplier::confirm()
public function confirm(string $reference): SupplyResultGelatoSupplier::fetch()
public function fetch(string $reference): SupplyResultGelatoSupplier::cancel()
public function cancel(string $reference): SupplyResultGelatoSupplier::notify()
public function notify(string $body, array $headers = []): ?SupplyResultGelatoSupplier::result()
public function result(array $order): SupplyResultGelato's order (or its status event) as a SupplyResult.
GelatoSupplier::status()
public static function status(string $fulfillment, string $orderType = 'order'): SupplyStatusOfflineSupplier 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(): stringOfflineSupplier::isConfigured()
public function isConfigured(): boolOfflineSupplier::products()
public function products(?string $query = null): arrayOfflineSupplier::quote()
public function quote(SupplyOrder $order): SupplyQuoteOfflineSupplier::submit()
public function submit(SupplyOrder $order, bool $draft = false): SupplyResultOfflineSupplier::confirm()
public function confirm(string $reference): SupplyResultOfflineSupplier::fetch()
public function fetch(string $reference): SupplyResultWhat the workshop last said on its page: kept on the job.
OfflineSupplier::cancel()
public function cancel(string $reference): SupplyResultOfflineSupplier::notify()
public function notify(string $body, array $headers = []): ?SupplyResultOfflineSupplier::link()
public function link(string $reference): stringThe 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(): stringWhat a Product's supplier holds: "gelato", "offline".
SupplierInterface::isConfigured()
public function isConfigured(): boolWhether 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): SupplyQuoteWhat the order would cost the shop.
SupplierInterface::submit()
public function submit(SupplyOrder $order, bool $draft = false): SupplyResultSends the order: launched, or as a draft the supplier keeps until confirmed.
SupplierInterface::confirm()
public function confirm(string $reference): SupplyResultLaunches a draft.
SupplierInterface::fetch()
public function fetch(string $reference): SupplyResultSupplierInterface::cancel()
public function cancel(string $reference): SupplyResultSupplierInterface::notify()
public function notify(string $body, array $headers = []): ?SupplyResultA 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): ?SupplierInterfaceSupplierRegistry::names()
public function names(): arraySupplierRegistry::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 $referenceOurs: the order item's id.
public string $productReferencepublic int $quantitypublic array $filesaddresses of the print files (PDF, PNG)
public ?string $titlepublic array $optionsthe 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 = [])$filesaddresses of the print files (PDF, PNG)
$optionsthe 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 $referenceOurs, unique: the supplier keeps it and gives it back ("CMD-1042-1").
public array $linespublic SupplyRecipient $recipientpublic string $currencypublic ?string $shippingMethodThe supplier's shipping method, when one is insisted on; else its cheapest.
public ?string $customerReferenceWho 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 $referencepublic string $titlepublic 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 $productspublic int $shippingpublic string $currencypublic ?int $minDaysDays until it is delivered, when the supplier says.
public ?int $maxDayspublic ?string $shippingMethodpublic 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(): intSupplyRecipient 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 $namepublic array $streetpublic string $postcodepublic string $citypublic string $countrypublic ?string $emailpublic ?string $phonepublic ?string $companypublic ?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): selfSupplyRecipient::toArray()
public function toArray(): arraySupplyRecipient::firstName()
public function firstName(): string"Marie" of "Marie Dupont de la Tour".
SupplyRecipient::lastName()
public function lastName(): stringSupplyRecipient::isComplete()
public function isComplete(): boolSupplyRecipient::key()
public function key(): stringWhat 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 $supplierpublic string $referenceThe supplier's id for it.
public SupplyStatus $statuspublic ?string $trackingNumberpublic ?string $trackingUrlpublic ?string $carrierpublic ?string $messagepublic ?string $orderReferenceOurs, 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(): arrayCatalogueTwigExtension::attributes()
public function attributes(Product $product, ?string $locale = null): arrayA 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): arrayThe 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(): arrayInvoiceTwigExtension::ofOrder()
public function ofOrder(Order $order): arrayInvoiceTwigExtension::getFilters()
public function getFilters(): arrayInvoiceTwigExtension::money()
public function money(int|float|null $amount, string $currency, string $locale = 'fr_FR'): stringInvoiceTwigExtension::rate()
public function rate(int|float|null $rate, string $locale = 'fr_FR'): stringMarketplaceTwigExtension 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(): ?stringMarketplaceTwigExtension::getFunctions()
public function getFunctions(): arrayQuickOrderTwigExtension 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(): arrayQuickOrderTwigExtension::view()
public function view(Product $product, ?string $back = null): FormViewQuickOrderTwigExtension::form()
public function form(Product $product, ?string $back = null): FormInterfaceThe 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(): arrayBase\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): voidVatNumber 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): voidBase\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): intThe 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): ?ContributionContributions::findByProviderReference()
public function findByProviderReference(string $gateway, string $providerReference): ?ContributionContributions::confirm()
public function confirm(Contribution $contribution): ContributionWhere it stands at the provider, applied: paid, cancelled, or still pending.
Contributions::apply()
public function apply(Contribution $contribution, ?Status $status): ContributionA 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(): boolWhether the provider is configured and opens accounts at all.
PayoutAccounts::for()
public function for(User $owner): ?PayoutAccountPayoutAccounts::open()
public function open(User $owner, string $country = 'FR'): PayoutAccountThe owner's account, opened at the provider when they have none yet.
PayoutAccounts::onboardingUrl()
public function onboardingUrl(PayoutAccount $account, string $returnUrl, string $refreshUrl): stringThe 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): PayoutAccountAsks the provider where it stands (on the holder's return).
PayoutAccounts::applyRemote()
public function applyRemote(string $gateway, Account $remote): ?PayoutAccountThe 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): ?arrayProductLookup::affiliateLink()
public function affiliateLink(string $url): ?stringThe 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): ?ReservationReservations::cancel()
public function cancel(string $token): ?ReservationBy its author: the object goes back on the list.
Reservations::confirm()
public function confirm(Reservation $reservation): ReservationBought: it no longer lapses.
Reservations::expire()
public function expire(?\DateTimeImmutable $now = null): intThe 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): WishlistWishlists::addFromUrl()
public function addFromUrl(Wishlist $wishlist, string $url, WishlistItemKind $kind = WishlistItemKind::OBJECT): ItemA 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): ItemA 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): ItemA 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): intThe 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): boolFills a wish from its page; on a refresh only its price, availability's date and link move.