PX Shop Core self-updates
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/pixeler-sk/px-shop-core/archive/refs/heads/main.zipShips its own WordPress updater (built-in updater), so new versions show up under Dashboard → Updates.
Zdieľané WooCommerce funkcie pre Pixeler eshopy. Prezentácia žije v téme —
tento plugin dodáva len funkcionalitu (neutrálny px-* markup, dáta, REST).
Každá funkcia je samostatný modul, dá sa vypnúť a téma sa jej pýta cez
class_exists().
- Vyžaduje WooCommerce (okrem modulov
contentaconsent_mode); WordPress ≥ 6.0, PHP ≥ 7.4. - Inštalácia a aktualizácie: RELEASING.md — releases cez tagy, weby sa aktualizujú cez Plugin Update Checker.
- Changelog po verziách: readme.txt.
- Licencia: GPL v2 or later.
Obsah
- Moduly a nastavenia
- Prehľad modulov
- Omnibus · Platnosť akcie · Jednotková cena · GPSR · Firemné údaje · Live search · Brand tab · Wishlist · Compare · Waitlist · Veľkostné tabuľky · Súvisiace kategórie · Shipping bar · Katalógový režim · Obrázky atribútov · Content bloky · Súhlas s cookies · Google Consent Mode v2 · Staré slugy termov
- Prístupnosť (WCAG)
- WP-CLI
- Page cache
- Konvencie pre tému
Moduly a nastavenia
Každý modul sa dá vypnúť vo WooCommerce → Nastavenia → PX Shop. Vypnutý
modul sa vôbec nenačíta — neregistruje hooky, REST routy, admin obrazovky ani
WP-CLI príkazy, takže class_exists( 'PX_Wishlist' ) ostáva pre tému
spoľahlivým testom dostupnosti. Uložené dáta zostávajú aj po vypnutí
(obľúbené, prihlásenia na naskladnenie, GPSR polia) a po zapnutí sa vrátia.
Stav modulov je jedna option px_shop_core_modules; kým ju nikto neuloží,
platia predvolené hodnoty z registra. Register je
v includes/modules.php:
| Filter | Na čo |
|---|---|
px_shop_core_modules |
pridá vlastný modul site pluginu — dostane prepínač, sekciu nastavení a načítanie zadarmo; bez názvu a popisu, tie idú do filtra nižšie |
px_shop_core_module_labels |
názov a popis modulu pre obrazovku nastavení (__() až tu — register sa číta na plugins_loaded, kde je preklad predčasný) |
px_shop_core_module_off_reason |
vlastné vysvetlenie pri module, ktorého prepínač nemá účinok (namiesto „nastavené v kóde") |
px_shop_core_module_on |
pripne stav modulu v kóde (weby vedené cez git); nastavenia to napíšu ako „nastavené v kóde" |
Moduly s vlastnou sekciou nastavení majú v PX Shop vlastnú záložku.
Prehľad modulov
| Modul | Kľúč | Predvolene | Čo robí |
|---|---|---|---|
| Omnibus | omnibus |
zap. | história cien, najnižšia cena za 30 dní pri zľave |
| Platnosť akcie | sale_dates |
zap. | dokedy platí zľavnená cena — dátum alebo odpočet |
| Jednotková cena | unit_price |
zap. | cena za 1 kg / 1 l / 1 m / 1 ks vedľa predajnej ceny (zákon 108/2024 § 6) |
| GPSR | gpsr |
zap. | bezpečnosť výrobku: výrobca, zodpovedná osoba v EÚ, pôvod, upozornenia, dokumentácia |
| Firemné údaje | company_fields |
vyp. | IČO/DIČ/IČ DPH v pokladni, RPO/ARES, VIES, reverse charge, vývoz mimo EÚ |
| Live search | search |
zap. | REST pixeler/v1/search pre šepkávač v hlavičke |
| Brand tab | brand_tab |
zap. | tab „O značke" z popisu termu product_brand |
| Wishlist | wishlist |
zap. | obľúbené (user meta / cookie), REST, shortcode |
| Compare | compare |
zap. | porovnanie až 4 produktov (cookie), REST, shortcode |
| Waitlist | waitlist |
zap. | stráženie dostupnosti s double opt-in a 4 e-mailmi |
| Veľkostné tabuľky | size_guide |
zap. | tabuľky veľkostí na produkte alebo zdedené z kategórie |
| Súvisiace kategórie | related_cats |
zap. | doplnky nastavené raz na kategórii, dedia sa po strome |
| Shipping bar | shipping_bar |
zap. | dáta pre lištu „do dopravy zadarmo chýba…" |
| Katalógový režim | catalog |
zap. (režim sám vyp.) | výklad bez cien a košíka |
| Obrázky atribútov | attribute_image |
zap. | obrázok na terme atribútu pa_* pre swatche a filtre |
| Content bloky | content |
zap. | skrytý CPT pre bannery, USP pásy a iné bloky kreslené témou |
| Súhlas s cookies | consent |
vyp. | vlastná CMP: lišta, blokovanie, stránka zásad, Consent Mode v2 |
| Google Consent Mode v2 | consent_mode |
vyp. | signály pre Google popri free Complianze |
| Staré slugy termov | old_term_slugs |
zap. | 301 zo starej URL kategórie/značky/štítku po zmene slugu (aj slugu rodiča) |
| Médiá produktov pre MCP | media_abilities |
vyp. | Abilities API pre MCP konektor: obrázky a galéria produktu, alt text |
Omnibus (omnibus)
Smernica Omnibus: pri zľavnenom produkte sa ukazuje najnižšia cena za posledných 30 dní. Plugin si históriu cien zapisuje sám pri uložení produktu, takže web, ktorý zapne modul dnes, má o mesiac úplné dáta.
Zápis „pri zobrazení detailu" pod page cache takmer nebeží — PHP sa spustí len
pri cache miss. Preto je mechanizmom denný cron px_omnibus_scan (03:20
miestneho času), ktorý prejde všetko v zľave a dopíše, čo chýba. Zobrazenie
ostáva ako záchrana.
Cenová báza
História sa zapisuje z get_price( 'edit' ) — z ceny uloženej na produkte, bez
filtrov na woocommerce_product_get_price. Je to jediná povolená báza, vo
všetkých zapisovateľoch naraz.
Plugin plošných zliav (Global Shop Discount a spol.) sa na ten filter vešia
s prioritou PHP_INT_MAX vždy, keď platí ! is_admin() || DOING_AJAX. Uloženie
v administrácii teda zľavnené nie je, ale zobrazenie na fronte aj request
WP-Cronu áno — wp-cron.php nie je admin. Miešanie dvoch báz v jednej histórii
robí z výpočtu streaku v get_lowest_price() nezmysel.
Rovnakú bázu číta aj get_lowest_price() (get_price( 'edit' ),
get_regular_price( 'edit' )) — inak by sa história na fronte nezhodovala so
žiadnym záznamom a výpočet „odkedy platí súčasná cena" by spadol na „od teraz"
pri každom produkte.
'edit' je navyše správny predmet tvrdenia: 30-dňové minimum hovorí o cene
produktu, nie o ohlásenej plošnej kampani, ktorá je samostatný konštrukt s
vlastným ohlásením. Web, ktorý to vidí inak, mení to, čo sa zobrazuje
(px_omnibus_lowest_price), nie to, čo sa zapisuje.
Sken
| Čo | Ako |
|---|---|
| Najnižšia cena | PX_Omnibus::get_lowest_price( $product ) (float), ::get_html( $product ) |
| História | PX_Omnibus::get_history( $product_id ) |
| Ručný beh | PX_Omnibus::scan() — vráti počet produktov s novým záznamom |
| Čo berie | onsale = 1 z wc_product_meta_lookup; ID, ktoré od minulého behu zo zľavy vypadli (px_omnibus_scan_seen); produkty s _sale_price_dates_* v okne ±3 dni |
| Čo neberie | variabilných a zoskupených rodičov (nemajú vlastnú cenu a WooCommerce im ukladá viac riadkov _price naraz), koncepty a kôš vrátane variácií po rodičovi v koši |
| Prevádzka | dávky po 200, jeden dotaz na dávku, bez načítania produktových objektov; zapisuje len tam, kde sa cena pohla. Na libike ~4 300 produktov za desatiny sekundy |
| Koniec akcie bez dátumov | obchod, kde zľavy robí import, _sale_price_dates_* nemá — sken si preto pamätá zoznam ID z posledného behu a ďalší beh prejde aj to, čo z onsale vypadlo |
| Presné ID zvonka | wc_after_products_starting_sales / wc_after_products_ending_sales, wc_product_start/end_scheduled_sale → PX_Omnibus::record_ids(). Bonus, nie mechanizmus — obchod bez dátumov akcie ich nevystrelí |
Prečo nie woocommerce_scheduled_sales |
je to akcia Action Schedulera; plný prechod katalógu v cudzej fronte by po action_scheduler_failure_period (300 s) označil hostiteľskú akciu za zlyhanú |
| Variácie | v dátach variácie cestuje px_omnibus_html; do price_html sa pripája len ak nie je prázdny |
| Filtre | px_omnibus_display (vypne výpis, história vzniká ďalej — web, ktorý cenu ukazuje iným pluginom, neskôr prejde bez diery v dátach), px_omnibus_lowest_price, px_omnibus_variation_price_html, px_omnibus_scan_limit (0 = bez stropu, aplikuje sa na hotový zlúčený zoznam), px_omnibus_scan_ids (druhý parameter = podmnožina práve v zľave) |
Platnosť akcie (sale_dates)
WooCommerce koniec akcie pozná (_sale_price_dates_to), ale nikde ho neukáže.
Modul dátum vyhľadá (pri variabilnom produkte podľa poslednej zľavnenej
variácie) a podá téme ako timestamp.
- Nastavenia: zobrazenie na kartách a na detaile zvlášť, prah pre živý odpočet v hodinách (0 = len dátum), „skryť, ak je koniec ďalej než N dní", koniec kampane pre celý obchod (pre zľavy robené cenovými filtrami bez dátumu).
PX_Sale_Dates::get_end( $product )/px_sale_end()— timestamp alebo 0;::get_html()záložné vykreslenie;::show( 'single'|'loop' ).- Vo
woocommerce_available_variationcestujepx_sale_end. - Filter
px_sale_end_datemá posledné slovo (dátum dodá aj potlačí návratom 0).
Jednotková cena (unit_price)
Označovanie cenami (smernica 98/6/ES; zákon 108/2024 § 2 písm. h) a § 6) vyžaduje pri tovare predbalenom podľa množstva okrem predajnej ceny aj jednotkovú cenu za kilogram, liter, meter, m², m³ alebo inú jednotku množstva (kus pri tovare predávanom podľa počtu). Modul robí presne toto a nič navyše — žiadne „za 100 ml", žiadne marketingové „za praciu dávku".
- Dáta: na produkte alebo variácii pod cenou pole Obsah balenia
(množstvo) a Jednotka (
ml,l,g,kg,m,m2,m3,pc), meta_px_unit_qty/_px_unit. Variácia bez údaja dedí rodiča. Hromadne: WooCommerce CSV import (stĺpceMeta: _px_unit_qty,Meta: _px_unit),PX_Unit_Price::set( $product, $qty, $unit )alebo WP-CLI. - Výpočet:
wc_get_price_to_display()÷ množstvo prepočítané na základ (kg, l, m, m², m³, ks) — teda aktívna cena vrátane akcie a v daňovom režime, v akom obchod ceny zobrazuje. Keď by zaokrúhlenie obchodu dalo 0,00, pridá desatinné miesta (najviac 4). - Zákonné výnimky drží modul: nekreslí sa, keď by sa jednotková cena
rovnala predajnej (§ 6 ods. 1 — 1 ks, presne 1 l/1 kg) a pri baleniach
s menovitým množstvom najviac 50 g / 50 ml (§ 6 ods. 3 písm. a); filter
px_unit_price_small_pack_exempt). Súbory rôznych tovarov za jednu cenu (§ 6 ods. 3 písm. b) sa riešia tak, že sa im údaj nevyplní. Variabilný rodič nekreslí nič — riadok patrí k cene variácie. - Výstup:
PX_Unit_Price::get_html( $product )→<span class="px-unit-price"><span class="screen-reader-text">Jednotková cena: </span>12,50 € / 1 l</span>; dáta::get()/px_unit_price(). Predvolene sa vešia pod cenu v archíve (woocommerce_after_shop_loop_item_title) aj na detaile (woocommerce_single_product_summary); téma s vlastným miestom vrátifalsez filtrapx_unit_price_display. Vowoocommerce_available_variationcestujepx_unit_price_html, live search vraciaunit_pricepri každom produkte. - Filtre:
px_unit_price_units,px_unit_price_bases,px_unit_price(výsledok pred vykreslením),px_unit_price_visible(skryté ceny pre hostí — jadro samo rešpektujePX_Guest_Prices::isHidden(); riadok prezrádza predajnú cenu, tak sa vypína aj v live search a vo variácii). - Kód jednotky sa pri čítaní normalizuje (
L→l,ks→pc), takže CSV import s ľudsky napísanou jednotkou funguje; neznámy kód = bez riadku. - Vedomé rozhodnutia: variabilný rodič bez riadku (karta ukazuje rozsah cien, riadok patrí k cene variácie); lepiaca lišta na mobile a košík bez riadku (duplikát ceny zo súhrnu, ponuka je už označená).
- Kód, ktorý produkt ukladá sám (importér pred prvým
save()), použijePX_Unit_Price::assign( $product, $qty, $unit )bez uloženia. - WP-CLI:
wp px unit-price set <id> <qty> <unit>,clear <id>,list [--missing] [--format=csv].
GPSR (gpsr)
Nariadenie o všeobecnej bezpečnosti výrobkov (GPSR, EÚ 2023/988). Produkt má v administrácii záložku Bezpečnosť a na fronte produktový tab s rovnakým obsahom.
Každý údaj má práve jedno miesto:
| Kde | Polia | Prečo |
|---|---|---|
Značka (Produkty → Značky, product_brand) |
výrobca, zodpovedná osoba v EÚ | opakujú sa na každom produkte značky; na produkte sa ukazujú len na čítanie s odkazom na značku, produkt s iným výrobcom dostane inú značku |
| Produkt | krajina pôvodu, bezpečnostné upozornenia, URL bezpečnostnej dokumentácie | líšia sa kus od kusu |
PX_GPSR::get_data( $product )vráti zlúčené dáta pre vlastnú šablónu.- Filtre:
px_gpsr_fields(sada polí; web, ktorý má niektoré inde, ho vypustí),px_gpsr_entity_fields(ktoré polia patria značke). - Meta kľúče
_px_gpsr_*na produkte,px_gpsr_*na terme značky.
Firemné údaje (company_fields)
Predvolene vypnutý — zapnúť až keď je preč plugin, ktorý polia riešil
doteraz (WPify Woo ic_dic: kým beží, modul sa nespustí a napíše prečo).
- Polia v pokladni: políčko „Nakupujem na firmu" za menom, pod ním
názov firmy, IČO, DIČ, IČ DPH. Pravidlá povinnosti (podľa políčka alebo
vyplneného názvu firmy; IČO povinné len v krajinách s registrom — SK, CZ,
filter
px_company_country_has_ic), kontrola formátu (IČO 8 číslic, SK DIČ 10, SK IČ DPHSK+10, EÚ prefix krajiny; SK DIČ a IČ DPH si musia odpovedať). - Rovnaké meta kľúče ako WPify Woo:
_billing_ic,_billing_dic,_billing_dic_dphna objednávke, bez podčiarkovníka na zákazníkovi — výmena pluginu bez migrácie. - Doplnenie z registra: RPO (ŠÚ SR) pre SK, ARES (MF ČR) pre CZ, zadarmo bez kľúča. Tlačidlo „Načítať z registra" doplní názov a sídlo. Zaniknuté subjekty sa neponúkajú.
- VIES: vypnuté / overiť a upozorniť / neplatné číslo zastaví objednávku. Výpadok VIES objednávku nikdy nezastaví.
- Prenesenie daňovej povinnosti a vývoz mimo EÚ, každé samostatne.
Rozhodujúca krajina podľa WooCommerce „Vypočítať daň podľa". Predvolene len
s IČ DPH potvrdeným vo VIES („Vyžadovať doklad"). Dôvod sa ukladá
(
_px_vat_exempt_reason), ukazuje v admine a loguje. - Cache (firma týždeň, platné IČ DPH deň, neplatné hodinu), REST endpointy
pixeler/v1/company/lookupa.../vats limitom na IP (px_company_rate_limit, 30). - Údaje idú do admin objednávky, profilu zákazníka, formátovanej adresy,
e-mailov a cez
sf_client_datado SuperFaktúry (jej vlastný firemný blok sa vypne). - Šablóny:
px_company_order_details( $order ),px_company_vat_reason( $order ). JS len prepínahiddena nasadzujepx-company-*triedy. - Ďalšie filtre:
px_company_force_company_field,px_company_use_dic_dph,px_company_vat_destination,px_company_vat_decision,px_company_register_countries,px_company_details.
Live search (search)
REST GET pixeler/v1/search?term=… vráti produkty a zodpovedajúce kategórie
pre šepkávač v hlavičke. Rešpektuje „skryť vypredané", vynecháva kategórie
bez viditeľných produktov a položka nesie in_stock.
Známy rozdiel: počet za „Zobraziť všetkých N výsledkov" sedí s archívom,
ale nie nutne so stránkou výsledkov vyhľadávania. Šepkávač vypredané skrýva
(keď je voľba zapnutá), kým WooCommerce na stránke výsledkov aplikuje len
exclude-from-search — hide_out_of_stock_items rieši v get_tax_query(),
ktorý beží na archívoch, nie na vyhľadávaní. Weby, ktoré chcú rovnaké čísla,
si vypredané skrývajú vlastným pre_get_posts (tak to má libike).
Filtre: px_shop_core_search_limit (8), px_shop_core_search_cat_limit (4),
px_shop_core_search_query_args, px_shop_core_search_code_ids,
px_shop_core_search_code_limit, px_shop_core_search_response.
Vyhľadávanie podľa SKU a EAN
Hľadá sa aj podľa SKU (_sku) a EAN/GTIN (_global_unique_id) —
v šepkávači aj na štandardnej stránke výsledkov (?s=…&post_type=product,
cez filter posts_search). WordPress prehľadáva len názov, perex a obsah;
nalepený kód dielu ani pípnutý čiarový kód dovtedy nevrátili nič. Zhoda
variácie sa mapuje na rodiča — variácia nemá vlastnú stránku a na krabici býva
jej SKU.
| Pravidlo | Prečo |
|---|---|
| SKU presne + podľa predpony od 4 znakov | predpona SKU nesie význam (SKU variácie predlžuje rodičovské), ale „RAM" nesmie ťahať pol katalógu |
| EAN/GTIN len presne | pevná dĺžka, čiastočný kód nič neznamená — a stĺpec nemá index, takže sa k nemu bežné slovo vôbec nedostane |
| presná zhoda potláča prefixové | keď kód nesie konkrétny produkt, rodina s rovnakým začiatkom SKU je šum; presné SKU tak vráti jeden výsledok — a pri jednom výsledku presmeruje WooCommerce (wc_template_redirect(), filter woocommerce_redirect_single_search_result) rovno na produkt, ale len keď je v URL post_type=product, teda z formulára v hlavičke |
| prefixové zhody sa radia podľa dĺžky SKU | keď ich je viac než strop, rez nesmie padnúť podľa ID produktu — päťdesiat najstarších z päťsto neodpovedá na nič. Prežije to, čo je najbližšie napísanému |
variácia → rodič, GROUP BY, strop |
žiadne dotazy v cykle, jeden $wpdb->prepare dotaz na otázku |
Zdroj dát je wc_product_meta_lookup (riadok na produkt, sku indexované, ten
istý zdroj, na akom beží vyhľadávanie v administrácii WooCommerce). SKU a EAN sa
pýtajú dvoma dotazmi, nie jedným OR: index má len sku, a spoločná
podmienka by oň optimalizátor pripravil — každá číselná fráza (aj bežné číselné
SKU) by potom znamenala full scan lookup tabuľky. Najprv teda beží indexovaná
otázka na SKU a global_unique_id sa pýta, až keď nič nevrátila.
Lookup je cache, ktorú WooCommerce prepisuje pri uložení produktu — importér
zapisujúci _sku priamo cez update_post_meta() ju vie nechať pozadu. Keď kód,
o ktorom vieš, že existuje, vyhľadávanie nenájde, správna oprava je
WooCommerce → Stav → Nástroje → Obnoviť vyhľadávacie tabuľky produktov.
Dohľadanie priamo v postmeta v kóde ostáva, ale beží len pod WP-CLI
(PX_Search::product_ids_matching_code() z wp eval) — je to sken každého
_sku a _global_unique_id riadku bez indexu, čo verejné vyhľadávacie pole
spúšťať nesmie: crawler s vymyslenými kódmi by ho vyvolal na každý request.
Slúži na overenie, či je lookup pozadu.
Stĺpec global_unique_id pribudol vo WooCommerce 9.1; na starších inštaláciách
sa EAN cez front end nenájde (prítomnosť stĺpca sa zisťuje raz za týždeň,
transient s číslom verzie WooCommerce v kľúči).
Na stránke výsledkov sa nájdené ID pripájajú do klauzuly posts_search
(OR ID IN (…)), takže post_type, post_status, ochrana heslom aj
tax_query na product_visibility z hlavného dopytu platia ďalej —
viditeľnosť sa nefiltruje druhýkrát. Podmienka na post_password sa pred
OR odtrhne a prilepí späť za neho; ak po tom v reťazci ostane čo i len
zmienka o post_password, alebo fragment nemá presne tvar AND (…), ktorý
stavia jadro, filter dotaz nechá nezmenený. Žiadny best effort — polovične
pochopený WHERE je presne to, čím sa vo výsledkoch začnú objavovať heslom
chránené a nepublikované príspevky. Vedľajšie dopyty (widgety, súvisiace
produkty) a administrácia — tá má vlastné vyhľadávanie podľa SKU od
WooCommerce — ostávajú nedotknuté. Hlavné vyhľadávanie bez post_type
WordPress rieši ako any, takže kód nájde produkt aj z bežného
vyhľadávacieho poľa.
Helper PX_Search::product_ids_matching_code( $term, $limit ) je verejný.
Filter px_shop_core_search_code_ids( $ids, $term, $limit ) je pre obchod,
ktorý drží čísla dielov inde (vlastný meta kľúč, dodávateľská tabuľka) —
zapojí sa sem namiesto toho, aby si vyhľadávanie písal odznova.
Odpoveď je 60 sekúnd v transiente a posiela Cache-Control: public, max-age=60. Endpoint je verejný a bez rate limitu, pri šepkávači ide request
na každé písmeno — bez cache by opakovaná fráza púšťala WP_Query aj
get_terms() nanovo. Cachuje sa stav pred px_shop_core_search_response, ten
filter beží aj nad cachovanými dátami (nech je lacný a bez údajov viazaných na
konkrétneho návštevníka).
Kľúč nesie normalizovanú frázu (malé písmená, zúžené medzery — „Prilba"
a „prilba" je tá istá otázka), jazyk, a všetko, od čoho závisí price_html:
menu, nastavenie „zobrazovať ceny s daňou / bez dane" a oslobodenie od DPH
(WC()->customer->get_is_vat_exempt(), ktoré prepína aj modul firemných údajov
tohto pluginu). Bez toho by prvý návštevník s iným daňovým kontextom otrávil
ceny všetkým na 60 sekúnd. Prihlásenému zákazníkovi sa necachuje vôbec a
zapisuje sa len s perzistentnou object cache (wp_using_ext_object_cache())
— inak by každá neznáma fráza z verejného endpointu znamenala dva riadky v
wp_options a crawler by ich narobil státisíce. Fráza je obmedzená na 64
znakov. viewAll sa do cache nedáva: nesie pôvodné písanie návštevníka.
Dôsledok: na webe bez object cache serverová cache šepkávača nie je a
zostáva len hlavička Cache-Control, ktorá opakované písmená zachytí
v prehliadači a na CDN. Kto chce cache aj na serveri, zapne Redis.
px_shop_core_search_query_args( $args, $term ) dostane WP_Query argumenty
skôr, než dotaz pobeží. Slúži na to, aby si web preložil časť frázy na
atribútový filter — e-shop s rozmermi chce z „matrac 90x200" spraviť
tax_query nad pa_rozmer a fulltextu nechať len „matrac", čo obyčajné LIKE
nad post_title nikdy netrafí. Názvy atribútov patria site pluginu, plugin
ich neháda. Ak filter skráti $args['s'], nech ho nechá orezaný — vyhľadanie
kategórie beží nad tou istou hodnotou (a pri prázdnej sa preskočí), takže
spotrebované tokeny neprepadnú do zhody na názov kategórie.
Brand tab (brand_tab)
Produktový tab „O značke" z popisu termu product_brand + logo značky.
PX_Brand_Tab::get_brands_with_description( $product ) pre vlastné
vykreslenie.
Wishlist (wishlist)
Obľúbené produkty: prihlásený zákazník v user meta, hosť v cookie
px_wishlist; pri prihlásení sa cookie zlúči do účtu.
| Čo | Ako |
|---|---|
| REST | GET px-shop-core/v1/wishlist, POST px-shop-core/v1/wishlist/toggle |
| Helpery | px_wishlist_ids(), px_wishlist_has( $id ), px_wishlist_count(), px_wishlist_url() |
| Stránka | shortcode [px_wishlist], stránka v nastaveniach (px_wishlist_page_id) |
| Filtre | px_wishlist_url, px_products_grid_classes |
| CLI | wp px wishlist migrate [--dry-run] (prevod z Woodmartu) |
Compare (compare)
Porovnanie až štyroch produktov, cookie px_compare.
| Čo | Ako |
|---|---|
| REST | GET px-shop-core/v1/compare, POST px-shop-core/v1/compare/toggle |
| Helpery | px_compare_ids(), px_compare_has( $id ), px_compare_count(), px_compare_url() |
| Stránka | shortcode [px_compare] (tabuľka atribútov), stránka v nastaveniach (px_compare_page_id) |
| Filtre | px_compare_attribute_rows, px_compare_url |
Waitlist (waitlist)
Stráženie dostupnosti vypredaného produktu (aj variácie).
- Double opt-in — adresa sa počíta až po kliknutí v e-maile; odhlásenie jedným odkazom v každej správe maže adresu zo všetkých produktov.
- Štyri e-maily ako bežné WooCommerce triedy (WooCommerce → Nastavenia →
E-maily, šablóny
woocommerce/emails/px-waitlist-*.php): potvrdenie adresy, potvrdené prihlásenie, naskladnenie, notifikácia pre admina. - Formulár
PX_Waitlist::render_form( $product )/::get_form_html(), RESTPOST px-shop-core/v1/waitlist. - Metabox na produkte so zoznamom prihlásených,
PX_Waitlist::count(). - Akcie:
px_waitlist_subscribed,px_waitlist_confirmed,px_waitlist_unsubscribed,px_waitlist_back_in_stock. Filtre:px_waitlist_require_confirmation,px_waitlist_show_form. - CLI:
wp px waitlist migrate [--dry-run]z Woodmartu.
Veľkostné tabuľky (size_guide)
CPT px_size_guide (Produkty → Veľkostné tabuľky) s tabuľkou (riadok na
riadok, bunky cez | alebo tabulátor) a voliteľným textom. Produkt si
tabuľku vyberie sám, inak zdedí z kategórie; „nezobrazovať" potlačí aj
kategóriu.
PX_Size_Guide::render()— odkaz + modál (<dialog>),::get_content_html()samotný obsah,::has_guide(). Témy sowoocommerce_single_product_summarydostanú modál samy.- Filter
px_size_guide_button_text. - CLI:
wp px size-guide migrate [--dry-run]z Woodmartu; dočasný most čítawoodmart_sguide_select, kým dáta nie sú prevedené.
Súvisiace kategórie (related_cats)
Doplnky raz na kategórii: Bicykle → Svetlá, Košíky na fľaše. Väzba je jednosmerná a dedí sa po strome (podkategória bez nastavenia sa pýta rodiča; stĺpec Súvisiace v Produkty → Kategórie). Produkty sa berú striedavo z každej kategórie, poradie voliteľné (najpredávanejšie / najnovšie / poradie v kategórii), vypredané a z katalógu vylúčené sa neponúkajú.
- Cache na množinu kategórií, neplatní ju uloženie kategórie.
PX_Related_Cats::get_product_ids( $product_id, $limit )/px_related_category_ids(),::get_title().- Voliteľne aj v košíku (cross-sell, klasický košík).
- Filtre:
px_related_cats_term_ids,px_related_cats_product_ids,px_related_cats_query_args,px_related_cats_title.
Shipping bar (shipping_bar)
Dáta pre lištu „do dopravy zadarmo chýba X €": px_free_shipping_state()
vráti null (doprava zadarmo sa neponúka) alebo
[ threshold, remaining, progress 0–100 ]. Prah sa berie z metódy Free
shipping v aktívnej zóne (počíta sa ako WooCommerce: zobrazený medzisúčet
mínus zľavy); filter px_free_shipping_threshold.
Katalógový režim (catalog)
„Výklad" bez nákupu: režim a skrytie cien sa zapína v nastaveniach modulu,
s voliteľným náhradným tlačidlom (text + odkaz, napr. „Dopyt"). Téma
používa px_catalog_mode(), px_catalog_hide_price(),
px_catalog_button( $product, $classes ); filter px_catalog_button_class.
Obrázky atribútov (attribute_image)
Pole s obrázkom na každom terme atribútu pa_* (pre swatche a filtre), so
stĺpcom v zozname termov. PX_Attribute_Image::image_id( $term_id ),
::image( $term_id, $size, $attr ); helpery px_get_term_image_id(),
px_get_term_image() sú chránené pred redeklaráciou.
Content bloky (content)
Neverejný CPT px_content pre znovupoužiteľné bloky (bannery, USP pásy)
s layoutmi (px_content_layouts, predvolene media-right), zarovnaním a
kategóriami. Nezávisí od WooCommerce.
- Helpery:
px_get_content_items( $category, $limit ),px_get_banner( $post ),px_banner( $item, $args ),px_banners( $args ),px_content_template( $name, $args ). - Shortcode
[px_banner]. Šablóny vtemplates/content/, prepis v téme cezpx_content_locate_template. - Video na pozadí (YouTube/Vimeo alebo MP4/WebM z knižnice), odkaz celého
bannera a karusel (
carousel) od 1.10.0, vyžadujú px-shop-theme 0.6.0+ — podrobne vtemplates/content/README.md. - Filtre:
px_content_banner_data,px_content_banner_html,px_content_banner_classes,px_content_text_html,px_content_default_layout,px_content_style_handle,px_content_video_script_handle,px_content_video_consent,px_content_video_cmp,px_content_video_cmp_category,px_content_carousel_handle,px_content_carousel_labels.
Súhlas s cookies (consent)
Vlastná CMP namiesto Complianzu. Predvolene vypnutá — web, ktorý si necháva
externú CMP (CookieYes, Complianz, Cookiebot), ju nechá vypnutú a z modulu sa
nenačíta nič. Zapnutý modul sa pri aktívnej cudzej CMP sám nespustí a napíše to
v admine; zároveň vypne most consent_mode, lebo signály posiela sám.
Nastavenia: WooCommerce → Nastavenia → PX Shop → Súhlas s cookies (služby, ich ID, verzia zásad, stránka so zásadami).
Čo modul robí:
- Register služieb je jediný zdroj pravdy — jedna deklarácia v PHP živí lištu, modál, stránku so zásadami aj blokovanie. Vstavaný katalóg: GA4, Google Ads, GTM, Meta Pixel, Microsoft Clarity, Smartsupp, Heureka, YouTube, Google Maps, reCAPTCHA + cookies WordPressu, WooCommerce a PX Shop.
- Lišta v dvoch vrstvách: Prijať všetko / Odmietnuť všetko / Nastavenia rovnakej váhy, žiadne predznačené políčka, žiadna cookie wall; v modále prepínače per kategória aj per služba.
- Súhlas v cookie
px_consent(verzia zásad, čas, ID, kategórie, služby), platnosť 182 dní. Zmena Verzie zásad = lišta sa spýta znova. PHP cookie nečíta — výstup je rovnaký pre všetkých, page cache nemá čo pokaziť. - Blokovanie skriptov cez
type="text/plain"; pri odvolaní sa zmažú známe cookies a stránka sa načíta znova. - Google (GA4, Ads, GTM) sa neblokuje, riadi sa signálmi Consent Mode v2:
consent defaultdenied v<head>,consent updatenapx:consent,dataLayereventpx_consent_update. Meta Pixel dostávafbq('consent'). - Vložené videá a mapy dostanú zástupný box s tlačidlom; YouTube cez
youtube-nocookie.com; bez JS ostáva odkaz na pôvodný obsah. - Podstránka so shortcodom
[px_cookie_policy]vzniká pri zapnutí ako koncept.
Kontrakt pre tému a site plugin:
| Čo | Ako |
|---|---|
| Je funkcia dostupná? | class_exists( 'PX_Consent' ) && PX_Consent::active() |
| Odkaz „Nastavenia cookies" | data-px-consent-settings na tlačidle, alebo window.pxConsent.open() |
| Reakcia na voľbu | document.addEventListener( 'px:consent', e => e.detail.categories ) |
| Vlastný skript tretej strany | ` |