Initial Commit

This commit is contained in:
David Stone
2024-11-30 18:24:12 -07:00
commit e8f7955c1c
5432 changed files with 1397750 additions and 0 deletions
LICENSE
assets
css
fonts
img
badge.pngbg-setup.png
checkout-forms
empty-state-bg.pngerasmo-carlos.jpg
flags
1x1
ad.svgae.svgaf.svgag.svgai.svgal.svgam.svgao.svgaq.svgar.svgas.svgat.svgau.svgaw.svgax.svgaz.svgba.svgbb.svgbd.svgbe.svgbf.svgbg.svgbh.svgbi.svgbj.svgbl.svgbm.svgbn.svgbo.svgbq.svgbr.svgbs.svgbt.svgbv.svgbw.svgby.svgbz.svgca.svgcc.svgcd.svgcf.svgcg.svgch.svgci.svgck.svgcl.svgcm.svgcn.svgco.svgcr.svgcu.svgcv.svgcw.svgcx.svgcy.svgcz.svgde.svgdj.svgdk.svgdm.svgdo.svgdz.svgec.svgee.svgeg.svgeh.svger.svges-ca.svges-ga.svges.svget.svgeu.svgfi.svgfj.svgfk.svgfm.svgfo.svgfr.svgga.svggb-eng.svggb-nir.svggb-sct.svggb-wls.svggb.svggd.svgge.svggf.svggg.svggh.svggi.svggl.svggm.svggn.svggp.svggq.svggr.svggs.svggt.svggu.svggw.svggy.svghk.svghm.svghn.svghr.svght.svghu.svgid.svgie.svgil.svgim.svgin.svgio.svgiq.svgir.svgis.svgit.svgje.svgjm.svgjo.svgjp.svgke.svgkg.svgkh.svgki.svgkm.svgkn.svgkp.svgkr.svgkw.svgky.svgkz.svgla.svglb.svglc.svgli.svglk.svglr.svgls.svglt.svglu.svglv.svgly.svgma.svgmc.svgmd.svgme.svgmf.svgmg.svgmh.svgmk.svgml.svgmm.svgmn.svgmo.svgmp.svgmq.svgmr.svgms.svgmt.svgmu.svgmv.svgmw.svgmx.svgmy.svgmz.svgna.svgnc.svgne.svgnf.svgng.svgni.svgnl.svgno.svgnp.svgnr.svgnu.svgnz.svgom.svgpa.svgpe.svgpf.svgpg.svgph.svgpk.svgpl.svgpm.svgpn.svgpr.svgps.svgpt.svgpw.svgpy.svgqa.svgre.svgro.svgrs.svgru.svgrw.svgsa.svgsb.svgsc.svgsd.svgse.svgsg.svgsh.svgsi.svgsj.svgsk.svgsl.svgsm.svgsn.svgso.svgsr.svgss.svgst.svgsv.svgsx.svgsy.svgsz.svgtc.svgtd.svgtf.svgtg.svgth.svgtj.svgtk.svgtl.svgtm.svgtn.svgto.svgtr.svgtt.svgtv.svgtw.svgtz.svgua.svgug.svgum.svgun.svgus.svguy.svguz.svgva.svgvc.svgve.svgvg.svgvi.svgvn.svgvu.svgwf.svgws.svgxk.svgye.svgyt.svgza.svgzm.svgzw.svg
4x3
ad.svgae.svgaf.svgag.svgai.svgal.svgam.svgao.svgaq.svgar.svgas.svgat.svgau.svgaw.svgax.svgaz.svgba.svgbb.svgbd.svgbe.svgbf.svgbg.svgbh.svgbi.svgbj.svgbl.svgbm.svgbn.svgbo.svgbq.svgbr.svgbs.svgbt.svgbv.svgbw.svgby.svgbz.svgca.svgcc.svgcd.svgcf.svgcg.svgch.svgci.svgck.svgcl.svgcm.svgcn.svgco.svgcr.svgcu.svgcv.svgcw.svgcx.svgcy.svgcz.svgde.svgdj.svgdk.svgdm.svgdo.svgdz.svgec.svgee.svgeg.svgeh.svger.svges-ca.svges-ga.svges.svget.svgeu.svgfi.svgfj.svgfk.svgfm.svgfo.svgfr.svgga.svggb-eng.svggb-nir.svggb-sct.svggb-wls.svggb.svggd.svgge.svggf.svggg.svggh.svggi.svggl.svggm.svggn.svggp.svggq.svggr.svggs.svggt.svggu.svggw.svggy.svghk.svghm.svghn.svghr.svght.svghu.svgid.svgie.svgil.svgim.svgin.svgio.svgiq.svgir.svgis.svgit.svgje.svgjm.svgjo.svgjp.svgke.svgkg.svgkh.svgki.svgkm.svgkn.svgkp.svgkr.svgkw.svgky.svgkz.svgla.svglb.svglc.svgli.svglk.svglr.svgls.svglt.svglu.svglv.svgly.svgma.svgmc.svgmd.svgme.svgmf.svgmg.svgmh.svgmk.svgml.svgmm.svgmn.svgmo.svgmp.svgmq.svgmr.svgms.svgmt.svgmu.svgmv.svgmw.svgmx.svgmy.svgmz.svgna.svgnc.svgne.svgnf.svgng.svgni.svgnl.svgno.svgnp.svgnr.svgnu.svgnz.svgom.svgpa.svgpe.svgpf.svgpg.svgph.svgpk.svgpl.svgpm.svgpn.svgpr.svgps.svgpt.svgpw.svgpy.svgqa.svgre.svgro.svgrs.svgru.svgrw.svgsa.svgsb.svgsc.svgsd.svgse.svgsg.svgsh.svgsi.svgsj.svgsk.svgsl.svgsm.svgsn.svgso.svgsr.svgss.svgst.svgsv.svgsx.svgsy.svgsz.svgtc.svgtd.svgtf.svgtg.svgth.svgtj.svgtk.svgtl.svgtm.svgtn.svgto.svgtr.svgtt.svgtv.svgtw.svgtz.svgua.svgug.svgum.svgun.svgus.svguy.svguz.svgva.svgvc.svgve.svgvg.svgvi.svgvn.svgvu.svgwf.svgws.svgxk.svgye.svgyt.svgza.svgzm.svgzw.svg
hosts
loader.svglogo.pngno-preview.pngpattern-wp-ultimo.png
settings
sidebar
site-placeholder-image.png
wizards
wp-ultimo-screenshot.png
js
addons.jsaddons.min.jsadmin-notices.jsadmin-notices.min.jsadmin-screen.jsadmin-screen.min.jsadmin.jsadmin.min.jsapp.jsapp.min.jscheckout-form-editor-modal.jscheckout-form-editor-modal.min.jscheckout-forms-editor.jscheckout-forms-editor.min.jscheckout.jscheckout.min.jscookie-helpers.jscookie-helpers.min.jscustomizer.jscustomizer.min.jsdashboard-statistics.jsdashboard-statistics.min.jsedit-placeholders.jsedit-placeholders.min.jsemail-edit-page.jsemail-edit-page.min.jsevent-view-page.jsevent-view-page.min.jsfields.jsfields.min.jsfunctions.jsfunctions.min.js
gateways
gutenberg-support.jsgutenberg-support.min.jsjumper.jsjumper.min.jslegacy-signup.jslegacy-signup.min.js
lib
list-tables.jslist-tables.min.jsscreenshot-scraper.jsscreenshot-scraper.min.jsselectizer.jsselectizer.min.jssetup-wizard-polyfill.jssetup-wizard-polyfill.min.jssetup-wizard.jssetup-wizard.min.jssite-maintenance.jssite-maintenance.min.jssso.jssso.min.jssupport.jssupport.min.jstax-rates.jstax-rates.min.jstax-statistics.jstax-statistics.min.jstemplate-previewer.jstemplate-previewer.min.jstemplate-switching.jstemplate-switching.min.jsthank-you.jsthank-you.min.jstours.jstours.min.jsurl-preview.jsurl-preview.min.jsview-logs.jsview-logs.min.jsvisits-counter.jsvisits-counter.min.jsvue-apps.jsvue-apps.min.jswebhook-list-page.jswebhook-list-page.min.jswebhook-page.jswebhook-page.min.jswubox.jswubox.min.js
autoload.phpconstants.php
data
dependencies
amphp
amp
byte-stream
cache
dns
hpack
http-client
http
parser
process
serialization
socket
sync
windows-registry
autoload.php
berlindb
composer
daverandom
delight-im
doctrine
deprecations
lib
Doctrine
guzzlehttp
guzzle
promises
psr7
hashids
ifsnop
mysqldump-php
src
Ifsnop
Mysqldump
jasny
kelunik
league
mexitek
phpcolors
demo
src
Mexitek
PHPColors
mpdf
mpdf
CREDITS.txt
data
CJKdata.php
collations
Afrikaans_South_Africa.phpAlbanian_Albania.phpAlsatian_France.phpArabic_Algeria.phpArabic_Bahrain.phpArabic_Egypt.phpArabic_Iraq.phpArabic_Jordan.phpArabic_Kuwait.phpArabic_Lebanon.phpArabic_Libya.phpArabic_Morocco.phpArabic_Oman.phpArabic_Pseudo_RTL.phpArabic_Qatar.phpArabic_Saudi_Arabia.phpArabic_Syria.phpArabic_Tunisia.phpArabic_Yemen.phpAzeri_(Cyrillic)_Azerbaijan.phpAzeri_(Latin)_Azerbaijan.phpBashkir_Russia.phpBasque_Spain.phpBelarusian_Belarus.phpBosnian_(Cyrillic)_Bosnia_and_Herzegovina.phpBosnian_(Latin)_Bosnia_and_Herzegovina.phpBreton_France.phpBulgarian_Bulgaria.phpCatalan_Spain.phpCorsican_France.phpCroatian_(Latin)_Bosnia_and_Herzegovina.phpCroatian_Croatia.phpCzech_Czech_Republic.phpDanish_Denmark.phpDari_Afghanistan.phpDutch_Belgium.phpDutch_Netherlands.phpEnglish_Australia.phpEnglish_Belize.phpEnglish_Canada.phpEnglish_Caribbean.phpEnglish_India.phpEnglish_Ireland.phpEnglish_Jamaica.phpEnglish_Malaysia.phpEnglish_New_Zealand.phpEnglish_Republic_of_the_Philippines.phpEnglish_Singapore.phpEnglish_South_Africa.phpEnglish_Trinidad_and_Tobago.phpEnglish_United_Kingdom.phpEnglish_United_States.phpEnglish_Zimbabwe.phpEstonian_Estonia.phpFaroese_Faroe_Islands.phpFilipino_Philippines.phpFinnish_Finland.phpFrench_Belgium.phpFrench_Canada.phpFrench_France.phpFrench_Luxembourg.phpFrench_Principality_of_Monaco.phpFrench_Switzerland.phpFrisian_Netherlands.phpGalician_Spain.phpGerman_Austria.phpGerman_Germany.phpGerman_Liechtenstein.phpGerman_Luxembourg.phpGerman_Switzerland.phpGreek_Greece.phpGreenlandic_Greenland.phpHausa_(Latin)_Nigeria.phpHebrew_Israel.phpHungarian_Hungary.phpIcelandic_Iceland.phpIgbo_Nigeria.phpIndonesian_Indonesia.phpInuktitut_(Latin)_Canada.phpInvariant_Language_Invariant_Country.phpIrish_Ireland.phpItalian_Italy.phpItalian_Switzerland.phpKinyarwanda_Rwanda.phpKiswahili_Kenya.phpKyrgyz_Kyrgyzstan.phpLatvian_Latvia.phpLithuanian_Lithuania.phpLower_Sorbian_Germany.phpLuxembourgish_Luxembourg.phpMacedonian_(FYROM)_Macedonia_(FYROM).phpMalay_Brunei_Darussalam.phpMalay_Malaysia.phpMapudungun_Chile.phpMohawk_Canada.phpMongolian_(Cyrillic)_Mongolia.phpNorwegian_(Nynorsk)_Norway.phpOccitan_France.phpPersian_Iran.phpPolish_Poland.phpPortuguese_Brazil.phpPortuguese_Portugal.phpQuechua_Bolivia.phpQuechua_Ecuador.phpQuechua_Peru.phpRomanian_Romania.phpRomansh_Switzerland.phpRussian_Russia.phpSami_(Inari)_Finland.phpSami_(Lule)_Norway.phpSami_(Lule)_Sweden.phpSami_(Northern)_Finland.phpSami_(Northern)_Norway.phpSami_(Northern)_Sweden.phpSami_(Skolt)_Finland.phpSami_(Southern)_Norway.phpSami_(Southern)_Sweden.phpSerbian_(Cyrillic)_Bosnia_and_Herzegovina.phpSerbian_(Cyrillic)_Serbia.phpSerbian_(Latin)_Bosnia_and_Herzegovina.phpSerbian_(Latin)_Serbia.phpSesotho_sa_Leboa_South_Africa.phpSetswana_South_Africa.phpSlovak_Slovakia.phpSlovenian_Slovenia.phpSpanish_Argentina.phpSpanish_Bolivia.phpSpanish_Chile.phpSpanish_Colombia.phpSpanish_Costa_Rica.phpSpanish_Dominican_Republic.phpSpanish_Ecuador.phpSpanish_El_Salvador.phpSpanish_Guatemala.phpSpanish_Honduras.phpSpanish_Mexico.phpSpanish_Nicaragua.phpSpanish_Panama.phpSpanish_Paraguay.phpSpanish_Peru.phpSpanish_Puerto_Rico.phpSpanish_Spain.phpSpanish_United_States.phpSpanish_Uruguay.phpSpanish_Venezuela.phpSwedish_Finland.phpSwedish_Sweden.phpTajik_(Cyrillic)_Tajikistan.phpTamazight_(Latin)_Algeria.phpTatar_Russia.phpTurkish_Turkey.phpTurkmen_Turkmenistan.phpUkrainian_Ukraine.phpUpper_Sorbian_Germany.phpUrdu_Islamic_Republic_of_Pakistan.phpUzbek_(Cyrillic)_Uzbekistan.phpUzbek_(Latin)_Uzbekistan.phpVietnamese_Vietnam.phpWelsh_United_Kingdom.phpWolof_Senegal.phpYakut_Russia.phpYoruba_Nigeria.phpisiXhosa_South_Africa.phpisiZulu_South_Africa.php
entity_substitutions.php
font
iccprofiles
lang2fonts.csslinebrdictK.datlinebrdictL.datlinebrdictT.datmpdf.cssno_image.jpgout.php
patterns
subs_core.phpsubs_win-1252.phpupperCase.php
phpunit.xmlruleset.xml
src
AssetFetcher.phpBarcode.php
Barcode
Cache.php
Color
Config
Container
Conversion
Css
CssManager.phpDirectWrite.php
Exception
File
Fonts
Form.phpFpdiTrait.php
Gif
Gradient.phpHTMLParserMode.php
Http
Hyphenator.php
Image
Language
Log
Mpdf.phpMpdfException.phpMpdfImageException.phpOtl.phpOtlDump.php
Output
PageBox.phpPageFormat.php
Pdf
ServiceFactory.php
Shaper
SizeConverter.phpStrict.phpTTFontFile.phpTTFontFileAnalysis.phpTableOfContents.phpTag.php
Tag
Ucdn.php
Utils
Watermark.phpWatermarkImage.phpWatermarkText.php
Writer
functions-dev.phpfunctions.php
ttfonts
psr-http-message-shim
psr-log-aware-trait
myclabs
nesbot
carbon
extension.neon
lazy
sponsors.php
src
Carbon
AbstractTranslator.phpCarbon.phpCarbonConverterInterface.phpCarbonImmutable.phpCarbonInterface.phpCarbonInterval.phpCarbonPeriod.phpCarbonPeriodImmutable.phpCarbonTimeZone.php
Cli
Doctrine
Exceptions
Factory.phpFactoryImmutable.php
Lang
aa.phpaa_DJ.phpaa_ER.phpaa_ER@saaho.phpaa_ET.phpaf.phpaf_NA.phpaf_ZA.phpagq.phpagr.phpagr_PE.phpak.phpak_GH.phpam.phpam_ET.phpan.phpan_ES.phpanp.phpanp_IN.phpar.phpar_AE.phpar_BH.phpar_DJ.phpar_DZ.phpar_EG.phpar_EH.phpar_ER.phpar_IL.phpar_IN.phpar_IQ.phpar_JO.phpar_KM.phpar_KW.phpar_LB.phpar_LY.phpar_MA.phpar_MR.phpar_OM.phpar_PS.phpar_QA.phpar_SA.phpar_SD.phpar_SO.phpar_SS.phpar_SY.phpar_Shakl.phpar_TD.phpar_TN.phpar_YE.phpas.phpas_IN.phpasa.phpast.phpast_ES.phpayc.phpayc_PE.phpaz.phpaz_AZ.phpaz_Cyrl.phpaz_IR.phpaz_Latn.phpbas.phpbe.phpbe_BY.phpbe_BY@latin.phpbem.phpbem_ZM.phpber.phpber_DZ.phpber_MA.phpbez.phpbg.phpbg_BG.phpbhb.phpbhb_IN.phpbho.phpbho_IN.phpbi.phpbi_VU.phpbm.phpbn.phpbn_BD.phpbn_IN.phpbo.phpbo_CN.phpbo_IN.phpbr.phpbr_FR.phpbrx.phpbrx_IN.phpbs.phpbs_BA.phpbs_Cyrl.phpbs_Latn.phpbyn.phpbyn_ER.phpca.phpca_AD.phpca_ES.phpca_ES_Valencia.phpca_FR.phpca_IT.phpccp.phpccp_IN.phpce.phpce_RU.phpcgg.phpchr.phpchr_US.phpckb.phpcmn.phpcmn_TW.phpcrh.phpcrh_UA.phpcs.phpcs_CZ.phpcsb.phpcsb_PL.phpcu.phpcv.phpcv_RU.phpcy.phpcy_GB.phpda.phpda_DK.phpda_GL.phpdav.phpde.phpde_AT.phpde_BE.phpde_CH.phpde_DE.phpde_IT.phpde_LI.phpde_LU.phpdje.phpdoi.phpdoi_IN.phpdsb.phpdsb_DE.phpdua.phpdv.phpdv_MV.phpdyo.phpdz.phpdz_BT.phpebu.phpee.phpee_TG.phpel.phpel_CY.phpel_GR.phpen.phpen_001.phpen_150.phpen_AG.phpen_AI.phpen_AS.phpen_AT.phpen_AU.phpen_BB.phpen_BE.phpen_BI.phpen_BM.phpen_BS.phpen_BW.phpen_BZ.phpen_CA.phpen_CC.phpen_CH.phpen_CK.phpen_CM.phpen_CX.phpen_CY.phpen_DE.phpen_DG.phpen_DK.phpen_DM.phpen_ER.phpen_FI.phpen_FJ.phpen_FK.phpen_FM.phpen_GB.phpen_GD.phpen_GG.phpen_GH.phpen_GI.phpen_GM.phpen_GU.phpen_GY.phpen_HK.phpen_IE.phpen_IL.phpen_IM.phpen_IN.phpen_IO.phpen_ISO.phpen_JE.phpen_JM.phpen_KE.phpen_KI.phpen_KN.phpen_KY.phpen_LC.phpen_LR.phpen_LS.phpen_MG.phpen_MH.phpen_MO.phpen_MP.phpen_MS.phpen_MT.phpen_MU.phpen_MW.phpen_MY.phpen_NA.phpen_NF.phpen_NG.phpen_NL.phpen_NR.phpen_NU.phpen_NZ.phpen_PG.phpen_PH.phpen_PK.phpen_PN.phpen_PR.phpen_PW.phpen_RW.phpen_SB.phpen_SC.phpen_SD.phpen_SE.phpen_SG.phpen_SH.phpen_SI.phpen_SL.phpen_SS.phpen_SX.phpen_SZ.phpen_TC.phpen_TK.phpen_TO.phpen_TT.phpen_TV.phpen_TZ.phpen_UG.phpen_UM.phpen_US.phpen_US_Posix.phpen_VC.phpen_VG.phpen_VI.phpen_VU.phpen_WS.phpen_ZA.phpen_ZM.phpen_ZW.phpeo.phpes.phpes_419.phpes_AR.phpes_BO.phpes_BR.phpes_BZ.phpes_CL.phpes_CO.phpes_CR.phpes_CU.phpes_DO.phpes_EA.phpes_EC.phpes_ES.phpes_GQ.phpes_GT.phpes_HN.phpes_IC.phpes_MX.phpes_NI.phpes_PA.phpes_PE.phpes_PH.phpes_PR.phpes_PY.phpes_SV.phpes_US.phpes_UY.phpes_VE.phpet.phpet_EE.phpeu.phpeu_ES.phpewo.phpfa.phpfa_AF.phpfa_IR.phpff.phpff_CM.phpff_GN.phpff_MR.phpff_SN.phpfi.phpfi_FI.phpfil.phpfil_PH.phpfo.phpfo_DK.phpfo_FO.phpfr.phpfr_BE.phpfr_BF.phpfr_BI.phpfr_BJ.phpfr_BL.phpfr_CA.phpfr_CD.phpfr_CF.phpfr_CG.phpfr_CH.phpfr_CI.phpfr_CM.phpfr_DJ.phpfr_DZ.phpfr_FR.phpfr_GA.phpfr_GF.phpfr_GN.phpfr_GP.phpfr_GQ.phpfr_HT.phpfr_KM.phpfr_LU.phpfr_MA.phpfr_MC.phpfr_MF.phpfr_MG.phpfr_ML.phpfr_MQ.phpfr_MR.phpfr_MU.phpfr_NC.phpfr_NE.phpfr_PF.phpfr_PM.phpfr_RE.phpfr_RW.phpfr_SC.phpfr_SN.phpfr_SY.phpfr_TD.phpfr_TG.phpfr_TN.phpfr_VU.phpfr_WF.phpfr_YT.phpfur.phpfur_IT.phpfy.phpfy_DE.phpfy_NL.phpga.phpga_IE.phpgd.phpgd_GB.phpgez.phpgez_ER.phpgez_ET.phpgl.phpgl_ES.phpgom.phpgom_Latn.phpgsw.phpgsw_CH.phpgsw_FR.phpgsw_LI.phpgu.phpgu_IN.phpguz.phpgv.phpgv_GB.phpha.phpha_GH.phpha_NE.phpha_NG.phphak.phphak_TW.phphaw.phphe.phphe_IL.phphi.phphi_IN.phphif.phphif_FJ.phphne.phphne_IN.phphr.phphr_BA.phphr_HR.phphsb.phphsb_DE.phpht.phpht_HT.phphu.phphu_HU.phphy.phphy_AM.phpi18n.phpia.phpia_FR.phpid.phpid_ID.phpig.phpig_NG.phpii.phpik.phpik_CA.phpin.phpis.phpis_IS.phpit.phpit_CH.phpit_IT.phpit_SM.phpit_VA.phpiu.phpiu_CA.phpiw.phpja.phpja_JP.phpjgo.phpjmc.phpjv.phpka.phpka_GE.phpkab.phpkab_DZ.phpkam.phpkde.phpkea.phpkhq.phpki.phpkk.phpkk_KZ.phpkkj.phpkl.phpkl_GL.phpkln.phpkm.phpkm_KH.phpkn.phpkn_IN.phpko.phpko_KP.phpko_KR.phpkok.phpkok_IN.phpks.phpks_IN.phpks_IN@devanagari.phpksb.phpksf.phpksh.phpku.phpku_TR.phpkw.phpkw_GB.phpky.phpky_KG.phplag.phplb.phplb_LU.phplg.phplg_UG.phpli.phpli_NL.phplij.phplij_IT.phplkt.phpln.phpln_AO.phpln_CD.phpln_CF.phpln_CG.phplo.phplo_LA.phplrc.phplrc_IQ.phplt.phplt_LT.phplu.phpluo.phpluy.phplv.phplv_LV.phplzh.phplzh_TW.phpmag.phpmag_IN.phpmai.phpmai_IN.phpmas.phpmas_TZ.phpmer.phpmfe.phpmfe_MU.phpmg.phpmg_MG.phpmgh.phpmgo.phpmhr.phpmhr_RU.phpmi.phpmi_NZ.phpmiq.phpmiq_NI.phpmjw.phpmjw_IN.phpmk.phpmk_MK.phpml.phpml_IN.phpmn.phpmn_MN.phpmni.phpmni_IN.phpmo.phpmr.phpmr_IN.phpms.phpms_BN.phpms_MY.phpms_SG.phpmt.phpmt_MT.phpmua.phpmy.phpmy_MM.phpmzn.phpnan.phpnan_TW.phpnan_TW@latin.phpnaq.phpnb.phpnb_NO.phpnb_SJ.phpnd.phpnds.phpnds_DE.phpnds_NL.phpne.phpne_IN.phpne_NP.phpnhn.phpnhn_MX.phpniu.phpniu_NU.phpnl.phpnl_AW.phpnl_BE.phpnl_BQ.phpnl_CW.phpnl_NL.phpnl_SR.phpnl_SX.phpnmg.phpnn.phpnn_NO.phpnnh.phpno.phpnr.phpnr_ZA.phpnso.phpnso_ZA.phpnus.phpnyn.phpoc.phpoc_FR.phpom.phpom_ET.phpom_KE.phpor.phpor_IN.phpos.phpos_RU.phppa.phppa_Arab.phppa_Guru.phppa_IN.phppa_PK.phppap.phppap_AW.phppap_CW.phppl.phppl_PL.phpprg.phpps.phpps_AF.phppt.phppt_AO.phppt_BR.phppt_CH.phppt_CV.phppt_GQ.phppt_GW.phppt_LU.phppt_MO.phppt_MZ.phppt_PT.phppt_ST.phppt_TL.phpqu.phpqu_BO.phpqu_EC.phpquz.phpquz_PE.phpraj.phpraj_IN.phprm.phprn.phpro.phpro_MD.phpro_RO.phprof.phpru.phpru_BY.phpru_KG.phpru_KZ.phpru_MD.phpru_RU.phpru_UA.phprw.phprw_RW.phprwk.phpsa.phpsa_IN.phpsah.phpsah_RU.phpsaq.phpsat.phpsat_IN.phpsbp.phpsc.phpsc_IT.phpsd.phpsd_IN.phpsd_IN@devanagari.phpse.phpse_FI.phpse_NO.phpse_SE.phpseh.phpses.phpsg.phpsgs.phpsgs_LT.phpsh.phpshi.phpshi_Latn.phpshi_Tfng.phpshn.phpshn_MM.phpshs.phpshs_CA.phpsi.phpsi_LK.phpsid.phpsid_ET.phpsk.phpsk_SK.phpsl.phpsl_SI.phpsm.phpsm_WS.phpsmn.phpsn.phpso.phpso_DJ.phpso_ET.phpso_KE.phpso_SO.phpsq.phpsq_AL.phpsq_MK.phpsq_XK.phpsr.phpsr_Cyrl.phpsr_Cyrl_BA.phpsr_Cyrl_ME.phpsr_Cyrl_XK.phpsr_Latn.phpsr_Latn_BA.phpsr_Latn_ME.phpsr_Latn_XK.phpsr_ME.phpsr_RS.phpsr_RS@latin.phpss.phpss_ZA.phpst.phpst_ZA.phpsv.phpsv_AX.phpsv_FI.phpsv_SE.phpsw.phpsw_CD.phpsw_KE.phpsw_TZ.phpsw_UG.phpszl.phpszl_PL.phpta.phpta_IN.phpta_LK.phpta_MY.phpta_SG.phptcy.phptcy_IN.phpte.phpte_IN.phpteo.phpteo_KE.phptet.phptg.phptg_TJ.phpth.phpth_TH.phpthe.phpthe_NP.phpti.phpti_ER.phpti_ET.phptig.phptig_ER.phptk.phptk_TM.phptl.phptl_PH.phptlh.phptn.phptn_ZA.phpto.phpto_TO.phptpi.phptpi_PG.phptr.phptr_CY.phptr_TR.phpts.phpts_ZA.phptt.phptt_RU.phptt_RU@iqtelif.phptwq.phptzl.phptzm.phptzm_Latn.phpug.phpug_CN.phpuk.phpuk_UA.phpunm.phpunm_US.phpur.phpur_IN.phpur_PK.phpuz.phpuz_Arab.phpuz_Cyrl.phpuz_Latn.phpuz_UZ.phpuz_UZ@cyrillic.phpvai.phpvai_Latn.phpvai_Vaii.phpve.phpve_ZA.phpvi.phpvi_VN.phpvo.phpvun.phpwa.phpwa_BE.phpwae.phpwae_CH.phpwal.phpwal_ET.phpwo.phpwo_SN.phpxh.phpxh_ZA.phpxog.phpyav.phpyi.phpyi_US.phpyo.phpyo_BJ.phpyo_NG.phpyue.phpyue_HK.phpyue_Hans.phpyue_Hant.phpyuw.phpyuw_PG.phpzgh.phpzh.phpzh_CN.phpzh_HK.phpzh_Hans.phpzh_Hans_HK.phpzh_Hans_MO.phpzh_Hans_SG.phpzh_Hant.phpzh_Hant_HK.phpzh_Hant_MO.phpzh_Hant_TW.phpzh_MO.phpzh_SG.phpzh_TW.phpzh_YUE.phpzu.phpzu_ZA.php
Laravel
List
MessageFormatter
PHPStan
Traits
Translator.phpTranslatorImmutable.phpTranslatorStrongTypeInterface.php
nyholm
pablo-sg-pacheco
paragonie
phpdocumentor
reflection-common
reflection-docblock
type-resolver
phpseclib
bcmath_compat
phpseclib
AUTHORS
phpseclib
Common
Functions
Crypt
AES.phpBlowfish.phpChaCha20.php
Common
DES.phpDH.php
DH
DSA.php
DSA
EC.php
EC
Hash.phpPublicKeyLoader.phpRC2.phpRC4.phpRSA.php
RSA
Random.phpRijndael.phpSalsa20.phpTripleDES.phpTwofish.php
Exception
File
ANSI.phpASN1.php
ASN1
Element.php
Maps
AccessDescription.phpAdministrationDomainName.phpAlgorithmIdentifier.phpAnotherName.phpAttribute.phpAttributeType.phpAttributeTypeAndValue.phpAttributeValue.phpAttributes.phpAuthorityInfoAccessSyntax.phpAuthorityKeyIdentifier.phpBaseDistance.phpBasicConstraints.phpBuiltInDomainDefinedAttribute.phpBuiltInDomainDefinedAttributes.phpBuiltInStandardAttributes.phpCPSuri.phpCRLDistributionPoints.phpCRLNumber.phpCRLReason.phpCertPolicyId.phpCertificate.phpCertificateIssuer.phpCertificateList.phpCertificatePolicies.phpCertificateSerialNumber.phpCertificationRequest.phpCertificationRequestInfo.phpCharacteristic_two.phpCountryName.phpCurve.phpDHParameter.phpDSAParams.phpDSAPrivateKey.phpDSAPublicKey.phpDigestInfo.phpDirectoryString.phpDisplayText.phpDistributionPoint.phpDistributionPointName.phpDssSigValue.phpECParameters.phpECPoint.phpECPrivateKey.phpEDIPartyName.phpEcdsaSigValue.phpEncryptedData.phpEncryptedPrivateKeyInfo.phpExtKeyUsageSyntax.phpExtension.phpExtensionAttribute.phpExtensionAttributes.phpExtensions.phpFieldElement.phpFieldID.phpGeneralName.phpGeneralNames.phpGeneralSubtree.phpGeneralSubtrees.phpHashAlgorithm.phpHoldInstructionCode.phpInvalidityDate.phpIssuerAltName.phpIssuingDistributionPoint.phpKeyIdentifier.phpKeyPurposeId.phpKeyUsage.phpMaskGenAlgorithm.phpName.phpNameConstraints.phpNetworkAddress.phpNoticeReference.phpNumericUserIdentifier.phpORAddress.phpOneAsymmetricKey.phpOrganizationName.phpOrganizationalUnitNames.phpOtherPrimeInfo.phpOtherPrimeInfos.phpPBEParameter.phpPBES2params.phpPBKDF2params.phpPBMAC1params.phpPKCS9String.phpPentanomial.phpPersonalName.phpPolicyInformation.phpPolicyMappings.phpPolicyQualifierId.phpPolicyQualifierInfo.phpPostalAddress.phpPrime_p.phpPrivateDomainName.phpPrivateKey.phpPrivateKeyInfo.phpPrivateKeyUsagePeriod.phpPublicKey.phpPublicKeyAndChallenge.phpPublicKeyInfo.phpRC2CBCParameter.phpRDNSequence.phpRSAPrivateKey.phpRSAPublicKey.phpRSASSA_PSS_params.phpReasonFlags.phpRelativeDistinguishedName.phpRevokedCertificate.phpSignedPublicKeyAndChallenge.phpSpecifiedECDomain.phpSubjectAltName.phpSubjectDirectoryAttributes.phpSubjectInfoAccessSyntax.phpSubjectPublicKeyInfo.phpTBSCertList.phpTBSCertificate.phpTerminalIdentifier.phpTime.phpTrinomial.phpUniqueIdentifier.phpUserNotice.phpValidity.phpnetscape_ca_policy_url.phpnetscape_cert_type.phpnetscape_comment.php
X509.php
Math
Net
System
bootstrap.phpopenssl.cnf
phpstan
phpdoc-parser
phpstan-baseline.neon
src
Ast
AbstractNodeVisitor.phpAttribute.php
ConstExpr
Node.phpNodeAttributes.phpNodeTraverser.phpNodeVisitor.php
NodeVisitor
PhpDoc
Type
Lexer
Parser
Printer
psr
rakit
ralouphie
getallheaders
remotelyliving
rpnzl
scoper-autoload.php
scssphp
setasign
spatie
stripe
stripe-php
OPENAPI_VERSIONVERSION
data
init.php
lib
Account.phpAccountLink.php
ApiOperations
ApiRequestor.phpApiResource.phpApiResponse.phpApplePayDomain.phpApplicationFee.phpApplicationFeeRefund.php
Apps
Balance.phpBalanceTransaction.phpBankAccount.phpBaseStripeClient.phpBaseStripeClientInterface.php
BillingPortal
Capability.phpCard.phpCashBalance.phpCharge.php
Checkout
Collection.phpCountrySpec.phpCoupon.phpCreditNote.phpCreditNoteLineItem.phpCustomer.phpCustomerBalanceTransaction.phpCustomerCashBalanceTransaction.phpDiscount.phpDispute.phpEphemeralKey.phpErrorObject.phpEvent.php
Exception
ExchangeRate.phpFile.phpFileLink.php
FinancialConnections
FundingInstructions.php
HttpClient
Identity
Invoice.phpInvoiceItem.phpInvoiceLineItem.php
Issuing
LineItem.phpLoginLink.phpMandate.phpOAuth.phpOAuthErrorObject.phpPaymentIntent.phpPaymentLink.phpPaymentMethod.phpPayout.phpPerson.phpPlan.phpPrice.phpProduct.phpPromotionCode.phpQuote.php
Radar
RecipientTransfer.phpRefund.php
Reporting
RequestTelemetry.phpReview.phpSearchResult.php
Service
AbstractService.phpAbstractServiceFactory.phpAccountLinkService.phpAccountService.phpApplePayDomainService.phpApplicationFeeService.php
Apps
BalanceService.phpBalanceTransactionService.php
BillingPortal
ChargeService.php
Checkout
CoreServiceFactory.phpCountrySpecService.phpCouponService.phpCreditNoteService.phpCustomerService.phpDisputeService.phpEphemeralKeyService.phpEventService.phpExchangeRateService.phpFileLinkService.phpFileService.php
FinancialConnections
Identity
InvoiceItemService.phpInvoiceService.php
Issuing
MandateService.phpOAuthService.phpPaymentIntentService.phpPaymentLinkService.phpPaymentMethodService.phpPayoutService.phpPlanService.phpPriceService.phpProductService.phpPromotionCodeService.phpQuoteService.php
Radar
RefundService.php
Reporting
ReviewService.phpSetupAttemptService.phpSetupIntentService.phpShippingRateService.php
Sigma
SourceService.phpSubscriptionItemService.phpSubscriptionScheduleService.phpSubscriptionService.php
Tax
TaxCodeService.phpTaxRateService.php
Terminal
TestHelpers
TokenService.phpTopupService.phpTransferService.php
Treasury
WebhookEndpointService.php
SetupAttempt.phpSetupIntent.phpShippingRate.php
Sigma
SingletonApiResource.phpSource.phpSourceTransaction.phpStripe.phpStripeClient.phpStripeClientInterface.phpStripeObject.phpStripeStreamingClientInterface.phpSubscription.phpSubscriptionItem.phpSubscriptionSchedule.php
Tax
TaxCode.phpTaxId.phpTaxRate.php
Terminal
TestHelpers
Token.phpTopup.phpTransfer.phpTransferReversal.php
Treasury
UsageRecord.phpUsageRecordSummary.php
Util
Webhook.phpWebhookEndpoint.phpWebhookSignature.php
symfony
cache-contracts
cache
deprecation-contracts
event-dispatcher-contracts
event-dispatcher
polyfill-mbstring
polyfill-php73
polyfill-php80
polyfill-php81
process
service-contracts
translation-contracts
translation
Catalogue
CatalogueMetadataAwareInterface.php
Command
DataCollector
DataCollectorTranslator.php
DependencyInjection
Dumper
Exception
Extractor
Formatter
IdentityTranslator.php
Loader
LocaleSwitcher.phpLoggingTranslator.phpMessageCatalogue.phpMessageCatalogueInterface.phpMetadataAwareInterface.php
Provider
PseudoLocalizationTranslator.php
Reader
Resources
Test
TranslatableMessage.phpTranslator.phpTranslatorBag.phpTranslatorBagInterface.php
Util
Writer
var-exporter
webmozart
woocommerce
action-scheduler
action-scheduler.php
classes
ActionScheduler_ActionClaim.phpActionScheduler_ActionFactory.phpActionScheduler_AdminView.phpActionScheduler_AsyncRequest_QueueRunner.phpActionScheduler_Compatibility.phpActionScheduler_DataController.phpActionScheduler_DateTime.phpActionScheduler_Exception.phpActionScheduler_FatalErrorMonitor.phpActionScheduler_InvalidActionException.phpActionScheduler_ListTable.phpActionScheduler_LogEntry.phpActionScheduler_NullLogEntry.phpActionScheduler_OptionLock.phpActionScheduler_QueueCleaner.phpActionScheduler_QueueRunner.phpActionScheduler_Versions.phpActionScheduler_WPCommentCleaner.phpActionScheduler_wcSystemStatus.php
WP_CLI
abstracts
actions
data-stores
migration
schedules
schema
deprecated
functions.php
lib
yahnis-elsts
inc
admin-pages
class-about-admin-page.phpclass-addons-admin-page.phpclass-base-admin-page.phpclass-base-customer-facing-admin-page.phpclass-broadcast-edit-admin-page.phpclass-broadcast-list-admin-page.phpclass-checkout-form-edit-admin-page.phpclass-checkout-form-list-admin-page.phpclass-customer-edit-admin-page.phpclass-customer-list-admin-page.phpclass-customizer-admin-page.phpclass-dashboard-admin-page.phpclass-discount-code-edit-admin-page.phpclass-discount-code-list-admin-page.phpclass-domain-edit-admin-page.phpclass-domain-list-admin-page.phpclass-edit-admin-page.phpclass-email-edit-admin-page.phpclass-email-list-admin-page.phpclass-email-template-customize-admin-page.phpclass-event-list-admin-page.phpclass-event-view-admin-page.phpclass-hosting-integration-wizard-admin-page.phpclass-invoice-template-customize-admin-page.phpclass-jobs-list-admin-page.phpclass-list-admin-page.phpclass-membership-edit-admin-page.phpclass-membership-list-admin-page.phpclass-migration-alert-admin-page.phpclass-payment-edit-admin-page.phpclass-payment-list-admin-page.phpclass-placeholders-admin-page.phpclass-product-edit-admin-page.phpclass-product-list-admin-page.phpclass-rollback-admin-page.phpclass-settings-admin-page.phpclass-setup-wizard-admin-page.phpclass-shortcodes-admin-page.phpclass-site-edit-admin-page.phpclass-site-list-admin-page.phpclass-system-info-admin-page.phpclass-tax-rates-admin-page.phpclass-template-previewer-customize-admin-page.phpclass-top-admin-nav-menu.phpclass-view-logs-admin-page.phpclass-webhook-edit-admin-page.phpclass-webhook-list-admin-page.phpclass-wizard-admin-page.php
customer-panel
debug
api
builders
checkout
class-cart.phpclass-checkout-pages.phpclass-checkout.phpclass-legacy-checkout.phpclass-line-item.php
signup-fields
class-admin-notices.phpclass-admin-themes-compatibility.phpclass-ajax.phpclass-api.phpclass-async-calls.phpclass-autoloader.phpclass-core-updates.phpclass-cron.phpclass-current.phpclass-dashboard-statistics.phpclass-dashboard-widgets.phpclass-documentation.phpclass-domain-mapping.phpclass-faker.phpclass-geolocation.phpclass-helper.phpclass-hooks.phpclass-license.phpclass-light-ajax.phpclass-logger.phpclass-maintenance-mode.phpclass-requirements.phpclass-scripts.phpclass-session-cookie.phpclass-settings.phpclass-sunrise.phpclass-unsupported.phpclass-user-switching.phpclass-views.phpclass-whitelabel.phpclass-wp-ultimo.php
compat
contracts
country
br
ca
class-country-br.phpclass-country-ca.phpclass-country-cn.phpclass-country-de.phpclass-country-default.phpclass-country-es.phpclass-country-fr.phpclass-country-gb.phpclass-country-in.phpclass-country-jp.phpclass-country-mx.phpclass-country-my.phpclass-country-ne.phpclass-country-nl.phpclass-country-ru.phpclass-country-sg.phpclass-country-tr.phpclass-country-us.phpclass-country-za.phpclass-country.php
cn
de
es
fr
gb
in
jp
mx
my
ne
nl
ru
sg
tr
us
za
database
debug
deprecated
development
domain-mapping
duplication
exception
functions
gateways
helpers
installers
integrations
internal
invoices
limitations
limits
list-tables
loaders
managers
mercator
models
next
objects
rollback
site-templates
sso
tax
traits
ui
updater
lang
loco.xmlreadme.txtsunrise.phpuninstall.php
views
about.phpadmin-notices.php
admin-pages
base
broadcast
checkout
classes.php
customers
dashboard-statistics
dashboard-widgets
domain
dynamic-styles
email
emails
events
invoice
legacy
limitations
memberships
payments
phpcs.xml
rollback
settings
shortcodes
sites
system-info
taxes
ui
wizards
wp-multisite-waas.php

2995
inc/checkout/class-cart.php Normal file

File diff suppressed because it is too large Load Diff

@@ -0,0 +1,750 @@
<?php
/**
* Handles registration pages and such.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Handles registration pages and such.
*
* @since 2.0.0
*/
class Checkout_Pages {
use \WP_Ultimo\Traits\Singleton;
/**
* Initializes the Checkout_Pages singleton and adds hooks.
*
* @since 2.0.0
* @return void
*/
public function init() {
add_filter('display_post_states', array($this, 'add_wp_ultimo_status_annotation'), 10, 2);
add_action('wu_thank_you_site_block', array($this, 'add_verify_email_notice'), 10, 3);
add_shortcode('wu_confirmation', array($this, 'render_confirmation_page'));
add_filter('lostpassword_redirect', array($this, 'filter_lost_password_redirect'));
if (is_main_site()) {
add_action('before_signup_header', array($this, 'redirect_to_registration_page'));
$use_custom_login = wu_get_setting('enable_custom_login_page', false);
if (!$use_custom_login) {
return;
} // end if;
add_filter('login_url', array($this, 'filter_login_url'), 10, 3);
add_filter('lostpassword_url', array($this, 'filter_login_url'), 10, 3);
add_filter('retrieve_password_message', array($this, 'replace_reset_password_link'), 10, 4);
add_filter('network_site_url', array($this, 'maybe_change_wp_login_on_urls'));
add_action('login_init', array($this, 'maybe_obfuscate_login_url'), 9);
add_action('template_redirect', array($this, 'maybe_redirect_to_admin_panel'));
add_action('after_password_reset', array($this, 'maybe_redirect_to_confirm_screen'));
add_action('lost_password', array($this, 'maybe_handle_password_reset_errors'));
add_action('validate_password_reset', array($this, 'maybe_handle_password_reset_errors'));
/**
* Adds the force elements controls.
*/
add_action('post_submitbox_misc_actions', array($this, 'render_compat_mode_setting'));
add_action('save_post', array($this, 'handle_compat_mode_setting'));
} // end if;
} // end init;
/**
* Filters the lost password redirect URL.
*
* @param string $redirect_to The redirect URL.
*/
public function filter_lost_password_redirect(string $redirect_to): string {
if (!empty($redirect_to)) {
return $redirect_to;
} // end if;
$redirect_to = add_query_arg('checkemail', 'confirm', wp_login_url());
return $redirect_to;
} // end filter_lost_password_redirect;
/**
* Renders the compat mode option for pages and posts.
*
* @since 2.0.0
* @return void
*/
public function render_compat_mode_setting() {
$post_id = get_the_ID();
$value = get_post_meta($post_id, '_wu_force_elements_loading', true);
wp_nonce_field('_wu_force_compat_' . $post_id, '_wu_force_compat');
// phpcs:disable
?>
<div class="misc-pub-section misc-pub-section-last" style="margin-top: 12px; margin-bottom: 6px; display: flex; align-items: center;">
<label for="wu-compat-mode">
<span style="display: block; font-weight: 600; margin-bottom: 3px;"><?php _e('WP Ultimo Compatibility Mode', 'wp-ultimo'); ?></span>
<small style="display: block; line-height: 1.8em;"><?php _e('Toggle this option on if WP Ultimo elements are not loading correctly or at all.', 'wp-ultimo'); ?></small>
</label>
<div style="margin-left: 6px;">
<input id="wu-compat-mode" type="checkbox" value="1" <?php checked($value, true, true); ?> name="_wu_force_elements_loading" />
</div>
</div>
<?php
// phpcs:enable
} // end render_compat_mode_setting;
/**
* Handles saving the compat mode switch on posts.
*
* @since 2.0.0
*
* @param int $post_id The id of the post being saved.
* @return void
*/
public function handle_compat_mode_setting($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
} // end if;
if (!isset($_POST['_wu_force_compat']) || !wp_verify_nonce($_POST['_wu_force_compat'], '_wu_force_compat_' . $post_id)) {
return;
} // end if;
if (!current_user_can('edit_post', $post_id)) {
return;
} // end if;
if (isset($_POST['_wu_force_elements_loading'])) {
update_post_meta($post_id, '_wu_force_elements_loading', $_POST['_wu_force_elements_loading']);
} else {
delete_post_meta($post_id, '_wu_force_elements_loading');
} // end if;
} // end handle_compat_mode_setting;
/**
* Replace wp-login.php in email URLs.
*
* @since 2.0.0
*
* @param string $url The URL to filter.
* @return string
*/
public function maybe_change_wp_login_on_urls($url) {
/*
* Only perform computational-heavy tasks if the URL has
* wp-login.php in it to begin with.
*/
if (strpos($url, 'wp-login.php') === false) {
return $url;
} // end if;
$post_id = wu_get_setting('default_login_page', 0);
$post = get_post($post_id);
if ($post) {
$url = str_replace('wp-login.php', $post->post_name, $url);
} // end if;
return $url;
} // end maybe_change_wp_login_on_urls;
/**
* Get an error message.
*
* @since 2.0.0
*
* @param string $error_code The error code.
* @param string $username The username.
* @return string
*/
public function get_error_message($error_code, $username = '') {
$messages = array(
'incorrect_password' => sprintf(__( '<strong>Error:</strong> The password you entered is incorrect.', 'wp-ultimo')),
// From here we are using the same messages as WordPress core.
'expired' => __('Your session has expired. Please log in to continue where you left off.'),
'confirm' => sprintf(__('Check your email for the confirmation link, then visit the <a href="%s">login page</a>.'), wp_login_url()),
'registered' => sprintf(__( 'Registration complete. Please check your email, then visit the <a href="%s">login page</a>.' ), wp_login_url()),
'loggedout' => __('You are now logged out.'),
'registerdisabled' => __('<strong>Error:</strong> User registration is currently not allowed.'),
'empty_username' => __('<strong>Error:</strong> The username field is empty.'),
'empty_password' => __('<strong>Error:</strong> The password field is empty.'),
'invalid_email' => __('Unknown email address. Check again or try your username.'),
'invalid_username' => sprintf(__('<strong>Error:</strong> The username <strong>%s</strong> is not registered on this site. If you are unsure of your username, try your email address instead.'), $username),
'invalidcombo' => __('<strong>Error:</strong> There is no account with that username or email address.'),
'password_reset_empty_space' => __('The password cannot be a space or all spaces.'),
'password_reset_mismatch' => __('<strong>Error:</strong> The passwords do not match.'),
'invalidkey' => __('<strong>Error:</strong> Your password reset link appears to be invalid. Please request a new link below.'),
'expiredkey' => __('<strong>Error:</strong> Your password reset link has expired. Please request a new link below.'),
);
/**
* Filter the error messages.
*
* @since 2.1.1
* @param array $messages The error messages.
* @return array
*/
$messages = apply_filters('wu_checkout_pages_error_messages', $messages);
return wu_get_isset($messages, $error_code, __('Something went wrong', 'wp-ultimo'));
} // end get_error_message;
/**
* Handle password reset errors.
*
* We redirect users to our custom login URL,
* so we can add an error message.
*
* @since 2.0.0
*
* @param \WP_Error $errors The error object.
* @return void
*/
public function maybe_handle_password_reset_errors($errors) {
if ($errors->has_errors()) {
$url = add_query_arg(array(
'action' => wu_request('action', ''),
'user_login' => wu_request('user_login', ''),
'error' => $errors->get_error_code(),
), wp_login_url());
wp_redirect($url);
exit;
} // end if;
} // end maybe_handle_password_reset_errors;
/**
* Maybe redirects users to the confirm screen.
*
* If we are successful in resetting a password,
* we need to prevent the user from reaching the empty
* wp-login.php message, so we redirect them to the passed
* redirect_to query argument.
*
* @since 2.0.0
* @return void
*/
public function maybe_redirect_to_confirm_screen() {
if (wu_request('redirect_to')) {
wp_redirect(wu_request('redirect_to'));
exit;
} // end if;
} // end maybe_redirect_to_confirm_screen;
/**
* Replace the reset password link, if necessary.
*
* @since 2.0.0
*
* @param string $message The email message.
* @param string $key The reset key.
* @param string $user_login The user login.
* @param array $user_data The user data array.
* @return string
*/
public function replace_reset_password_link($message, $key, $user_login, $user_data) {
if (!is_main_site()) {
return $message;
} // end if;
$results = array();
preg_match_all('/.*\/wp-login\.php.*/', $message, $results);
$switched_locale = false;
if (isset($results[0][0])) {
// Localize password reset message content for user.
$locale = get_user_locale($user_data);
$switched_locale = switch_to_locale($locale);
$new_url = add_query_arg(array(
'action' => 'rp',
'key' => $key,
'login' => rawurlencode($user_login),
'wp_lang' => $locale
), wp_login_url());
$new_url = set_url_scheme($new_url, null);
$message = str_replace($results[0], $new_url, $message);
} // end if;
if ($switched_locale) {
restore_previous_locale();
} // end if;
return $message;
} // end replace_reset_password_link;
/**
* Redirect logged users when they reach the login page.
*
* @since 2.0.0
* @return void
*/
public function maybe_redirect_to_admin_panel() {
global $post;
if (!is_user_logged_in()) {
return;
} // end if;
$custom_login_page = $this->get_signup_page('login');
if (empty($custom_login_page) || empty($post)) {
return;
} // end if;
if ($custom_login_page->ID !== $post->ID) {
return;
} // end if;
/**
* Create an exclusion list of parameters that prevent the auto-redirect.
*
* This is needed because otherwise page builder won't be able to
* edit the login page once it is defined.
*
* @since 2.0.4
* @return array
*/
$exclusion_list = apply_filters('wu_maybe_redirect_to_admin_panel_exclusion_list', array(
'preview', // WordPress Preview
'ct_builder', // Oxygen Builder
'fl_builder', // Beaver Builder
'elementor-preview', // Elementor
'brizy-edit', // Brizy
'brizy-edit-iframe', // Brizy
), $custom_login_page, $post, $this);
foreach ($exclusion_list as $exclusion_param) {
if (wu_request($exclusion_param, null) !== null) {
return;
} // end if;
} // end foreach;
$user = wp_get_current_user();
$active_blog = get_active_blog_for_user($user->ID);
$redirect_to = $active_blog ? get_admin_url($active_blog->blog_id) : false;
if (isset($_GET['redirect_to'])) {
$redirect_to = $_GET['redirect_to'];
} elseif (is_multisite() && !get_active_blog_for_user($user->ID) && !is_super_admin($user->ID)) {
$redirect_to = user_admin_url();
} elseif (is_multisite() && !$user->has_cap('read')) {
$redirect_to = get_dashboard_url($user->ID);
} elseif (!$user->has_cap('edit_posts')) {
$redirect_to = $user->has_cap('read') ? admin_url('profile.php') : home_url();
} // end if;
if (!$redirect_to) {
return;
} // end if;
wp_redirect($redirect_to);
exit;
} // end maybe_redirect_to_admin_panel;
/**
* Adds the unverified email account error message.
*
* @since 2.0.0
*
* @param \WP_Ultimo\Models\Payment $payment The current payment.
* @param \WP_Ultimo\Models\Membership $membership the current membership.
* @param \WP_Ultimo\Models\Customer $customer the current customer.
* @return void
*/
public function add_verify_email_notice($payment, $membership, $customer) {
if ($payment->get_total() == 0 && $customer->get_email_verification() === 'pending') {
$html = '<div class="wu-p-4 wu-bg-yellow-200 wu-mb-2 wu-text-yellow-700 wu-rounded">%s</div>';
$message = __('Your email address is not yet verified. Your site <strong>will only be activated</strong> after your email address is verified. Check your inbox and verify your email address.', 'wp-ultimo');
$message .= sprintf('<br><a href="#" class="wu-resend-verification-email wu-text-gray-700">%s</a>', __('Resend verification email &rarr;', 'wp-ultimo'));
printf($html, $message);
} // end if;
} // end add_verify_email_notice;
/**
* Check if we should obfuscate the login URL.
*
* @since 2.0.0
* @return void
*/
public function maybe_obfuscate_login_url() {
$use_custom_login = wu_get_setting('enable_custom_login_page', false);
if (!$use_custom_login) {
return;
} // end if;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
return;
} // end if;
if (wu_request('interim-login')) {
return;
} // end if;
if (wu_request('action') === 'logout') {
return;
} // end if;
$new_login_url = $this->get_page_url('login');
if (!$new_login_url) {
return;
} // end if;
$should_obfuscate = wu_get_setting('obfuscate_original_login_url', 1);
$bypass_obfuscation = wu_request('wu_bypass_obfuscation');
if ($should_obfuscate && !$bypass_obfuscation) {
status_header(404);
nocache_headers();
global $wp_query;
$wp_query->set_404();
include(get_404_template());
die;
} else {
wp_redirect($new_login_url);
exit;
} // end if;
} // end maybe_obfuscate_login_url;
/**
* Redirects the customers to the registration page, when one is used.
*
* @since 2.0.0
* @return void
*/
public function redirect_to_registration_page() {
$registration_url = $this->get_page_url('register');
if ($registration_url) {
wp_redirect($registration_url);
exit;
} // end if;
} // end redirect_to_registration_page;
/**
* Filters the login URL if necessary.
*
* @since 2.0.0
*
* @param string $login_url Original login URL.
* @param string $redirect URL to redirect to after login.
* @param bool $force_reauth If we need to force reauth.
* @return string
*/
public function filter_login_url($login_url, $redirect, $force_reauth = false) {
/**
* Fix incompatibility with UIPress, making sure we only filter after wp_loaded ran.
*/
if (!did_action('wp_loaded')) {
return $login_url;
} // end if;
$function_caller = wu_get_function_caller(5);
if ($function_caller === 'wp_auth_check_html') {
return $login_url;
} // end if;
$params = array();
$old_url_params = wp_parse_url($login_url, PHP_URL_QUERY);
wp_parse_str($old_url_params, $params);
$new_login_url = $this->get_page_url('login');
if (!$new_login_url) {
return $login_url;
} // end if;
if ($params) {
$new_login_url = add_query_arg($params, $new_login_url);
} // end if;
if ($redirect) {
$new_login_url = add_query_arg('redirect_to', urlencode( $redirect ), $new_login_url);
} // end if;
if ($force_reauth) {
$new_login_url = add_query_arg('reauth', 1, $new_login_url);
} // end if;
return $new_login_url;
} // end filter_login_url;
/**
* Returns the ID of the pages being used for each WP Ultimo purpose.
*
* @since 2.0.0
* @return array
*/
public function get_signup_pages() {
return array(
'register' => wu_guess_registration_page(),
'update' => wu_get_setting('default_update_page', false),
'login' => wu_get_setting('default_login_page', false),
'block_frontend' => wu_get_setting('default_block_frontend_page', false),
'new_site' => wu_get_setting('default_new_site_page', false),
);
} // end get_signup_pages;
/**
* Returns the WP_Post object for one of the pages.
*
* @since 2.0.0
*
* @param string $page The slug of the page to retrieve.
* @return \WP_Post|false
*/
public function get_signup_page($page) {
$pages = $this->get_signup_pages();
$page_id = wu_get_isset($pages, $page);
if (!$page_id) {
return false;
} // end if;
return get_blog_post(wu_get_main_site_id(), $page_id);
} // end get_signup_page;
/**
* Returns the URL for a particular page type.
*
* @since 2.0.0
*
* @param string $page_slug The signup page to get.
* @return string|false
*/
public function get_page_url($page_slug = 'login') {
$page = $this->get_signup_page($page_slug);
if (!$page) {
return false;
} // end if;
return wu_switch_blog_and_run(fn() => get_the_permalink($page));
} // end get_page_url;
/**
* Tags the WP Ultimo pages on the main site.
*
* @since 2.0.0
*
* @param array $states The previous states of that page.
* @param \WP_Post $post The current post.
* @return array
*/
public function add_wp_ultimo_status_annotation($states, $post) {
if (!is_main_site()) {
return $states;
} // end if;
$labels = array(
'register' => __('WP Ultimo - Register Page', 'wp-ultimo'),
'login' => __('WP Ultimo - Login Page', 'wp-ultimo'),
'block_frontend' => __('WP Ultimo - Site Blocked Page', 'wp-ultimo'),
'update' => __('WP Ultimo - Membership Update Page', 'wp-ultimo'),
'new_site' => __('WP Ultimo - New Site Page', 'wp-ultimo'),
);
$pages = array_map('absint', $this->get_signup_pages());
if (in_array($post->ID, $pages, true)) {
$key = array_search($post->ID, $pages, true);
$states['wp_ultimo_page'] = wu_get_isset($labels, $key);
} // end if;
return $states;
} // end add_wp_ultimo_status_annotation;
/**
* Renders the confirmation page.
*
* @since 2.0.0
*
* @param array $atts Shortcode attributes.
* @param null|string $content The post content.
* @return string
*/
public function render_confirmation_page($atts, $content = null) {
return wu_get_template_contents('checkout/confirmation', array(
'errors' => Checkout::get_instance()->errors,
'membership' => wu_get_membership_by_hash(wu_request('membership')),
));
} // end render_confirmation_page;
} // end class Checkout_Pages;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@@ -0,0 +1,614 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
abstract class Base_Signup_Field {
/**
* Holds the field attributes.
*
* @since 2.0.0
* @var array
*/
protected $attributes;
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
abstract public function get_type();
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
abstract public function is_required();
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
abstract public function get_title();
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
abstract public function get_description();
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
abstract function get_tooltip();
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
abstract public function get_icon();
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
abstract public function get_fields();
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
abstract public function to_fields_array($attributes);
/**
* Set's if a field should not be available on the form creation.
*
* @since 2.0.0
* @return boolean
*/
public function is_hidden() {
return false;
} // end is_hidden;
/**
* Defines if this field/element is related to site creation or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_site_field() {
return false;
} // end is_site_field;
/**
* Defines if this field/element is related to user/customer creation or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return false;
} // end is_user_field;
/**
* Returns the field as an array that the form builder can understand.
*
* @since 2.0.0
* @return array
*/
public function get_field_as_type_option() {
return array(
'title' => $this->get_title(),
'desc' => $this->get_description(),
'tooltip' => $this->get_tooltip(),
'type' => $this->get_type(),
'icon' => $this->get_icon(),
'required' => $this->is_required(),
'default_fields' => $this->default_fields(),
'force_attributes' => $this->force_attributes(),
'all_attributes' => $this->get_all_attributes(),
'fields' => array($this, 'get_editor_fields'),
);
} // end get_field_as_type_option;
/**
* Modifies the HTML attr array before sending it over to the form.
*
* @since 2.0.0
*
* @param array $html_attr The current attributes.
* @param string $field_name Field name.
* @return array
*/
public function get_editor_fields_html_attr($html_attr, $field_name) {
return $html_attr;
} // end get_editor_fields_html_attr;
/**
* Get the tabs available for this field.
*
* @since 2.0.0
* @return array
*/
public function get_tabs() {
return array(
'content',
'style',
);
} // end get_tabs;
/**
* Gets the pre-filled value for the field.
*
* @since 2.0.0
* @return mixed
*/
public function get_value() {
$value = wu_get_isset($this->attributes, 'default_value', '');
$session = wu_get_session('signup');
$value_session = wu_get_isset($session->get('signup'), $this->attributes['id']);
if ($value_session) {
$value = $value_session;
} // end if;
if (wu_get_isset($this->attributes, 'from_request') && wu_get_isset($this->attributes, 'id')) {
$value = wu_request($this->attributes['id'], '');
} // end if;
return $value;
} // end get_value;
/**
* Calculate the style attributes for the field.
*
* @since 2.0.4
* @return string
*/
public function calculate_style_attr() {
$styles = array();
$width = (int) wu_get_isset($this->attributes, 'width');
if ($width) {
if ($width !== 100) {
$styles[] = 'float: left';
$styles[] = sprintf('width: %s%%', $width);
} // end if;
} else {
$styles[] = 'clear: both';
} // end if;
return implode('; ', $styles);
} // end calculate_style_attr;
/**
* Sets the config values for the current field.
*
* @since 2.0.0
*
* @param array $attributes Array containing settings for the field.
* @return void
*/
public function set_attributes($attributes) {
$this->attributes = $attributes;
} // end set_attributes;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Default values for the editor fields.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array();
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
'placeholder',
'tooltip',
'default',
'required',
);
} // end default_fields;
/**
* Returns the editor fields.
*
* @since 2.0.0
*
* @param array $attributes The list of attributes of the field.
* @return array
*/
public function get_editor_fields($attributes = array()) {
$final_field_list = $this->get_fields();
/*
* Checks if this is a site field
*/
if ($this->is_site_field()) {
$final_field_list['_site_notice_field_' . uniqid()] = array(
'type' => 'note',
'classes' => 'wu--mt-px',
'desc' => sprintf('<div class="wu-p-4 wu--m-4 wu-bg-blue-100 wu-text-blue-600 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid">%s</div>', __('This is a site-related field. For that reason, this field will not show up when no plans are present on the shopping cart.', 'wp-ultimo')),
'order' => 98.5,
);
} // end if;
/*
* Checks if this is a user field
*/
if ($this->is_user_field()) {
$final_field_list['_user_notice_field_' . uniqid()] = array(
'type' => 'note',
'classes' => 'wu--mt-px',
'desc' => sprintf('<div class="wu-p-4 wu--m-4 wu-bg-blue-100 wu-text-blue-600 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid">%s</div>', __('This is a customer-related field. For that reason, this field will not show up when the user is logged and already has a customer on file.', 'wp-ultimo')),
'order' => 98.5,
);
} // end if;
foreach ($final_field_list as $key => &$field) {
$field['html_attr'] = wu_get_isset($field, 'html_attr', array());
$value = wu_get_isset($attributes, $key, null);
$field['default'] = wu_get_isset($this->defaults(), $key, '');
if ($value === null) {
$value = $field['default'];
} // end if;
if (wu_get_isset($field['html_attr'], 'data-model')) {
$model_name = wu_get_isset($field['html_attr'], 'data-model', 'product');
$models = explode(',', (string) $value);
$func_name = "wu_get_{$model_name}";
if (function_exists($func_name)) {
$selected = array_map(function($id) use ($func_name) {
$model = call_user_func($func_name, absint($id));
if (!$model) {
return false;
} // end if;
return $model->to_search_results();
}, $models);
$selected = array_filter($selected);
$field['html_attr']['data-selected'] = json_encode($selected);
} // end if;
} // end if;
if (!is_null($value)) {
$field['value'] = $value;
} // end if;
$field['html_attr'] = $this->get_editor_fields_html_attr($field['html_attr'], $field['type']);
/**
* Default v-show
*/
$show_reqs = false;
if (isset($field['wrapper_html_attr'])) {
$show_reqs = wu_get_isset($field['wrapper_html_attr'], 'v-show');
} // end if;
$tab = wu_get_isset($field, 'tab', 'content');
$field['wrapper_html_attr'] = array_merge(wu_get_isset($field, 'wrapper_html_attr', array()), array(
'v-cloak' => 1,
'v-show' => sprintf('require("type", "%s") && require("tab", "%s")', $this->get_type(), $tab) . ($show_reqs ? " && $show_reqs" : ''),
));
} // end foreach;
return $final_field_list;
} // end get_editor_fields;
/**
* Returns a list of all the attributes.
*
* @since 2.0.0
* @return array
*/
public function get_all_attributes() {
$styles = array(
'wrapper_element_classes',
'element_classes',
'element_id',
'from_request',
'width',
'logged',
);
$field_keys = array_keys($this->get_fields());
return array_merge($this->default_fields(), $field_keys, $styles);
} // end get_all_attributes;
/**
* Treat the attributes array to avoid reaching the input var limits.
*
* @since 2.0.0
*
* @param array $attributes The attributes.
* @return array
*/
public function reduce_attributes($attributes) {
return $attributes;
} // end reduce_attributes;
/**
* List of all the default fields available.
*
* @since 2.0.0
* @return array
*/
public static function fields_list() {
$fields = array();
$fields['id'] = array(
'type' => 'text',
'title' => __('Field ID', 'wp-ultimo'),
'placeholder' => __('e.g. info-name', 'wp-ultimo'),
'tooltip' => __('Only alpha-numeric and hyphens allowed.', 'wp-ultimo'),
'desc' => __('The ID of the field. This is used to reference the field.', 'wp-ultimo'),
'value' => wu_request('id', ''),
'html_attr' => array(
'v-on:input' => 'id = $event.target.value.toLowerCase().replace(/[^a-z0-9-_]+/g, "")',
'v-bind:value' => 'id',
),
);
$fields['name'] = array(
'type' => 'text',
'title' => __('Field Label', 'wp-ultimo'),
'placeholder' => __('e.g. Your Name', 'wp-ultimo'),
'desc' => __('This is what your customer see as the field title.', 'wp-ultimo'),
'tooltip' => __('Leave blank to hide the field label. You can also set a placeholder value and tip in the "Additional Settings" tab.', 'wp-ultimo'),
'value' => '',
'html_attr' => array(
'v-model' => 'name',
),
);
$fields['placeholder'] = array(
'type' => 'text',
'title' => __('Field Placeholder', 'wp-ultimo'),
'placeholder' => __('e.g. Placeholder value', 'wp-ultimo'),
'desc' => __('This value appears inside the field, as an example of how to fill it.', 'wp-ultimo'),
'tooltip' => '',
'value' => '',
'tab' => 'advanced',
'html_attr' => array(
'v-model' => 'placeholder',
),
);
$fields['tooltip'] = array(
'type' => 'textarea',
'title' => __('Field Tooltip', 'wp-ultimo'),
'placeholder' => __('e.g. This field is great, be sure to fill it.', 'wp-ultimo'),
// translators: %is is the icon for a question mark.
'desc' => sprintf(__('Any text entered here will be shown when the customer hovers the %s icon next to the field label.', 'wp-ultimo'), wu_tooltip(__('Just like this!', 'wp-ultimo'))),
'tooltip' => '',
'value' => '',
'tab' => 'advanced',
'html_attr' => array(
'v-model' => 'tooltip',
'rows' => 4,
),
);
$fields['default_value'] = array(
'type' => 'text',
'title' => __('Default Value', 'wp-ultimo'),
'placeholder' => __('e.g. None', 'wp-ultimo'),
'value' => '',
'html_attr' => array(
'v-model' => 'default_value',
),
);
$fields['note'] = array(
'type' => 'textarea',
'title' => __('Content', 'wp-ultimo'),
'placeholder' => '',
'tooltip' => '',
'value' => '',
'html_attr' => array(
'v-model' => 'content',
),
);
$fields['limits'] = array(
'type' => 'group',
'title' => __('Field Length', 'wp-ultimo'),
'tooltip' => '',
'fields' => array(
'min' => array(
'type' => 'number',
'value' => '',
'placeholder' => __('Min', 'wp-ultimo'),
'wrapper_classes' => 'wu-w-1/2',
'html_attr' => array(
'v-model' => 'min',
),
),
'max' => array(
'type' => 'number',
'value' => '',
'placeholder' => __('Max', 'wp-ultimo'),
'wrapper_classes' => 'wu-ml-2 wu-w-1/2',
'html_attr' => array(
'v-model' => 'max',
),
),
),
);
$fields['save_as'] = array(
'type' => 'select',
'title' => __('Save As', 'wp-ultimo'),
'desc' => __('Select how you want to save this piece of meta data. You can attach it to the customer or the site as site meta or as site option.', 'wp-ultimo'),
'placeholder' => '',
'tooltip' => '',
'value' => 'customer_meta',
'order' => 99.5,
'options' => array(
'customer_meta' => __('Customer Meta', 'wp-ultimo'),
'user_meta' => __('User Meta', 'wp-ultimo'),
'site_meta' => __('Site Meta', 'wp-ultimo'),
'site_option' => __('Site Option', 'wp-ultimo'),
'nothing' => __('Do not save', 'wp-ultimo'),
),
'html_attr' => array(
'v-model' => 'save_as',
),
);
$fields['required'] = array(
'type' => 'toggle',
'title' => __('Required', 'wp-ultimo'),
'desc' => __('Mark this field as required. The checkout will not proceed unless this field is filled.', 'wp-ultimo'),
'value' => 0,
'order' => 98,
'html_attr' => array(
'v-model' => 'required',
),
);
return $fields;
} // end fields_list;
} // end class Base_Signup_Field;

@@ -0,0 +1,303 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Billing_Address extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'billing_address';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return true;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Address', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds billing address fields such as country, zip code.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds billing address fields such as country, zip code.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-map1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'zip_and_country' => true,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'billing_address',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'zip_and_country' => array(
'type' => 'toggle',
'title' => __('Display only ZIP and Country?', 'wp-ultimo'),
'desc' => __('Checking this option will only add the ZIP and country fields, instead of all the normal billing address fields.', 'wp-ultimo'),
'value' => true,
),
);
} // end get_fields;
/**
* Build a filed alternative.
*
* @since 2.0.11
*
* @param array $base_field The base field.
* @param string $data_key_name The data key name.
* @param string $label_key_field The field label name.
* @return array
*/
public function build_select_alternative(&$base_field, $data_key_name, $label_key_field) {
$base_field['wrapper_html_attr']['v-if'] = "!{$data_key_name}.length";
$field = $base_field;
$option_template = sprintf('<option v-for="item in %s" :value="item.code">
{{ item.name }}
</option>', $data_key_name);
$field['type'] = 'select';
$field['options_template'] = $option_template;
$field['options'] = array();
$field['required'] = true;
$field['wrapper_html_attr']['v-if'] = "{$data_key_name}.length";
$field['html_attr']['required'] = 'required';
$field['html_attr']['required'] = 'required';
$field['html_attr']['v-bind:name'] = "'billing_" . str_replace('_list', '', $data_key_name) . "'";
$field['title'] = sprintf('<span v-html="%s">%s</span>', "labels.$label_key_field", $field['title']);
return $field;
} // end build_select_alternative;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$zip_only = wu_string_to_bool($attributes['zip_and_country']);
$customer = wu_get_current_customer();
/*
* Checks for an existing customer
*/
if ($customer) {
$fields = $customer->get_billing_address()->get_fields($zip_only);
} else {
$checkout_form = \WP_Ultimo\Checkout\Checkout::get_instance()->checkout_form;
$fields = \WP_Ultimo\Objects\Billing_Address::fields($zip_only, $checkout_form);
} // end if;
if (isset($fields['billing_country'])) {
$fields['billing_country']['html_attr'] = array(
'v-model' => 'country',
);
} // end if;
if (!$zip_only) {
if (isset($fields['billing_state'])) {
$fields['billing_state']['html_attr'] = array(
'v-model.lazy' => 'state',
);
/**
* Format the state field accordingly.
*
* @since 2.0.11
*/
$fields['billing_state_select'] = $this->build_select_alternative($fields['billing_state'], 'state_list', 'state_field');
} // end if;
if (isset($fields['billing_city'])) {
$fields['billing_city']['html_attr'] = array(
'v-model.lazy' => 'city',
);
/**
* Format the city field accordingly.
*
* @since 2.0.11
*/
$fields['billing_city_select'] = $this->build_select_alternative($fields['billing_city'], 'city_list', 'city_field');
} // end if;
} // end if;
foreach ($fields as &$field) {
$field['wrapper_classes'] = trim(wu_get_isset($field, 'wrapper_classes', '') . ' ' . $attributes['element_classes']);
} // end foreach;
uasort($fields, 'wu_sort_by_order');
return $fields;
} // end to_fields_array;
} // end class Signup_Field_Billing_Address;

@@ -0,0 +1,227 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Checkbox extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'checkbox';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return false;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Checkbox', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a checkout box that can be checked by the customer.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a checkout box that can be checked by the customer.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-check-square';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
'tooltip',
'save_as',
'required',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'default_state' => array(
'type' => 'toggle',
'title' => __('Default State', 'wp-ultimo'),
'desc' => __('Use the toggle to the set the default state of the checkbox.', 'wp-ultimo'),
'value' => 0,
'order' => 12,
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
$checkout_fields[$attributes['id']] = array(
'type' => 'checkbox',
'id' => $attributes['id'],
'name' => $attributes['name'],
'tooltip' => $attributes['tooltip'],
'required' => $attributes['required'],
'wrapper_classes' => $attributes['element_classes'],
);
if ($attributes['default_state']) {
$checkout_fields[$attributes['id']]['html_attr']['checked'] = 'checked';
} // end if;
$value = $this->get_value();
if ($value !== '' && (bool) $value === true) {
$checkout_fields[$attributes['id']]['html_attr']['checked'] = 'checked';
} // end if;
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Checkbox;

@@ -0,0 +1,203 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Color extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'color_picker';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Color', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a color picker field.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a color picker field.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-droplet';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
'placeholder',
'tooltip',
'required',
'save_as',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'default_value' => array(
'type' => 'color-picker',
'order' => 12,
'title' => __('Default Color', 'wp-ultimo'),
'desc' => __('Set the default value for this color field.', 'wp-ultimo'),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
return array(
$attributes['id'] => array(
'type' => 'color',
'id' => $attributes['id'],
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'default' => $attributes['default_value'],
'required' => $attributes['required'],
'wrapper_classes' => $attributes['element_classes'],
'classes' => 'wu-rounded',
'value' => $this->get_value(),
'html_attr' => array(
'style' => 'width: 50px !important',
),
),
);
} // end to_fields_array;
} // end class Signup_Field_Color;

@@ -0,0 +1,212 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Discount_Code extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'discount_code';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Coupon Code', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds an additional field to apply a discount code.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds an additional field to apply a discount code.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-tag1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'placeholder' => '',
'default' => '',
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'discount_code',
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array();
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
$checkout_fields['discount_code_checkbox'] = array(
'id' => 'discount_code',
'type' => 'toggle',
'name' => __('Have a coupon code?', 'wp-ultimo'),
'class' => 'wu-w-auto',
'html_attr' => array(
'v-model' => 'toggle_discount_code',
),
);
$checkout_fields['discount_code'] = array(
'type' => 'text',
'id' => 'discount_code',
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'default' => $attributes['default'],
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'v-show' => 'toggle_discount_code',
'style' => $this->calculate_style_attr(),
),
'html_attr' => array(
'v-model.lazy' => 'discount_code',
'v-init:discount_code' => "'{$this->get_value()}'",
'v-init:toggle_discount_code' => !empty($this->get_value()),
),
);
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Discount_Code;

@@ -0,0 +1,308 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Email extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'email';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return true;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
*/
public function is_user_field(): bool {
return false;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Email', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a email address field. This email address will be used to create the WordPress user.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a email address field. This email address will be used to create the WordPress user.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-at-sign';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'display_notices' => true,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'email_address',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'display_notices' => array(
'type' => 'toggle',
'title' => __('Display Notices', 'wp-ultimo'),
'desc' => __('When the customer is already logged in, a box with the customer\'s username and a link to logout is displayed instead of the email field. Disable this option if you do not want that box to show up.', 'wp-ultimo'),
'tooltip' => '',
'value' => 1,
'html_attr' => array(
'v-model' => 'display_notices',
),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
if (is_user_logged_in()) {
if ($attributes['display_notices']) {
$checkout_fields['login_note'] = array(
'type' => 'note',
'title' => __('Not you?', 'wp-ultimo'),
'desc' => array($this, 'render_not_you_customer_message'),
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
} else {
if ($attributes['display_notices']) {
$checkout_fields['login_note'] = array(
'type' => 'note',
'title' => __('Existing customer?', 'wp-ultimo'),
'desc' => array($this, 'render_existing_customer_message'),
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
$checkout_fields['email_address'] = array(
'type' => 'text',
'id' => 'email_address',
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'value' => $this->get_value(),
'required' => true,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
return $checkout_fields;
} // end to_fields_array;
/**
* Renders the login message for users that are not logged in.
*
* @since 2.0.0
* @return string
*/
public function render_existing_customer_message() {
$login_url = wp_login_url(add_query_arg('logged', '1'));
ob_start(); ?>
<div class="wu-p-4 wu-bg-yellow-200">
<?php // phpcs:disable
// translators: %s is the login URL.
printf(__('<a href="%s">Log in</a> to renew or change an existing membership.', 'wp-ultimo'), $login_url);
?>
</div>
<?php // phpcs:enable
return ob_get_clean();
} // end render_existing_customer_message;
/**
* Renders the login message for users that are not logged in.
*
* @since 2.0.0
* @return string
*/
public function render_not_you_customer_message() {
$login_url = wp_login_url(add_query_arg('logged', '1'), true);
ob_start();
?>
<p class="wu-p-4 wu-bg-yellow-200">
<?php
// translators: 1$s is the display name of the user currently logged in.
printf(__('Not %1$s? <a href="%2$s">Log in</a> using your account.', 'wp-ultimo'), wp_get_current_user()->display_name, $login_url);
?>
</p>
<?php
return ob_get_clean();
} // end render_not_you_customer_message;
} // end class Signup_Field_Email;

@@ -0,0 +1,213 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Hidden extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'hidden';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Hidden Field', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a hidden field. This is useful when coupled with the "Fill from the Request" option, to load values from the URL, for example.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a hidden field. This is useful when coupled with the "Fill from the Request" option, to load values from the URL, for example.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-eye-off';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'from_request' => true,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'save_as',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'fixed_value' => array(
'order' => 12,
'type' => 'text',
'title' => __('Pre-filled Value', 'wp-ultimo'),
'desc' => __('The field will be populated with this value. Can be overridden if the pre-fill from request option is enabled.', 'wp-ultimo'),
'placeholder' => __('e.g. blue', 'wp-ultimo'),
'tooltip' => '',
'value' => '',
),
);
} // end get_fields;
/**
* Gets the pre-filled value for the field.
*
* @since 2.0.0
* @return mixed
*/
public function get_value() {
$value = parent::get_value();
if (empty($value)) {
$value = $this->attributes['fixed_value'];
} // end if;
return $value;
} // end get_value;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
return array(
$attributes['id'] => array(
'type' => 'hidden',
'id' => $attributes['id'],
'wrapper_classes' => $attributes['element_classes'],
'value' => $this->get_value(),
),
);
} // end to_fields_array;
} // end class Signup_Field_Hidden;

@@ -0,0 +1,275 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Order_Bump extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'order_bump';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Order Bump', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a product offer that the customer can click to add to the current cart.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a product offer that the customer can click to add to the current cart.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-gift';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'order_bump_template' => 'simple',
'display_product_description' => 0,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
// 'id',
'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'order_bump_template' => 'simple',
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_templates() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('order_bump');
return $available_templates;
} // end get_templates;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array(
'product' => array(
'type' => 'model',
'title' => __('Product', 'wp-ultimo'),
'placeholder' => __('e.g. Premium', 'wp-ultimo'),
'desc' => __('Select the product that will be presented to the customer as an add-on option.', 'wp-ultimo'),
'tooltip' => '',
'order' => 12,
'html_attr' => array(
'data-model' => 'product',
'data-value-field' => 'id',
'data-label-field' => 'name',
'data-search-field' => 'name',
'data-max-items' => 1,
),
),
'display_product_description' => array(
'order' => 13,
'type' => 'toggle',
'title' => __('Display Product Description', 'wp-ultimo'),
'desc' => __('Toggle to display the product description as well, if one is available.', 'wp-ultimo'),
'value' => 0,
),
'display_product_image' => array(
'order' => 14,
'type' => 'toggle',
'title' => __('Display Product Image', 'wp-ultimo'),
'desc' => __('Toggle to display the product image as well, if one is available.', 'wp-ultimo'),
'value' => 1,
),
);
// $editor_fields['order_bump_template'] = array(
// 'type' => 'group',
// 'desc' => Field_Templates_Manager::get_instance()->render_preview_block('order_bump'),
// 'order' => 98,
// 'fields' => array(
// 'order_bump_template' => array(
// 'type' => 'select',
// 'title' => __('Layout', 'wp-ultimo'),
// 'placeholder' => __('Select your Layout', 'wp-ultimo'),
// 'options' => array($this, 'get_templates'),
// 'wrapper_classes' => 'wu-flex-grow',
// 'html_attr' => array(
// 'v-model' => 'order_bump_template',
// ),
// ),
// ),
// );
// @todo: re-add developer notes.
// $editor_fields['_dev_note_develop_your_own_template_order_bump'] = array(
// 'type' => 'note',
// 'order' => 99,
// 'wrapper_classes' => 'sm:wu-p-0 sm:wu-block',
// 'classes' => '',
// 'desc' => sprintf('<div class="wu-p-4 wu-bg-blue-100 wu-text-grey-600">%s</div>', __('Want to add customized order bump templates?<br><a target="_blank" class="wu-no-underline" href="https://help.wpultimo.com/article/343-customize-your-checkout-flow-using-field-templates">See how you can do that here</a>.', 'wp-ultimo')),
// );
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$product_id = $attributes['product'];
$product = is_numeric($product_id) ? wu_get_product($product_id) : wu_get_product_by_slug($product_id);
if (!$product) {
return array();
} // end if;
$attributes['product'] = $product;
$template_class = Field_Templates_Manager::get_instance()->get_template_class('order_bump', $attributes['order_bump_template']);
$content = $template_class ? $template_class->render_container($attributes) : __('Template does not exist.', 'wp-ultimo');
return array(
$attributes['id'] => array(
'type' => 'note',
'desc' => $content,
'wrapper_classes' => $attributes['element_classes'],
),
);
} // end to_fields_array;
} // end class Signup_Field_Order_Bump;

@@ -0,0 +1,251 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Order_Summary extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'order_summary';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return true;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Order Summary', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a summary table with prices, key subscription dates, discounts, and taxes.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a summary table with prices, key subscription dates, discounts, and taxes.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-dollar-sign';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'order_summary_template' => 'clean',
'table_columns' => 'simple',
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'order_summary',
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_templates() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('order_summary');
return $available_templates;
} // end get_templates;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array();
$editor_fields['table_columns'] = array(
'type' => 'select',
'title' => __('Table Columns', 'wp-ultimo'),
'desc' => __('"Simplified" will condense all discount and tax info into separate rows to keep the table with only two columns. "Display All" adds a discounts and taxes column to each product row.', 'wp-ultimo'),
'options' => array(
'simple' => __('Simplified', 'wp-ultimo'),
'full' => __('Display All', 'wp-ultimo'),
)
);
$editor_fields['order_summary_template'] = array(
'type' => 'group',
'desc' => Field_Templates_Manager::get_instance()->render_preview_block('order_summary'),
'fields' => array(
'order_summary_template' => array(
'type' => 'select',
'title' => __('Layout', 'wp-ultimo'),
'placeholder' => __('Select your Layout', 'wp-ultimo'),
'options' => array($this, 'get_templates'),
'wrapper_classes' => 'wu-flex-grow',
'html_attr' => array(
'v-model' => 'order_summary_template',
),
),
),
);
// @todo: re-add developer notes.
// $editor_fields['_dev_note_develop_your_own_template_order_summary'] = array(
// 'type' => 'note',
// 'order' => 99,
// 'wrapper_classes' => 'sm:wu-p-0 sm:wu-block',
// 'classes' => '',
// 'desc' => sprintf('<div class="wu-p-4 wu-bg-blue-100 wu-text-grey-600">%s</div>', __('Want to add customized order summary templates?<br><a target="_blank" class="wu-no-underline" href="https://help.wpultimo.com/article/343-customize-your-checkout-flow-using-field-templates">See how you can do that here</a>.', 'wp-ultimo')),
// );
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
/*
* Backwards compatibility with previous betas
*/
if ($attributes['order_summary_template'] === 'simple') {
$attributes['order_summary_template'] = 'clean';
} // end if;
$template_class = Field_Templates_Manager::get_instance()->get_template_class('order_summary', $attributes['order_summary_template']);
$content = $template_class ? $template_class->render_container($attributes) : __('Template does not exist.', 'wp-ultimo');
$checkout_fields[$attributes['id']] = array(
'type' => 'note',
'desc' => $content,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Order_Summary;

@@ -0,0 +1,259 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Password extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'password';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return true;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return true;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Password', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a password field, with options for enforcing password strength and adding password confirmation field. This password is then used to create the WordPress user.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a password field, with options for enforcing password strength and adding password confirmation field. This password is then used to create the WordPress user.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-lock1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'password_confirm_field' => false,
'password_confirm_label' => __('Confirm Password', 'wp-ultimo'),
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'password',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'password_strength_meter' => array(
'type' => 'toggle',
'title' => __('Display Password Strength Meter', 'wp-ultimo'),
'desc' => __('Adds a password strength meter below the password field. Enabling this option also enforces passwords to be strong.', 'wp-ultimo'),
'value' => 1,
),
'password_confirm_field' => array(
'type' => 'toggle',
'title' => __('Display Password Confirm Field', 'wp-ultimo'),
'desc' => __('Adds a "Confirm your Password" field below the default password field to reduce the chance or making a mistake.', 'wp-ultimo'),
'value' => 1,
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
/*
* Logged in user, bail.
*/
if (is_user_logged_in()) {
return array();
} // end if;
$checkout_fields = array();
$checkout_fields['password'] = array(
'type' => 'password',
'id' => 'password',
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'meter' => $attributes['password_strength_meter'],
'required' => true,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'html_attr' => array(
'autocomplete' => 'new-password',
),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
if ($attributes['password_confirm_field']) {
$checkout_fields['password_conf'] = array(
'type' => 'password',
'id' => 'password_conf',
'name' => $attributes['password_confirm_label'],
'placeholder' => '',
'tooltip' => '',
'meter' => false,
'required' => true,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'html_attr' => array(
'autocomplete' => 'new-password',
),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Password;

@@ -0,0 +1,224 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Gateway_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Payment extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'payment';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return true;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Payment', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds the payment options and the additional fields required to complete a purchase (e.g. credit card field).', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds the payment options and the additional fields required to complete a purchase (e.g. credit card field).', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-credit-card2';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'payment',
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array();
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$fields = array(
'payment_template' => array(
'type' => 'text',
'id' => 'payment_template',
'name' => '',
'classes' => 'wu-hidden',
),
'payment' => array(
'type' => 'payment-methods',
'id' => 'payment',
'name' => $attributes['name'],
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
),
);
/*
* Checks if we need to add the
* auto renew field.
*/
if (!wu_get_setting('force_auto_renew', 1)) {
$auto_renewable_gateways = Gateway_Manager::get_instance()->get_auto_renewable_gateways();
$fields['auto_renew'] = array(
'type' => 'toggle',
'id' => 'auto_renew',
'name' => __('Auto-renew', 'wp-ultimo'),
'tooltip' => '',
'value' => '1',
'html_attr' => array(
'v-model' => 'auto_renew',
'true-value' => '1',
'false-value' => '0',
),
'wrapper_html_attr' => array(
'v-cloak' => 1,
'v-show' => sprintf('%s.includes(gateway) && order.should_collect_payment && order.has_recurring', json_encode($auto_renewable_gateways)),
)
);
} // end if;
return $fields;
} // end to_fields_array;
} // end class Signup_Field_Payment;

@@ -0,0 +1,340 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Period_Selection extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'period_selection';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Period Select', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a period selector, that allows customers to switch between different billing periods.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a period selector, that allows customers to switch between different billing periods.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu dashicons-wu-toggle-right';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'period_selection_template' => 'clean',
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
// 'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'period_selection',
'name' => __('Plan Duration Switch', 'wp-ultimo'),
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_template_options() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('period_selection');
return $available_templates;
} // end get_template_options;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array();
$editor_fields['period_selection_template'] = array(
'type' => 'group',
'order' => 98.4,
'desc' => Field_Templates_Manager::get_instance()->render_preview_block('period_selection'),
'fields' => array(
'period_selection_template' => array(
'type' => 'select',
'title' => __('Period Selector Template', 'wp-ultimo'),
'placeholder' => __('Select your Template', 'wp-ultimo'),
'options' => array($this, 'get_template_options'),
'wrapper_classes' => 'wu-flex-grow',
'html_attr' => array(
'v-model' => 'period_selection_template',
),
),
),
);
$editor_fields['period_options_header'] = array(
'type' => 'small-header',
'title' => __('Options', 'wp-ultimo'),
'desc' => __('Add different options below. These need to match your product price variations.', 'wp-ultimo'),
'order' => 90,
);
$editor_fields['period_options_empty'] = array(
'type' => 'note',
'desc' => __('Add the first option using the button below.', 'wp-ultimo'),
'classes' => 'wu-text-gray-600 wu-text-xs wu-text-center wu-w-full',
'wrapper_classes' => 'wu-bg-gray-100 wu-items-end',
'order' => 90.5,
'wrapper_html_attr' => array(
'v-if' => 'period_options.length === 0',
'v-cloak' => '1',
),
);
$editor_fields['period_options'] = array(
'type' => 'group',
'tooltip' => '',
'order' => 91,
'wrapper_classes' => 'wu-relative wu-bg-gray-100 wu-pb-2',
'wrapper_html_attr' => array(
'v-if' => 'period_options.length',
'v-for' => '(period_option, index) in period_options',
'v-cloak' => '1',
),
'fields' => array(
'period_options_remove' => array(
'type' => 'note',
'desc' => sprintf('<a title="%s" class="wu-no-underline wu-inline-block wu-text-gray-600 wu-mt-2 wu-mr-2" href="#" @click.prevent="() => period_options.splice(index, 1)"><span class="dashicons-wu-squared-cross"></span></a>', __('Remove', 'wp-ultimo')),
'wrapper_classes' => 'wu-absolute wu-top-0 wu-right-0',
),
'period_options_duration' => array(
'type' => 'number',
'title' => __('Duration', 'wp-ultimo'),
'placeholder' => '',
'wrapper_classes' => 'wu-w-2/12',
'min' => 1,
'html_attr' => array(
'v-model' => 'period_option.duration',
'steps' => 1,
'v-bind:name' => '"period_options[" + index + "][duration]"',
),
),
'period_options_duration_unit' => array(
'type' => 'select',
'title' => '&nbsp',
'placeholder' => '',
'wrapper_classes' => 'wu-w-5/12 wu-mx-2',
'html_attr' => array(
'v-model' => 'period_option.duration_unit',
'v-bind:name' => '"period_options[" + index + "][duration_unit]"',
),
'options' => array(
'day' => __('Days', 'wp-ultimo'),
'week' => __('Weeks', 'wp-ultimo'),
'month' => __('Months', 'wp-ultimo'),
'year' => __('Years', 'wp-ultimo'),
),
),
'period_options_label' => array(
'type' => 'text',
'title' => __('Label', 'wp-ultimo'),
'placeholder' => __('e.g. Monthly', 'wp-ultimo'),
'wrapper_classes' => 'wu-w-5/12',
'html_attr' => array(
'v-model' => 'period_option.label',
'v-bind:name' => '"period_options[" + index + "][label]"',
),
),
),
);
$editor_fields['repeat'] = array(
'order' => 92,
'type' => 'submit',
'title' => __('+ Add option', 'wp-ultimo'),
'classes' => 'wu-uppercase wu-text-2xs wu-text-blue-700 wu-border-none wu-bg-transparent wu-font-bold wu-text-right wu-w-full wu-cursor-pointer',
'wrapper_classes' => 'wu-bg-gray-100 wu-items-end',
'wrapper_html_attr' => array(
'v-cloak' => '1',
),
'html_attr' => array(
'v-on:click.prevent' => '() => period_options.push({
duration: 1,
duration_unit: "month",
label: "",
})',
),
);
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
if (wu_get_isset($attributes, 'period_selection_template') === 'legacy') {
wp_register_script('wu-legacy-signup', wu_get_asset('legacy-signup.js', 'js'), array('wu-functions'), wu_get_version());
wp_enqueue_script('wu-legacy-signup');
wp_enqueue_style('legacy-shortcodes', wu_get_asset('legacy-shortcodes.css', 'css'), array('dashicons'), wu_get_version());
} // end if;
$template_class = Field_Templates_Manager::get_instance()->get_template_class('period_selection', $attributes['period_selection_template']);
$content = $template_class ? $template_class->render_container($attributes) : __('Template does not exist.', 'wp-ultimo');
$checkout_fields = array();
$checkout_fields[$attributes['id']] = array(
'type' => 'note',
'id' => $attributes['id'],
'wrapper_classes' => $attributes['element_classes'],
'desc' => $content,
);
$checkout_fields['duration'] = array(
'type' => 'hidden',
'html_attr' => array(
'v-model' => 'duration',
),
);
$checkout_fields['duration_unit'] = array(
'type' => 'hidden',
'html_attr' => array(
'v-model' => 'duration_unit',
),
);
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Period_Selection;

@@ -0,0 +1,312 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Pricing_Table extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'pricing_table';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Pricing Table', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a pricing table section that customers can use to choose a plan to subscribe to.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a pricing table section that customers can use to choose a plan to subscribe to.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu dashicons-wu-columns';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'pricing_table_products' => implode(',', array_keys(wu_get_plans_as_options())),
'pricing_table_template' => 'list',
'force_different_durations' => false,
'hide_pricing_table_when_pre_selected' => false,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
// 'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'pricing_table',
'name' => __('Plan Selection', 'wp-ultimo'),
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_pricing_table_templates() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('pricing_table');
return $available_templates;
} // end get_pricing_table_templates;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array();
$editor_fields['pricing_table_products'] = array(
'type' => 'model',
'title' => __('Products', 'wp-ultimo'),
'placeholder' => __('e.g. Premium', 'wp-ultimo'),
'desc' => __('Be sure to add the products in the order you want them to show up.', 'wp-ultimo'),
'tooltip' => '',
'order' => 20,
'html_attr' => array(
'data-model' => 'product',
'data-value-field' => 'id',
'data-label-field' => 'name',
'data-search-field' => 'name',
'data-include' => implode(',', array_keys(wu_get_plans_as_options())),
'data-max-items' => 999,
),
);
$editor_fields['force_different_durations'] = array(
'type' => 'toggle',
'title' => __('Force Different Durations', 'wp-ultimo'),
'desc' => __('Check this option to force the display of plans with different recurring durations.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'order' => 22,
'html_attr' => array(
'v-model' => 'force_different_durations',
),
);
$editor_fields['hide_pricing_table_when_pre_selected'] = array(
'type' => 'toggle',
'title' => __('Hide when Pre-Selected', 'wp-ultimo'),
'desc' => __('Prevent customers from seeing this field when a plan was already selected via the URL.', 'wp-ultimo'),
'tooltip' => __('If the pricing table field is the only field in the current step, the step will be skipped.', 'wp-ultimo'),
'value' => 0,
'order' => 24,
'html_attr' => array(
'v-model' => 'hide_pricing_table_when_pre_selected',
),
);
$editor_fields['pricing_table_template'] = array(
'type' => 'group',
'desc' => Field_Templates_Manager::get_instance()->render_preview_block('pricing_table'),
'order' => 26,
'fields' => array(
'pricing_table_template' => array(
'type' => 'select',
'title' => __('Pricing Table Template', 'wp-ultimo'),
'placeholder' => __('Select your Template', 'wp-ultimo'),
'options' => array($this, 'get_pricing_table_templates'),
'wrapper_classes' => 'wu-flex-grow',
'html_attr' => array(
'v-model' => 'pricing_table_template',
),
),
),
);
// @todo: re-add developer notes.
// $editor_fields['_dev_note_develop_your_own_template_2'] = array(
// 'type' => 'note',
// 'order' => 99,
// 'wrapper_classes' => 'sm:wu-p-0 sm:wu-block',
// 'classes' => '',
// 'desc' => sprintf('<div class="wu-p-4 wu-bg-blue-100 wu-text-grey-600">%s</div>', __('Want to add customized pricing table templates?<br><a target="_blank" class="wu-no-underline" href="https://help.wpultimo.com/article/343-customize-your-checkout-flow-using-field-templates">See how you can do that here</a>.', 'wp-ultimo')),
// );
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
if (wu_get_isset($attributes, 'pricing_table_template') === 'legacy') {
wp_enqueue_style('legacy-shortcodes', wu_get_asset('legacy-shortcodes.css', 'css'), array('dashicons'), wu_get_version());
wp_add_inline_style('legacy-shortcodes', \WP_Ultimo\Checkout\Legacy_Checkout::get_instance()->get_legacy_dynamic_styles());
} // end if;
$product_list = explode(',', (string) $attributes['pricing_table_products']);
$products = array_map('wu_get_product', $product_list);
/**
* Clear the product list out of invalid items and inactive products.
*/
$products = array_filter($products, fn($item) => $item && $item->is_active());
/**
* Hide when pre-selected.
*/
if (wu_should_hide_form_field($attributes)) {
return array();
} // end if;
$template_attributes = array(
'products' => $products,
'name' => $attributes['name'],
'force_different_durations' => $attributes['force_different_durations'],
'classes' => wu_get_isset($attributes, 'element_classes', ''),
);
$template_class = Field_Templates_Manager::get_instance()->get_template_class('pricing_table', $attributes['pricing_table_template']);
$content = $template_class ? $template_class->render_container($template_attributes) : __('Template does not exist.', 'wp-ultimo');
$checkout_fields = array();
$checkout_fields[$attributes['id']] = array(
'type' => 'note',
'id' => $attributes['id'],
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'desc' => $content,
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Pricing_Table;

@@ -0,0 +1,247 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Products extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'products';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Product', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Hidden field used to pre-select products. This is useful when you have a signup page for specific offering/bundles and do not want your customers to be able to choose plans and products manually.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Hidden field used to pre-select products. This is useful when you have a signup page for specific offering/bundles and do not want your customers to be able to choose plans and products manually.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu dashicons-wu-package';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array();
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'name' => __('Pre-selected Products', 'wp-ultimo'),
'id' => 'products',
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'products' => array(
'type' => 'model',
'title' => __('Products', 'wp-ultimo'),
'placeholder' => __('Products', 'wp-ultimo'),
'desc' => __('Use this field to pre-select products. This is useful when you have a signup page for specific offering/bundles and do not want your customers to be able to choose plans and other products manually.', 'wp-ultimo'),
'tooltip' => '',
'html_attr' => array(
'data-model' => 'product',
'data-value-field' => 'id',
'data-label-field' => 'name',
'data-search-field' => 'name',
'data-max-items' => 10,
),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
$products = explode(',', (string) $attributes['products']);
foreach ($products as $product_id) {
$checkout_fields["products[{$product_id}]"] = array(
'type' => 'hidden',
'value' => $product_id,
'html_attr' => array(
'v-bind:name' => "'products[]'",
),
);
} // end foreach;
$this->insert_products_in_form($products);
return $checkout_fields;
} // end to_fields_array;
/**
* Inserts the products in the form.
*
* @param array $products An array of product IDs.
* @return void
*/
protected function insert_products_in_form(array $products): void {
static $added = false;
if ($added) {
return;
} // end if;
$added = true;
$script = "wp.hooks.addFilter('wu_before_form_init', 'nextpress/wp-ultimo', function(data) {
if (typeof data !== 'undefined' && Array.isArray(data.products)) {
data.products.push(...%s);
data.products = data.products.map((value) => parseInt(value) || value);
data.products = [...new Set(data.products)];
} // end if;
return data;
});";
if (did_action('wu-checkout')) {
wp_add_inline_script('wu-checkout', sprintf($script, json_encode($products)), 'before');
return;
} // end if;
add_action('wp_enqueue_scripts', function() use ($script, $products) {
wp_add_inline_script('wu-checkout', sprintf($script, json_encode($products)), 'before');
}, 11);
} // end insert_products_in_form;
} // end class Signup_Field_Products;

@@ -0,0 +1,278 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Select extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'select';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Select', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a select field.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a select field.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-list1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
'placeholder',
'default_value',
'tooltip',
'required',
'save_as',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array();
$editor_fields['options_header'] = array(
'order' => 12,
'type' => 'small-header',
'title' => __('Options', 'wp-ultimo'),
'desc' => __('Add different options below. The first option is used as the default.', 'wp-ultimo'),
);
$editor_fields['options_empty'] = array(
'type' => 'note',
'desc' => __('Add the first option using the button below.', 'wp-ultimo'),
'classes' => 'wu-text-gray-600 wu-text-xs wu-text-center wu-w-full',
'wrapper_classes' => 'wu-bg-gray-100 wu-items-end',
'order' => 13,
'wrapper_html_attr' => array(
'v-if' => 'options.length === 0',
'v-cloak' => '1',
),
);
$editor_fields['options'] = array(
'order' => 14,
'type' => 'group',
'tooltip' => '',
'wrapper_classes' => 'wu-relative wu-bg-gray-100',
'wrapper_html_attr' => array(
'v-if' => 'options.length',
'v-for' => '(option, index) in options',
'v-cloak' => '1',
),
'fields' => array(
'options_remove' => array(
'type' => 'note',
'desc' => sprintf('<a title="%s" class="wu-no-underline wu-inline-block wu-text-gray-600 wu-mt-2 wu-mr-2" href="#" @click.prevent="() => options.splice(index, 1)"><span class="dashicons-wu-squared-cross"></span></a>', __('Remove', 'wp-ultimo')),
'wrapper_classes' => 'wu-absolute wu-top-0 wu-right-0',
),
'options_key' => array(
'type' => 'text',
'title' => __('Option Value', 'wp-ultimo'),
'placeholder' => __('e.g. option1', 'wp-ultimo'),
'wrapper_classes' => 'wu-w-1/2 wu-mr-2',
'html_attr' => array(
'v-model' => 'option.key',
'steps' => 1,
'v-bind:name' => '"options[" + index + "][key]"',
),
),
'options_label' => array(
'type' => 'text',
'title' => __('Label', 'wp-ultimo'),
'placeholder' => __('e.g. Option 1', 'wp-ultimo'),
'wrapper_classes' => 'wu-w-1/2 wu-ml-2',
'html_attr' => array(
'v-model' => 'option.label',
'v-bind:name' => '"options[" + index + "][label]"',
),
),
),
);
$editor_fields['repeat_select_option'] = array(
'order' => 16,
'type' => 'submit',
'title' => __('+ Add option', 'wp-ultimo'),
'classes' => 'wu-uppercase wu-text-2xs wu-text-blue-700 wu-border-none wu-bg-transparent wu-font-bold wu-text-right wu-w-full wu-cursor-pointer',
'wrapper_classes' => 'wu-bg-gray-100 wu-items-end',
'wrapper_html_attr' => array(
'v-cloak' => '1',
),
'html_attr' => array(
'type' => 'button',
'v-on:click.prevent' => '() => options.push({})',
),
);
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$options = array();
foreach ($attributes['options'] as $_option) {
$options[$_option['key']] = $_option['label'];
} // end foreach;
return array(
$attributes['id'] => array(
'type' => 'select',
'id' => $attributes['id'],
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'default' => $attributes['default_value'],
'required' => $attributes['required'],
'wrapper_classes' => $attributes['element_classes'],
'options' => $options,
'value' => $this->get_value(),
),
);
} // end to_fields_array;
} // end class Signup_Field_Select;

@@ -0,0 +1,190 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Shortcode extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'shortcode';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Shortcode', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Displays the content of a given WordPress shortcode. Can be useful to inset content from other plugins inside a WP Ultimo checkout form.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Displays the content of a given WordPress shortcode. Can be useful to insert content from other plugins inside a WP Ultimo checkout form.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-terminal';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
// 'id',
// 'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'name' => __('Shortcode', 'wp-ultimo'),
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'shortcode_code' => array(
'type' => 'text',
'title' => __('Shortcode', 'wp-ultimo'),
'placeholder' => __('e.g. [shortcode]', 'wp-ultimo'),
'desc' => __('Please, enter the full shortcode, including [].', 'wp-ultimo'),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
return array(
$attributes['id'] => array(
'type' => 'note',
'desc' => fn() => do_shortcode($attributes['shortcode_code']),
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
),
);
} // end to_fields_array;
} // end class Signup_Field_Shortcode;

@@ -0,0 +1,239 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Site_Title extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'site_title';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Defines if this field/element is related to site creation or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_site_field() {
return true;
} // end is_site_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Site Title', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a Site Title field. This value is used to set the site title for the site being created.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a Site Title field. This value is used to set the site title for the site being created.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-type';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'auto_generate_site_title' => false,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'site_title',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'auto_generate_site_title' => array(
'type' => 'toggle',
'title' => __('Auto-generate?', 'wp-ultimo'),
'desc' => __('Check this option to auto-generate this field based on the username of the customer.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'html_attr' => array(
'v-model' => 'auto_generate_site_title',
),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
/*
* If we should auto-generate, add as hidden.
*/
if (isset($attributes['auto_generate_site_title']) && $attributes['auto_generate_site_title']) {
return array(
'auto_generate_site_title' => array(
'type' => 'hidden',
'id' => 'auto_generate_site_title',
'value' => 'username',
),
'site_title' => array(
'type' => 'hidden',
'id' => 'site_title',
'html_attr' => array(
'v-bind:value' => 'username',
)
),
);
} // end if;
return array(
'site_title' => array(
'type' => 'text',
'id' => 'site_title',
'required' => true,
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'value' => $this->get_value(),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
),
);
} // end to_fields_array;
} // end class Signup_Field_Site_Title;

@@ -0,0 +1,403 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Site_Url extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'site_url';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Defines if this field/element is related to site creation or not.
*
* @since 2.0.0
*/
public function is_site_field(): bool {
return true;
} // end is_site_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Site URL', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a Site URL field. This is used to set the URL of the site being created.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a Site URL field. This is used to set the URL of the site being created.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-globe1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
global $current_site;
return array(
'auto_generate_site_url' => false,
'display_url_preview' => true,
'enable_domain_selection' => false,
'display_field_attachments' => true,
'available_domains' => $current_site->domain . PHP_EOL,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'site_url',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
global $current_site;
return array(
'auto_generate_site_url' => array(
'order' => 12,
'type' => 'toggle',
'title' => __('Auto-generate', 'wp-ultimo'),
'desc' => __('Check this option to auto-generate this field based on the username of the customer.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'html_attr' => array(
'v-model' => 'auto_generate_site_url',
),
),
'display_field_attachments' => array(
'order' => 18,
'type' => 'toggle',
'title' => __('Display URL field attachments', 'wp-ultimo'),
'desc' => __('Adds the prefix and suffix blocks to the URL field.', 'wp-ultimo'),
'tooltip' => '',
'value' => 1,
'tab' => 'content',
'wrapper_html_attr' => array(
'v-show' => '!auto_generate_site_url',
),
'html_attr' => array(
'v-model' => 'display_field_attachments',
),
),
'display_url_preview' => array(
'order' => 19,
'type' => 'toggle',
'title' => __('Display URL preview block', 'wp-ultimo'),
'desc' => __('Adds a preview block that shows the final URL.', 'wp-ultimo'),
'tooltip' => '',
'value' => 1,
'tab' => 'content',
'wrapper_html_attr' => array(
'v-show' => '!auto_generate_site_url',
),
'html_attr' => array(
'v-model' => 'display_url_preview',
),
),
'enable_domain_selection' => array(
'order' => 20,
'type' => 'toggle',
'title' => __('Enable Domain Selection', 'wp-ultimo'),
'desc' => __('Offer different domain options to your customers to choose from.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'tab' => 'content',
'wrapper_html_attr' => array(
'v-show' => '!auto_generate_site_url',
),
'html_attr' => array(
'v-model' => 'enable_domain_selection',
'rows' => 5,
),
),
'available_domains' => array(
'order' => 30,
'type' => 'textarea',
'title' => __('Available Domains', 'wp-ultimo'),
'desc' => '',
'desc' => __('Enter one domain option per line.', 'wp-ultimo'),
'value' => $current_site->domain . PHP_EOL,
'tab' => 'content',
'wrapper_html_attr' => array(
'v-show' => '!auto_generate_site_url && enable_domain_selection',
),
'html_attr' => array(
'rows' => 4,
),
),
);
} // end get_fields;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_url_preview_templates() {
$templates = array(
'legacy/signup/steps/step-domain-url-preview' => __('New URL Preview', 'wp-ultimo'),
// 'legacy/signup/steps/step-domain-url-preview' => __('Legacy Template', 'wp-ultimo'),
);
return apply_filters('wu_get_pricing_table_templates', $templates);
} // end get_url_preview_templates;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
/*
* If we should auto-generate, add as hidden.
*/
if ($attributes['auto_generate_site_url']) {
return array(
'auto_generate_site_url' => array(
'type' => 'hidden',
'id' => 'auto_generate_site_url',
'value' => 'username',
),
'site_url' => array(
'type' => 'hidden',
'id' => 'site_url',
'value' => uniqid(),
),
);
} // end if;
$checkout_fields = array();
$checkout_fields['site_url'] = array(
'type' => 'text',
'id' => 'site_url',
'wrapper_classes' => 'wu-flex-grow wu-my-0',
'classes' => 'disabled sm:wu-my-0',
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'required' => true,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', 'wu-my-1'),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'html_attr' => array(
'autocomplete' => 'off',
'v-on:input' => 'site_url = $event.target.value.toLowerCase().replace(/[^a-z0-9-]+/g, "")',
'v-bind:value' => 'site_url',
),
);
if ($attributes['display_field_attachments']) {
$checkout_fields['site_url']['classes'] .= ' xs:wu-rounded-none';
$checkout_fields['site_url']['prefix'] = ' ';
$checkout_fields['site_url']['prefix_html_attr'] = array(
'class' => 'wu-flex wu-items-center wu-px-3 wu-mt-1 sm:wu-mb-1 wu-border-box wu-font-mono wu-justify-center sm:wu-border-r-0',
'style' => 'background-color: rgba(0, 0, 0, 0.008); border: 1px solid #eee; margin-right: -1px; font-size: 90%;',
'v-html' => 'is_subdomain ? "https://" : "https://" + site_domain + "/"',
'v-cloak' => 1,
);
$checkout_fields['site_url']['suffix'] = ' ';
$checkout_fields['site_url']['suffix_html_attr'] = array(
'class' => 'wu-flex wu-items-center wu-px-3 sm:wu-mt-1 wu-mb-1 wu-border-box wu-font-mono wu-justify-center sm:wu-border-l-0',
'style' => 'background-color: rgba(0, 0, 0, 0.008); border: 1px solid #eee; margin-left: -1px; font-size: 90%;',
'v-html' => '"." + site_domain',
'v-cloak' => 1,
'v-show' => 'is_subdomain',
);
} // end if;
if ($attributes['available_domains'] && $attributes['enable_domain_selection']) {
$options = $this->get_domain_options($attributes['available_domains']);
$checkout_fields['site_domain'] = array(
'name' => __('Domain', 'wp-ultimo'),
'options' => $options,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'order' => 25,
'required' => true,
'id' => 'site_domain',
'type' => 'select',
'classes' => 'input',
'html_attr' => array(
'v-model' => 'site_domain',
),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
if ($attributes['display_url_preview']) {
$content = wu_get_template_contents('legacy/signup/steps/step-domain-url-preview');
$checkout_fields['site_url_preview'] = array(
'type' => 'note',
'desc' => $content,
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
);
} // end if;
return $checkout_fields;
} // end to_fields_array;
/**
* Get the domain options.
*
* @since 2.0.0
*
* @param string $domain_options The list of domains, in string format.
*/
protected function get_domain_options($domain_options): array {
$domains = array_filter(explode(PHP_EOL, $domain_options));
$domains = array_map(fn($item) => trim((string) $item), $domains);
return array_combine($domains, $domains);
} // end get_domain_options;
} // end class Signup_Field_Site_Url;

@@ -0,0 +1,233 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Steps extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'steps';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Steps', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a list of the steps.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a list of the steps.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-filter_1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'steps_template' => 'clean',
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array();
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'steps',
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_templates() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('steps');
return $available_templates;
} // end get_templates;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields['steps_template'] = array(
'type' => 'group',
'desc' => Field_Templates_Manager::get_instance()->render_preview_block('steps'),
'order' => 98,
'fields' => array(
'steps_template' => array(
'type' => 'select',
'title' => __('Layout', 'wp-ultimo'),
'placeholder' => __('Select your Layout', 'wp-ultimo'),
'options' => array($this, 'get_templates'),
'wrapper_classes' => 'wu-flex-grow',
'html_attr' => array(
'v-model' => 'steps_template',
),
),
),
);
// @todo: re-add developer notes.
// $editor_fields['_dev_note_develop_your_own_template_steps'] = array(
// 'type' => 'note',
// 'order' => 99,
// 'wrapper_classes' => 'sm:wu-p-0 sm:wu-block',
// 'classes' => '',
// 'desc' => sprintf('<div class="wu-p-4 wu-bg-blue-100 wu-text-grey-600">%s</div>', __('Want to add customized steps templates?<br><a target="_blank" class="wu-no-underline" href="https://help.wpultimo.com/article/343-customize-your-checkout-flow-using-field-templates">See how you can do that here</a>.', 'wp-ultimo')),
// );
return $editor_fields;
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
if (wu_get_isset($attributes, 'steps_template') === 'legacy') {
wp_enqueue_style('legacy-shortcodes', wu_get_asset('legacy-shortcodes.css', 'css'), array('dashicons'), wu_get_version());
wp_add_inline_style('legacy-shortcodes', \WP_Ultimo\Checkout\Legacy_Checkout::get_instance()->get_legacy_dynamic_styles());
} // end if;
$attributes['steps'] = \WP_Ultimo\Checkout\Checkout::get_instance()->steps;
$attributes['current_step'] = \WP_Ultimo\Checkout\Checkout::get_instance()->step_name;
$template_class = Field_Templates_Manager::get_instance()->get_template_class('steps', $attributes['steps_template']);
$content = $template_class ? $template_class->render_container($attributes) : __('Template does not exist.', 'wp-ultimo');
return array(
$attributes['id'] => array(
'type' => 'note',
'desc' => $content,
'wrapper_classes' => $attributes['element_classes'],
),
);
} // end to_fields_array;
} // end class Signup_Field_Steps;

@@ -0,0 +1,259 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Submit_Button extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'submit_button';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return true;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Submit Button', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a submit button. This is required to finalize single-step checkout forms or to navigate to the next step on multi-step checkout forms.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a submit button. This is required to finalize single-step checkout forms or to navigate to the next step on multi-step checkout forms.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-zap';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'enable_go_back_button' => false,
'back_button_label' => __('&larr; Go Back', 'wp-ultimo'),
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'enable_go_back_button' => array(
'type' => 'toggle',
'title' => __('Add "Go Back" button', 'wp-ultimo'),
'desc' => __('Enable this option to add a "Go Back" button. Useful for multi-step checkout forms.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'html_attr' => array(
'v-model' => 'enable_go_back_button',
),
),
'back_button_label' => array(
'type' => 'text',
'title' => __('"Go Back" Button Label', 'wp-ultimo'),
'desc' => __('Value to be used as the "Go Back" label.', 'wp-ultimo'),
'placeholder' => __('e.g. &larr; Go Back', 'wp-ultimo'),
'value' => __('&larr; Go Back', 'wp-ultimo'),
'wrapper_html_attr' => array(
'v-cloak' => '1',
'v-show' => 'enable_go_back_button',
),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$uniqid = uniqid();
$fields = array();
$fields[$attributes['id'] . '_errors'] = array(
'type' => 'html',
'wrapper_classes' => 'wu_submit_button_errors wu-clear-both',
'content' => '<span v-cloak class="wu-block wu-bg-red-100 wu-p-2 wu-mb-4" v-html="get_errors().join(' . esc_js(json_encode('<br>')) . ')"></span>',
'wrapper_html_attr' => array(
'v-if' => 'get_errors()',
),
);
$fields[$attributes['id'] . '_group'] = array(
'type' => 'group',
'raw' => true,
'default' => array(),
'wrapper_classes' => '',
'fields' => array(),
);
$button_wrapper_classes = 'wu_submit_button';
if ($attributes['enable_go_back_button']) {
$steps = \WP_Ultimo\Checkout\Checkout::get_instance()->steps;
$is_first_step = isset($steps[0]) && $steps[0]['id'] === $attributes['step'];
if (!$is_first_step) {
$fields[$attributes['id'] . '_group']['fields'][$attributes['id'] . '_go_back'] = array(
'type' => 'html',
'wrapper_classes' => 'md:wu-w-1/2 wu-box-border wu-float-left wu--mt-4',
'id' => $attributes['id'] . '_go_back',
'content' => sprintf('<a href="#" class="button wu-go-back" v-on:click.prevent="go_back()">%s</a>', $attributes['back_button_label']),
);
$button_wrapper_classes .= ' md:wu-w-1/2 wu-box-border wu-float-left wu-text-right';
} // end if;
} // end if;
$fields[$attributes['id'] . '_group']['fields'][$attributes['id']] = array(
'type' => 'submit',
'wrapper_classes' => trim($button_wrapper_classes . ' ' . wu_get_isset($attributes, 'wrapper_element_classes', '')),
'classes' => trim('button button-primary btn-primary' . ' ' . wu_get_isset($attributes, 'element_classes', '')),
'id' => $attributes['id'],
'name' => $attributes['name'],
);
if ($attributes['enable_go_back_button']) {
$fields[$attributes['id'] . '_clear'] = array(
'type' => 'clear',
);
} // end if;
return $fields;
} // end to_fields_array;
} // end class Signup_Field_Submit_Button;

@@ -0,0 +1,425 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
use \WP_Ultimo\Managers\Field_Templates_Manager;
use \WP_Ultimo\Models\Site;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Template_Selection extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
*/
public function get_type(): string {
return 'template_selection';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
*/
public function is_required(): bool {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Templates', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a template selection section. This allows the customer to choose a pre-built site to be used as a template for the site being currently created.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a template selection section. This allows the customer to choose a pre-built site to be used as a template for the site being currently created.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
*/
public function get_icon(): string {
return 'dashicons-wu-layout';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'template_selection_sites' => implode(',', wu_get_site_templates(array('fields' => 'ids'))),
'template_selection_type' => 'name',
'template_selection_template' => 'clean',
'cols' => 3,
'hide_template_selection_when_pre_selected' => false,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
// 'name',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'template_selection',
'name' => __('Template Selection', 'wp-ultimo'),
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of available pricing table templates.
*
* @since 2.0.0
* @return array
*/
public function get_template_selection_templates() {
$available_templates = Field_Templates_Manager::get_instance()->get_templates_as_options('template_selection');
return $available_templates;
} // end get_template_selection_templates;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
$editor_fields = array();
$editor_fields['cols'] = array(
'type' => 'hidden',
);
$editor_fields['template_selection_type'] = array(
'type' => 'select',
'title' => __('Available templates', 'wp-ultimo'),
'desc' => __('How do you want to choose available which templates will be available.', 'wp-ultimo'),
'order' => 20,
'options' => array(
'name' => __('Select by names'),
'categories' => __('Select by categories'),
'all' => __('All templates'),
),
'html_attr' => array(
'v-model' => 'template_selection_type',
),
);
$editor_fields['template_selection_categories'] = array(
'type' => 'select',
'title' => __('Template Categories', 'wp-ultimo'),
'placeholder' => __('e.g.: Landing Page, Health...', 'wp-ultimo'),
'desc' => __('Customers will be able to filter by categories during signup.', 'wp-ultimo'),
'order' => 21,
'options' => Site::get_all_categories(),
'html_attr' => array(
'data-selectize-categories' => 1,
'multiple' => 1,
),
'wrapper_html_attr' => array(
'v-show' => 'template_selection_type === "categories"',
),
);
$editor_fields['template_selection_sites'] = array(
'type' => 'model',
'title' => __('Template Sites', 'wp-ultimo'),
'placeholder' => __('e.g. Template Site 1, My Agency', 'wp-ultimo'),
'desc' => __('Be sure to add the templates in the order you want them to show up.', 'wp-ultimo'),
'order' => 22,
'html_attr' => array(
'v-model' => 'template_selection_sites',
'data-model' => 'site',
'data-value-field' => 'blog_id',
'data-label-field' => 'title',
'data-search-field' => 'title',
'data-max-items' => 999,
'data-include' => implode(',', wu_get_site_templates(array(
'fields' => 'blog_id',
))),
),
'wrapper_html_attr' => array(
'v-show' => 'template_selection_type === \'name\'',
),
);
$editor_fields['hide_template_selection_when_pre_selected'] = array(
'type' => 'toggle',
'title' => __('Hide when Pre-Selected', 'wp-ultimo'),
'desc' => __('Prevent customers from seeing this field when a template was already selected via the URL.', 'wp-ultimo'),
'tooltip' => __('If the template selection field is the only field in the current step, the step will be skipped.', 'wp-ultimo'),
'value' => 0,
'order' => 23,
'html_attr' => array(
'v-model' => 'hide_template_selection_when_pre_selected',
),
);
$editor_fields['template_selection_template'] = array(
'type' => 'group',
'order' => 24,
'desc' => Field_Templates_Manager::get_instance()->render_preview_block('template_selection'),
'fields' => array(
'template_selection_template' => array(
'type' => 'select',
'title' => __('Template Selector Template', 'wp-ultimo'),
'placeholder' => __('Select your Template', 'wp-ultimo'),
'options' => array($this, 'get_template_selection_templates'),
'wrapper_classes' => 'wu-flex-grow',
'html_attr' => array(
'v-model' => 'template_selection_template',
),
),
),
);
// @todo: re-add developer notes.
// $editor_fields['_dev_note_develop_your_own_template_1'] = array(
// 'type' => 'note',
// 'order' => 99,
// 'wrapper_classes' => 'sm:wu-p-0 sm:wu-block',
// 'classes' => '',
// 'desc' => sprintf('<div class="wu-p-4 wu-bg-blue-100 wu-text-grey-600">%s</div>', __('Want to add customized template selection templates?<br><a target="_blank" class="wu-no-underline" href="https://help.wpultimo.com/article/343-customize-your-checkout-flow-using-field-templates">See how you can do that here</a>.', 'wp-ultimo')),
// );
return $editor_fields;
} // end get_fields;
/**
* Treat the attributes array to avoid reaching the input var limits.
*
* @since 2.0.0
*
* @param array $attributes The attributes.
* @return array
*/
public function reduce_attributes($attributes) {
$array_sites = json_decode(json_encode($attributes['sites']), true);
$attributes['sites'] = array_values(array_column($array_sites, 'blog_id'));
return $attributes;
} // end reduce_attributes;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
$checkout_fields['template_id'] = array(
'type' => 'hidden',
'html_attr' => array(
'v-model' => 'template_id',
),
);
/**
* Hide when pre-selected.
*/
if (wu_should_hide_form_field($attributes)) {
return $checkout_fields;
} // end if;
if (wu_get_isset($attributes, 'template_selection_template') === 'legacy') {
wp_register_script('wu-legacy-signup', wu_get_asset('legacy-signup.js', 'js'), array('wu-functions'), wu_get_version());
wp_enqueue_script('wu-legacy-signup');
wp_enqueue_style('legacy-shortcodes', wu_get_asset('legacy-shortcodes.css', 'css'), array('dashicons'), wu_get_version());
} // end if;
$site_list = $this->site_list($attributes);
$customer_sites = array();
if (wu_get_setting('allow_own_site_as_template')) {
$customer = wu_get_current_customer();
if ($customer) {
$customer_sites = $customer->get_sites(array('fields' => 'ids'));
$site_list = array_merge(
$customer_sites,
$site_list
);
} // end if;
} // end if;
$sites = array_map('wu_get_site', $site_list);
$sites = array_filter($sites);
// Remove inactive sites
$sites = array_filter($sites, fn($site) => $site->is_active());
$template_attributes = array(
'sites' => $sites,
'name' => $attributes['name'],
'cols' => $attributes['cols'],
'categories' => $attributes['template_selection_categories'] ?? \WP_Ultimo\Models\Site::get_all_categories($sites),
'customer_sites' => $customer_sites,
);
$template_class = Field_Templates_Manager::get_instance()->get_template_class('template_selection', $attributes['template_selection_template']);
$content = $template_class ? $template_class->render_container($template_attributes, $this) : __('Template does not exist.', 'wp-ultimo');
$checkout_fields[$attributes['id']] = array(
'type' => 'note',
'desc' => $content,
'wrapper_classes' => $attributes['element_classes'],
);
return $checkout_fields;
} // end to_fields_array;
/**
* Return site list according to selection type used.
*
* @param array $attributes Attributes saved on the editor form.
* @return array Array of template ID's
*/
protected function site_list(array $attributes): array {
$selection_type = wu_get_isset($attributes, 'template_selection_type', 'name');
if ($selection_type === 'name') {
return explode(',', $attributes['template_selection_sites']);
} // end if;
if ($selection_type === 'all') {
return wu_get_site_templates(array('fields' => 'blog_id'));
} // end if;
if ($selection_type === 'categories') {
return array_column(
\WP_Ultimo\Models\Site::get_all_by_categories(
$attributes['template_selection_categories'],
array(
'fields' => array('blog_id'),
),
),
'blog_id'
);
} // end if;
return explode(',', $attributes['template_selection_sites']);
} // end site_list;
} // end class Signup_Field_Template_Selection;

@@ -0,0 +1,218 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Terms_Of_Use extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'terms_of_use';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return false;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Terms of Use', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a terms and conditions checkbox that must be marked before the account/site can be created.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a terms and conditions checkbox that must be marked before the account/site can be created.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-file-text';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'tou_name' => __('I agree with the terms of use.', 'wp-ultimo'),
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array();
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'terms_of_use',
'name' => __('Terms of Use', 'wp-ultimo'),
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'tou_name' => array(
'order' => 10,
'type' => 'text',
'title' => __('Terms Checkbox Label', 'wp-ultimo'),
'placeholder' => __('e.g. I agree with the terms of use.', 'wp-ultimo'),
),
'tou_url' => array(
'order' => 20,
'type' => 'url',
'title' => __('Link to the Terms Page', 'wp-ultimo'),
'desc' => __('Enter the link to the terms of use content.', 'wp-ultimo'),
'placeholder' => __('e.g. https://yoursite.com/terms', 'wp-ultimo'),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$checkout_fields = array();
$tou_link = sprintf('<a href="%s" target="_blank">%s</a>', $attributes['tou_url'], __('Read here', 'wp-ultimo'));
$checkout_fields['terms_of_use'] = array(
'type' => 'checkbox',
'id' => 'terms_of_use',
'name' => $attributes['tou_name'] . ' - ',
'desc' => $tou_link,
'wrapper_classes' => $attributes['element_classes'],
'required' => true,
);
return $checkout_fields;
} // end to_fields_array;
} // end class Signup_Field_Terms_Of_Use;

@@ -0,0 +1,194 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Text extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'text';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return false;
} // end is_required;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Text', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds a text field that the customer can fill with arbitrary data.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds a text field that the customer can fill with arbitrary data.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-edit-3';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
''
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'id',
'name',
'placeholder',
'default_value',
'tooltip',
'required',
'save_as',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array();
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array();
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
$fields = array(
$attributes['id'] => array(
'type' => 'text',
'id' => $attributes['id'],
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'required' => $attributes['required'],
'wrapper_classes' => $attributes['element_classes'],
'value' => $this->get_value(),
),
);
return $fields;
} // end to_fields_array;
} // end class Signup_Field_Text;

@@ -0,0 +1,251 @@
<?php
/**
* Creates a cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Order
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields;
use \WP_Ultimo\Checkout\Signup_Fields\Base_Signup_Field;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Creates an cart with the parameters of the purchase being placed.
*
* @package WP_Ultimo
* @subpackage Checkout
* @since 2.0.0
*/
class Signup_Field_Username extends Base_Signup_Field {
/**
* Returns the type of the field.
*
* @since 2.0.0
* @return string
*/
public function get_type() {
return 'username';
} // end get_type;
/**
* Returns if this field should be present on the checkout flow or not.
*
* @since 2.0.0
* @return boolean
*/
public function is_required() {
return true;
} // end is_required;
/**
* Is this a user-related field?
*
* If this is set to true, this field will be hidden
* when the user is already logged in.
*
* @since 2.0.0
* @return boolean
*/
public function is_user_field() {
return true;
} // end is_user_field;
/**
* Requires the title of the field/element type.
*
* This is used on the Field/Element selection screen.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Username', 'wp-ultimo');
} // end get_title;
/**
* Returns the description of the field/element.
*
* This is used as the title attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Adds an username field. This username will be used to create the WordPress user.', 'wp-ultimo');
} // end get_description;
/**
* Returns the tooltip of the field/element.
*
* This is used as the tooltip attribute of the selector.
*
* @since 2.0.0
* @return string
*/
public function get_tooltip() {
return __('Adds an username field. This username will be used to create the WordPress user.', 'wp-ultimo');
} // end get_tooltip;
/**
* Returns the icon to be used on the selector.
*
* Can be either a dashicon class or a wu-dashicon class.
*
* @since 2.0.0
* @return string
*/
public function get_icon() {
return 'dashicons-wu-user1';
} // end get_icon;
/**
* Returns the default values for the field-elements.
*
* This is passed through a wp_parse_args before we send the values
* to the method that returns the actual fields for the checkout form.
*
* @since 2.0.0
* @return array
*/
public function defaults() {
return array(
'auto_generate_username' => false,
);
} // end defaults;
/**
* List of keys of the default fields we want to display on the builder.
*
* @since 2.0.0
* @return array
*/
public function default_fields() {
return array(
'name',
'placeholder',
'tooltip',
);
} // end default_fields;
/**
* If you want to force a particular attribute to a value, declare it here.
*
* @since 2.0.0
* @return array
*/
public function force_attributes() {
return array(
'id' => 'username',
'required' => true,
);
} // end force_attributes;
/**
* Returns the list of additional fields specific to this type.
*
* @since 2.0.0
* @return array
*/
public function get_fields() {
return array(
'auto_generate_username' => array(
'type' => 'toggle',
'title' => __('Auto-generate', 'wp-ultimo'),
'desc' => __('Check this option to auto-generate this field based on the email address of the customer.', 'wp-ultimo'),
'tooltip' => '',
'value' => 0,
'html_attr' => array(
'v-model' => 'auto_generate_username',
),
),
);
} // end get_fields;
/**
* Returns the field/element actual field array to be used on the checkout form.
*
* @since 2.0.0
*
* @param array $attributes Attributes saved on the editor form.
* @return array An array of fields, not the field itself.
*/
public function to_fields_array($attributes) {
/*
* Logged in user, bail.
*/
if (is_user_logged_in()) {
return array();
} // end if;
if (isset($attributes['auto_generate_username']) && $attributes['auto_generate_username']) {
return array(
'auto_generate_username' => array(
'type' => 'hidden',
'id' => 'auto_generate_username',
'value' => 'email',
),
'username' => array(
'type' => 'hidden',
'id' => 'username',
'value' => uniqid(),
),
);
} // end if;
return array(
'username' => array(
'type' => 'text',
'id' => 'username',
'name' => $attributes['name'],
'placeholder' => $attributes['placeholder'],
'tooltip' => $attributes['tooltip'],
'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''),
'classes' => wu_get_isset($attributes, 'element_classes', ''),
'required' => true,
'value' => $this->get_value(),
'html_attr' => array(
'v-model' => 'username',
'v-init:username' => "'{$this->get_value()}'",
'autocomplete' => 'username',
),
'wrapper_html_attr' => array(
'style' => $this->calculate_style_attr(),
),
),
);
} // end to_fields_array;
} // end class Signup_Field_Username;

@@ -0,0 +1,175 @@
<?php
/**
* Base Field Template
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* Base Field Template
*
* @since 2.0.0
*/
class Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id;
/**
* @var array
*/
protected $attributes = array();
/**
* Field Template Constructor
*
* @since 2.0.0
*
* @param array $attributes The attributes passed to the field.
*/
public function __construct($attributes = array())
{
$this->attributes = $attributes;
} // end __construct;
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'ajax';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Field Template', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Description', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
*/
public function get_preview(): string {
return '';
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {} // end output;
/**
* Renders the content.
*
* This method should not be override.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return string
*/
public function render($attributes) {
ob_start();
$this->output($attributes);
return ob_get_clean();
} // end render;
/**
* Displays the content on the checkout form as a wrapper.
*
* This method should not be override.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @param object $signup_field The base field.
* @return string
*/
public function render_container($attributes, $signup_field = false) {
if ($this->get_render_type() === 'ajax') {
if ($signup_field) {
$attributes = $signup_field->reduce_attributes($attributes);
} // end if;
$markup = sprintf('<dynamic :template="get_template(\'%s\', %s)"></dynamic>', esc_js($this->id), esc_attr(json_encode($attributes)));
} else {
$markup = $this->render($attributes);
} // end if;
return $markup;
} // end render_container;
} // end class Base_Field_Template;

@@ -0,0 +1,115 @@
<?php
/**
* Order Summary Simple
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Order_Bump;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Simple
*
* @since 2.0.0
*/
class Simple_Order_Bump_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'order-bump/simple';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'ajax';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Simple', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple layout with minimal styling, just enough to make it usable out-of-the-box.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/clean-template-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
/**
* Loads the actual order-bump template
*/
wu_get_template('checkout/templates/order-bump/simple', $attributes);
} // end output;
} // end class Simple_Order_Bump_Field_Template;

@@ -0,0 +1,115 @@
<?php
/**
* Order Summary Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Order_Summary;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Order Summary Clean
*
* @since 2.0.0
*/
class Clean_Order_Summary_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'order-summary/simple';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Clean', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple layout with minimal styling, just enough to make it usable out-of-the-box.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/clean-order-summary.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
/**
* Loads the actual order-summary template
*/
wu_get_template('checkout/templates/order-summary/simple', $attributes);
} // end output;
} // end class Clean_Order_Summary_Field_Template;

@@ -0,0 +1,114 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Period_Selection;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Clean_Period_Selection_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'period-selection/clean';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Clean', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple template with clean markup and no styling, ready to be customized with custom CSS.', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/clean-period-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/period-selection/clean', $attributes);
} // end output;
} // end class Clean_Period_Selection_Field_Template;

@@ -0,0 +1,114 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Period_Selection;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Legacy_Period_Selection_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'period-selection/legacy';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Legacy', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Implementation of the layout that shipped with WP Ultimo < 1.10.X.', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/legacy-period-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/period-selection/legacy', $attributes);
} // end output;
} // end class Legacy_Period_Selection_Field_Template;

@@ -0,0 +1,114 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Pricing_Table;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Legacy_Pricing_Table_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'pricing-table/legacy';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Legacy', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Implementation of the layout that shipped with WP Ultimo < 1.10.X.', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/legacy-pricing-table.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/pricing-table/legacy', $attributes);
} // end output;
} // end class Legacy_Pricing_Table_Field_Template;

@@ -0,0 +1,91 @@
<?php
/**
* Base Field Template
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Pricing_Table;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Base Field Template
*
* @since 2.0.0
*/
class List_Pricing_Table_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'pricing-table/list';
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Simple List', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Simple stylized list with price, recurrence, and the plan description.', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/list-pricing-table.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/pricing-table/list', $attributes);
} // end output;
} // end class List_Pricing_Table_Field_Template;

@@ -0,0 +1,112 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Steps;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Clean_Steps_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'steps/clean';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Clean', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple layout with minimal styling, just enough to make it usable out-of-the-box.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/clean-steps.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/steps/clean', $attributes);
} // end output;
} // end class Clean_Steps_Field_Template;

@@ -0,0 +1,112 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Steps;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Legacy_Steps_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'steps/legacy';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Legacy', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Implementation of the layout that shipped with WP Ultimo < 1.10.X.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/legacy-steps.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/steps/legacy', $attributes);
} // end output;
} // end class Legacy_Steps_Field_Template;

@@ -0,0 +1,112 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Steps;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Minimal_Steps_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'steps/minimal';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'dynamic';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Minimal', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple template with clean markup and no styling, ready to be customized with custom CSS.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/minimal-steps.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/steps/minimal', $attributes);
} // end output;
} // end class Minimal_Steps_Field_Template;

@@ -0,0 +1,112 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Template_Selection;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Clean
*
* @since 2.0.0
*/
class Clean_Template_Selection_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'template-selection/clean';
/**
* The render type for the template.
*
* Field templates can have two different render types, ajax and dynamic.
* If ajax is selected, when we detect a change in the billing period and other
* sensitive info, an ajax request is made to fetch the new pricing table HTML
* markup.
*
* If dynamic is selected, nothing is done as the template can handle
* reactive updates natively (using Vue.js)
*
* In terms of performance, dynamic is preferred, but ajax should
* work just fine.
*
* @since 2.0.0
* @return string Either ajax or dynamic
*/
public function get_render_type(): string {
return 'ajax';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Clean', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description(): string {
return __('A simple layout with minimal styling, just enough to make it usable out-of-the-box.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/clean-template-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/template-selection/clean', $attributes);
} // end output;
} // end class Clean_Template_Selection_Field_Template;

@@ -0,0 +1,103 @@
<?php
/**
* Legacy Field Template Selector
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Template_Selection;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Legacy Field Template Selector
*
* @since 2.0.0
*/
class Legacy_Template_Selection_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'template-selection/legacy';
/**
* Get render type for the template.
*
* @since 2.0.0
* @return string
*/
public function get_render_type(): string {
return 'ajax';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Legacy', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('Implementation of the layout that shipped with WP Ultimo < 1.10.X.', 'wp-ultimo');
} // end get_description;
/**
* The preview image of the field template.
*
* The URL of the image preview.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/legacy-template-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/template-selection/legacy', $attributes);
} // end output;
} // end class Legacy_Template_Selection_Field_Template;

@@ -0,0 +1,101 @@
<?php
/**
* Template Selection Clean
*
* @package WP_Ultimo
* @subpackage Checkout\Signup_Fields
* @since 2.0.0
*/
namespace WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Template_Selection;
// Exit if accessed directly
defined('ABSPATH') || exit;
use \WP_Ultimo\Checkout\Signup_Fields\Field_Templates\Base_Field_Template;
/**
* Template Selection Minimal
*
* @since 2.0.0
*/
class Minimal_Template_Selection_Field_Template extends Base_Field_Template {
/**
* Field template id.
*
* Needs to take the following format: field-type/id.
* e.g. pricing-table/clean.
*
* @since 2.0.0
* @var string
*/
protected $id = 'template-selection/minimal';
/**
* Get render type for the template.
*
* @since 2.0.0
* @return string
*/
public function get_render_type(): string {
return 'ajax';
} // end get_render_type;
/**
* The title of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_title() {
return __('Minimal', 'wp-ultimo');
} // end get_title;
/**
* The description of the field template.
*
* This is used on the template selector.
*
* @since 2.0.0
* @return string
*/
public function get_description() {
return __('A simple template with clean markup and no styling, ready to be customized with custom CSS.', 'wp-ultimo');
} // end get_description;
/**
* The preview of the field template.
*
* @since 2.0.0
* @return string
*/
public function get_preview(): string {
return wu_get_asset('checkout-forms/minimal-template-selection.png');
} // end get_preview;
/**
* The content of the template.
*
* @since 2.0.0
*
* @param array $attributes The field template attributes.
* @return void
*/
public function output($attributes) {
wu_get_template('checkout/templates/template-selection/minimal', $attributes);
} // end output;
} // end class Minimal_Template_Selection_Field_Template;