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

@@ -0,0 +1,44 @@
<?php
namespace WP_Ultimo\Dependencies;
/**
* Autoloader.
*
* @package Database
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 2.0.0
*/
// Exit if accessed directly.
\defined('ABSPATH') || exit;
// Register a closure to autoload BerlinDB.
\spl_autoload_register(
/**
* Closure of the autoloader.
*
* @param string $class_name The fully-qualified class name.
* @return void
*/
static function ($class_name = '') {
// Project namespace & length.
$project_namespace = 'BerlinDB\\Database\\';
$length = \strlen($project_namespace);
// Bail if class is not in this namespace.
if (0 !== \strncmp($project_namespace, $class_name, $length)) {
return;
}
// Setup file parts.
$format = '%1$s/src/%2$s.php';
$path = __DIR__;
$name = \str_replace('\\', '/', \substr($class_name, $length));
// Parse class and namespace to file.
$file = \sprintf($format, $path, $name);
// Bail if file does not exist.
if (!\is_file($file)) {
return;
}
// Require the file.
require_once $file;
}
);

@@ -0,0 +1,298 @@
<?php
/**
* Base Custom Database Class.
*
* @package Database
* @subpackage Base
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* The base class that all other database base classes extend.
*
* This class attempts to provide some universal immutability to all other
* classes that extend it, starting with a magic getter, but likely expanding
* into a magic call handler and others.
*
* @since 1.0.0
*/
class Base
{
/**
* The name of the PHP global that contains the primary database interface.
*
* For example, WordPress traditionally uses 'wpdb', but other applications
* may use something else, or you may be doing something really cool that
* requires a custom interface.
*
* A future version of this utility may abstract this out entirely, so
* custom calls to the get_db() should be avoided if at all possible.
*
* @since 1.0.0
* @var string
*/
protected $db_global = 'wpdb';
/** Global Properties *****************************************************/
/**
* Global prefix used for tables/hooks/cache-groups/etc...
*
* @since 1.0.0
* @var string
*/
protected $prefix = '';
/**
* The last database error, if any.
*
* @since 1.0.0
* @var mixed
*/
protected $last_error = \false;
/** Public ****************************************************************/
/**
* Magic isset'ter for immutability.
*
* @since 1.0.0
*
* @param string $key
* @return mixed
*/
public function __isset($key = '')
{
// No more uppercase ID properties ever
if ('ID' === $key) {
$key = 'id';
}
// Class method to try and call
$method = "get_{$key}";
// Return property if exists
if (\method_exists($this, $method)) {
return \true;
// Return get method results if exists
} elseif (\property_exists($this, $key)) {
return \true;
}
// Return false if not exists
return \false;
}
/**
* Magic getter for immutability.
*
* @since 1.0.0
*
* @param string $key
* @return mixed
*/
public function __get($key = '')
{
// No more uppercase ID properties ever
if ('ID' === $key) {
$key = 'id';
}
// Class method to try and call
$method = "get_{$key}";
// Return property if exists
if (\method_exists($this, $method)) {
return \call_user_func(array($this, $method));
// Return get method results if exists
} elseif (\property_exists($this, $key)) {
return $this->{$key};
}
// Return null if not exists
return null;
}
/**
* Converts the given object to an array.
*
* @since 1.0.0
*
* @return array Array version of the given object.
*/
public function to_array()
{
return \get_object_vars($this);
}
/** Protected *************************************************************/
/**
* Maybe append the prefix to string.
*
* @since 1.0.0
*
* @param string $string
* @param string $sep
* @return string
*/
protected function apply_prefix($string = '', $sep = '_')
{
return !empty($this->prefix) ? "{$this->prefix}{$sep}{$string}" : $string;
}
/**
* Return the first letters of a string of words with a separator.
*
* Used primarily to guess at table aliases when none is manually set.
*
* Applies the following formatting to a string:
* - Trim whitespace
* - No accents
* - No trailing underscores
*
* @since 1.0.0
*
* @param string $string
* @param string $sep
* @return string
*/
protected function first_letters($string = '', $sep = '_')
{
// Set empty default return value
$retval = '';
// Bail if empty or not a string
if (empty($string) || !\is_string($string)) {
return $retval;
}
// Trim spaces off the ends
$unspace = \trim($string);
// Only non-accented table names (avoid truncation)
$accents = remove_accents($unspace);
// Only lowercase letters are allowed
$lower = \strtolower($accents);
// Explode into parts
$parts = \explode($sep, $lower);
// Loop through parts and concatenate the first letters together
foreach ($parts as $part) {
$retval .= \substr($part, 0, 1);
}
// Return the result
return $retval;
}
/**
* Sanitize a table name string.
*
* Used to make sure that a table name value meets MySQL expectations.
*
* Applies the following formatting to a string:
* - Trim whitespace
* - No accents
* - No special characters
* - No hyphens
* - No double underscores
* - No trailing underscores
*
* @since 1.0.0
*
* @param string $name The name of the database table
*
* @return string Sanitized database table name
*/
protected function sanitize_table_name($name = '')
{
// Bail if empty or not a string
if (empty($name) || !\is_string($name)) {
return \false;
}
// Trim spaces off the ends
$unspace = \trim($name);
// Only non-accented table names (avoid truncation)
$accents = remove_accents($unspace);
// Only lowercase characters, hyphens, and dashes (avoid index corruption)
$lower = sanitize_key($accents);
// Replace hyphens with single underscores
$under = \str_replace('-', '_', $lower);
// Single underscores only
$single = \str_replace('__', '_', $under);
// Remove trailing underscores
$clean = \trim($single, '_');
// Bail if table name was garbaged
if (empty($clean)) {
return \false;
}
// Return the cleaned table name
return $clean;
}
/**
* Set class variables from arguments.
*
* @since 1.0.0
* @param array $args
*/
protected function set_vars($args = array())
{
// Bail if empty or not an array
if (empty($args)) {
return;
}
// Cast to an array
if (!\is_array($args)) {
$args = (array) $args;
}
// Set all properties
foreach ($args as $key => $value) {
$this->{$key} = $value;
}
}
/**
* Return the global database interface.
*
* See: https://core.trac.wordpress.org/ticket/31556
*
* @since 1.0.0
*
* @return \wpdb Database interface, or False if not set
*/
protected function get_db()
{
// Default database return value (might change)
$retval = \false;
// Look for a commonly used global database interface
if (isset($GLOBALS[$this->db_global])) {
$retval = $GLOBALS[$this->db_global];
}
/*
* Developer note:
*
* It should be impossible for a database table to be interacted with
* before the primary database interface is setup.
*
* However, because applications are complicated, it is unsafe to assume
* anything, so this silently returns false instead of halting everything.
*
* If you are here because this method is returning false for you, that
* means the database table is being invoked too early in the lifecycle
* of the application.
*
* In WordPress, that means before the $wpdb global is created; in other
* environments, you will need to adjust accordingly.
*/
// Return the database interface
return $retval;
}
/**
* Check if an operation succeeded.
*
* @since 1.0.0
*
* @param mixed $result
* @return bool
*/
protected function is_success($result = \false)
{
// Bail if no row exists
if (empty($result)) {
$retval = \false;
// Bail if an error occurred
} elseif (is_wp_error($result)) {
$this->last_error = $result;
$retval = \false;
// No errors
} else {
$retval = \true;
}
// Return the result
return (bool) $retval;
}
}

@@ -0,0 +1,803 @@
<?php
/**
* Base Custom Database Table Column Class.
*
* @package Database
* @subpackage Column
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* Base class used for each column for a custom table.
*
* @since 1.0.0
*
* @see Column::__construct() for accepted arguments.
*/
class Column extends Base
{
/** Table Attributes ******************************************************/
/**
* Name for the database column.
*
* Required. Must contain lowercase alphabetical characters only. Use of any
* other character (number, ascii, unicode, emoji, etc...) will result in
* fatal application errors.
*
* @since 1.0.0
* @var string
*/
public $name = '';
/**
* Type of database column.
*
* See: https://dev.mysql.com/doc/en/data-types.html
*
* @since 1.0.0
* @var string
*/
public $type = '';
/**
* Length of database column.
*
* See: https://dev.mysql.com/doc/en/storage-requirements.html
*
* @since 1.0.0
* @var string
*/
public $length = \false;
/**
* Is integer unsigned?
*
* See: https://dev.mysql.com/doc/en/numeric-type-overview.html
*
* @since 1.0.0
* @var bool
*/
public $unsigned = \true;
/**
* Is integer filled with zeroes?
*
* See: https://dev.mysql.com/doc/en/numeric-type-overview.html
*
* @since 1.0.0
* @var bool
*/
public $zerofill = \false;
/**
* Is data in a binary format?
*
* See: https://dev.mysql.com/doc/en/binary-varbinary.html
*
* @since 1.0.0
* @var bool
*/
public $binary = \false;
/**
* Is null an allowed value?
*
* See: https://dev.mysql.com/doc/en/data-type-defaults.html
*
* @since 1.0.0
* @var bool
*/
public $allow_null = \false;
/**
* Typically empty/null, or date value.
*
* See: https://dev.mysql.com/doc/en/data-type-defaults.html
*
* @since 1.0.0
* @var string
*/
public $default = '';
/**
* auto_increment, etc...
*
* See: https://dev.mysql.com/doc/en/data-type-defaults.html
*
* @since 1.0.0
* @var string
*/
public $extra = '';
/**
* Typically inherited from the database interface (wpdb).
*
* By default, this will use the globally available database encoding. You
* most likely do not want to change this; if you do, you already know what
* to do.
*
* See: https://dev.mysql.com/doc/mysql/en/charset-column.html
*
* @since 1.0.0
* @var string
*/
public $encoding = '';
/**
* Typically inherited from the database interface (wpdb).
*
* By default, this will use the globally available database collation. You
* most likely do not want to change this; if you do, you already know what
* to do.
*
* See: https://dev.mysql.com/doc/mysql/en/charset-column.html
*
* @since 1.0.0
* @var string
*/
public $collation = '';
/**
* Typically empty; probably ignore.
*
* By default, columns do not have comments. This is unused by any other
* relative code, but you can include less than 1024 characters here.
*
* @since 1.0.0
* @var string
*/
public $comment = '';
/** Special Attributes ****************************************************/
/**
* Is this the primary column?
*
* By default, columns are not the primary column. This is used by the Query
* class for several critical functions, including (but not limited to) the
* cache key, meta-key relationships, auto-incrementing, etc...
*
* @since 1.0.0
* @var bool
*/
public $primary = \false;
/**
* Is this the column used as a created date?
*
* By default, columns do not represent the date a value was first entered.
* This is used by the Query class to set its value automatically to the
* current datetime value immediately before insert.
*
* @since 1.0.0
* @var bool
*/
public $created = \false;
/**
* Is this the column used as a modified date?
*
* By default, columns do not represent the date a value was last changed.
* This is used by the Query class to update its value automatically to the
* current datetime value immediately before insert|update.
*
* @since 1.0.0
* @var bool
*/
public $modified = \false;
/**
* Is this the column used as a unique universal identifier?
*
* By default, columns are not UUIDs. This is used by the Query class to
* generate a unique string that can be used to identify a row in a database
* table, typically in such a way that is unrelated to the row data itself.
*
* @since 1.0.0
* @var bool
*/
public $uuid = \false;
/** Query Attributes ******************************************************/
/**
* What is the string-replace pattern?
*
* By default, column patterns will be guessed based on their type. Set this
* manually to `%s|%d|%f` only if you are doing something weird, or are
* explicitly storing numeric values in text-based column types.
*
* @since 1.0.0
* @var string
*/
public $pattern = '';
/**
* Is this column searchable?
*
* By default, columns are not searchable. When `true`, the Query class will
* add this column to the results of search queries.
*
* Avoid setting to `true` on large blobs of text, unless you've optimized
* your database server to accommodate these kinds of queries.
*
* @since 1.0.0
* @var bool
*/
public $searchable = \false;
/**
* Is this column a date?
*
* By default, columns do not support date queries. When `true`, the Query
* class will accept complex statements to help narrow results down to
* specific periods of time for values in this column.
*
* @since 1.0.0
* @var bool
*/
public $date_query = \false;
/**
* Is this column used in orderby?
*
* By default, columns are not sortable. This ensures that the database
* table does not perform costly operations on unindexed columns or columns
* of an inefficient type.
*
* You can safely turn this on for most numeric columns, indexed columns,
* and text columns with intentionally limited lengths.
*
* @since 1.0.0
* @var bool
*/
public $sortable = \false;
/**
* Is __in supported?
*
* By default, columns support being queried using an `IN` statement. This
* allows the Query class to retrieve rows that match your array of values.
*
* Consider setting this to `false` for longer text columns.
*
* @since 1.0.0
* @var bool
*/
public $in = \true;
/**
* Is __not_in supported?
*
* By default, columns support being queried using a `NOT IN` statement.
* This allows the Query class to retrieve rows that do not match your array
* of values.
*
* Consider setting this to `false` for longer text columns.
*
* @since 1.0.0
* @var bool
*/
public $not_in = \true;
/** Cache Attributes ******************************************************/
/**
* Does this column have its own cache key?
*
* By default, only primary columns are used as cache keys. If this column
* is unique, or is frequently used to get database results, you may want to
* consider setting this to true.
*
* Use in conjunction with a database index for speedy queries.
*
* @since 1.0.0
* @var string
*/
public $cache_key = \false;
/** Action Attributes *****************************************************/
/**
* Does this column fire a transition action when it's value changes?
*
* By default, columns do not fire transition actions. In some cases, it may
* be desirable to know when a database value changes, and what the old and
* new values are when that happens.
*
* The Query class is responsible for triggering the event action.
*
* @since 1.0.0
* @var bool
*/
public $transition = \false;
/** Callback Attributes ***************************************************/
/**
* Maybe validate this data before it is written to the database.
*
* By default, column data is validated based on the type of column that it
* is. You can set this to a callback function of your choice to override
* the default validation behavior.
*
* @since 1.0.0
* @var string
*/
public $validate = '';
/**
* Array of capabilities used to interface with this column.
*
* These are used by the Query class to allow and disallow CRUD access to
* column data, typically based on roles or capabilities.
*
* @since 1.0.0
* @var array
*/
public $caps = array();
/**
* Array of possible aliases this column can be referred to as.
*
* These are used by the Query class to allow for columns to be renamed
* without requiring complex architectural backwards compatibility support.
*
* @since 1.0.0
* @var array
*/
public $aliases = array();
/**
* Array of possible relationships this column has with columns in other
* database tables.
*
* These are typically unenforced foreign keys, and are used by the Query
* class to help prime related items.
*
* @since 1.0.0
* @var array
*/
public $relationships = array();
/** Methods ***************************************************************/
/**
* Sets up the order query, based on the query vars passed.
*
* @since 1.0.0
*
* @param string|array $args {
* Optional. Array or query string of order query parameters. Default empty.
*
* @type string $name Name of database column
* @type string $type Type of database column
* @type int $length Length of database column
* @type bool $unsigned Is integer unsigned?
* @type bool $zerofill Is integer filled with zeroes?
* @type bool $binary Is data in a binary format?
* @type bool $allow_null Is null an allowed value?
* @type mixed $default Typically empty/null, or date value
* @type string $extra auto_increment, etc...
* @type string $encoding Typically inherited from wpdb
* @type string $collation Typically inherited from wpdb
* @type string $comment Typically empty
* @type bool $pattern What is the string-replace pattern?
* @type bool $primary Is this the primary column?
* @type bool $created Is this the column used as a created date?
* @type bool $modified Is this the column used as a modified date?
* @type bool $uuid Is this the column used as a universally unique identifier?
* @type bool $searchable Is this column searchable?
* @type bool $sortable Is this column used in orderby?
* @type bool $date_query Is this column a datetime?
* @type bool $in Is __in supported?
* @type bool $not_in Is __not_in supported?
* @type bool $cache_key Is this column queried independently?
* @type bool $transition Does this column transition between changes?
* @type string $validate A callback function used to validate on save.
* @type array $caps Array of capabilities to check.
* @type array $aliases Array of possible column name aliases.
* @type array $relationships Array of columns in other tables this column relates to.
* }
*/
public function __construct($args = array())
{
// Parse arguments
$r = $this->parse_args($args);
// Maybe set variables from arguments
if (!empty($r)) {
$this->set_vars($r);
}
}
/** Argument Handlers *****************************************************/
/**
* Parse column arguments
*
* @since 1.0.0
* @param array $args Default empty array.
* @return array
*/
private function parse_args($args = array())
{
// Parse arguments
$r = wp_parse_args($args, array(
// Table
'name' => '',
'type' => '',
'length' => '',
'unsigned' => \false,
'zerofill' => \false,
'binary' => \false,
'allow_null' => \false,
'default' => '',
'extra' => '',
'encoding' => $this->get_db()->charset,
'collation' => $this->get_db()->collate,
'comment' => '',
// Query
'pattern' => \false,
'searchable' => \false,
'sortable' => \false,
'date_query' => \false,
'transition' => \false,
'in' => \true,
'not_in' => \true,
// Special
'primary' => \false,
'created' => \false,
'modified' => \false,
'uuid' => \false,
// Cache
'cache_key' => \false,
// Validation
'validate' => '',
// Capabilities
'caps' => array(),
// Backwards Compatibility
'aliases' => array(),
// Column Relationships
'relationships' => array(),
));
// Force some arguments for special column types
$r = $this->special_args($r);
// Set the args before they are sanitized
$this->set_vars($r);
// Return array
return $this->validate_args($r);
}
/**
* Validate arguments after they are parsed.
*
* @since 1.0.0
* @param array $args Default empty array.
* @return array
*/
private function validate_args($args = array())
{
// Sanitization callbacks
$callbacks = array('name' => 'sanitize_key', 'type' => 'strtoupper', 'length' => 'intval', 'unsigned' => 'wp_validate_boolean', 'zerofill' => 'wp_validate_boolean', 'binary' => 'wp_validate_boolean', 'allow_null' => 'wp_validate_boolean', 'default' => array($this, 'sanitize_default'), 'extra' => 'wu_kses_data', 'encoding' => 'wu_kses_data', 'collation' => 'wu_kses_data', 'comment' => 'wu_kses_data', 'primary' => 'wp_validate_boolean', 'created' => 'wp_validate_boolean', 'modified' => 'wp_validate_boolean', 'uuid' => 'wp_validate_boolean', 'searchable' => 'wp_validate_boolean', 'sortable' => 'wp_validate_boolean', 'date_query' => 'wp_validate_boolean', 'transition' => 'wp_validate_boolean', 'in' => 'wp_validate_boolean', 'not_in' => 'wp_validate_boolean', 'cache_key' => 'wp_validate_boolean', 'pattern' => array($this, 'sanitize_pattern'), 'validate' => array($this, 'sanitize_validation'), 'caps' => array($this, 'sanitize_capabilities'), 'aliases' => array($this, 'sanitize_aliases'), 'relationships' => array($this, 'sanitize_relationships'));
// Default args array
$r = array();
// Loop through and try to execute callbacks
foreach ($args as $key => $value) {
// Callback is callable
if (isset($callbacks[$key]) && \is_callable($callbacks[$key])) {
$r[$key] = \call_user_func($callbacks[$key], $value ?? "");
// Callback is malformed so just let it through to avoid breakage
} else {
$r[$key] = $value;
}
}
// Return sanitized arguments
return $r;
}
/**
* Force column arguments for special column types
*
* @since 1.0.0
* @param array $args Default empty array.
* @return array
*/
private function special_args($args = array())
{
// Primary key columns are always used as cache keys
if (!empty($args['primary'])) {
$args['cache_key'] = \true;
// All UUID columns need to follow a very specific pattern
} elseif (!empty($args['uuid'])) {
$args['name'] = 'uuid';
$args['type'] = 'varchar';
$args['length'] = '100';
$args['in'] = \false;
$args['not_in'] = \false;
$args['searchable'] = \false;
$args['sortable'] = \false;
}
// Return args
return (array) $args;
}
/** Public Helpers ********************************************************/
/**
* Return if a column type is numeric or not.
*
* @since 1.0.0
* @return bool
*/
public function is_numeric()
{
return $this->is_type(array('tinyint', 'int', 'mediumint', 'bigint'));
}
/** Private Helpers *******************************************************/
/**
* Return if this column is of a certain type.
*
* @since 1.0.0
* @param mixed $type Default empty string. The type to check. Also accepts an array.
* @return bool True if of type, False if not
*/
private function is_type($type = '')
{
// If string, cast to array
if (\is_string($type)) {
$type = (array) $type;
}
// Make them lowercase
$types = \array_map('strtolower', $type);
// Return if match or not
return (bool) \in_array(\strtolower($this->type), $types, \true);
}
/** Private Sanitizers ****************************************************/
/**
* Sanitize capabilities array
*
* @since 1.0.0
* @param array $caps Default empty array.
* @return array
*/
private function sanitize_capabilities($caps = array())
{
return wp_parse_args($caps, array('select' => 'exist', 'insert' => 'exist', 'update' => 'exist', 'delete' => 'exist'));
}
/**
* Sanitize aliases array using `sanitize_key()`
*
* @since 1.0.0
* @param array $aliases Default empty array.
* @return array
*/
private function sanitize_aliases($aliases = array())
{
return \array_map('sanitize_key', $aliases);
}
/**
* Sanitize relationships array
*
* @todo
* @since 1.0.0
* @param array $relationships Default empty array.
* @return array
*/
private function sanitize_relationships($relationships = array())
{
return \array_filter($relationships);
}
/**
* Sanitize the default value
*
* @since 1.0.0
* @param string $default
* @return string|null
*/
private function sanitize_default($default = '')
{
// Null
if (\true === $this->allow_null && \is_null($default)) {
return null;
// String
} elseif (\is_string($default)) {
return wu_kses_data($default);
// Integer
} elseif ($this->is_numeric()) {
return (int) $default;
}
// @todo datetime, decimal, and other column types
// Unknown, so return the default's default
return '';
}
/**
* Sanitize the pattern
*
* @since 1.0.0
* @param string $pattern
* @return string
*/
private function sanitize_pattern($pattern = '%s')
{
// Allowed patterns
$allowed_patterns = array('%s', '%d', '%f');
// Return pattern if allowed
if (\in_array($pattern, $allowed_patterns, \true)) {
return $pattern;
}
// Fallback to digit or string
return $this->is_numeric() ? '%d' : '%s';
}
/**
* Sanitize the validation callback
*
* @since 1.0.0
* @param string $callback Default empty string. A callable PHP function name or method
* @return string The most appropriate callback function for the value
*/
private function sanitize_validation($callback = '')
{
// Return callback if it's callable
if (\is_callable($callback)) {
return $callback;
}
// UUID special column
if (\true === $this->uuid) {
$callback = array($this, 'validate_uuid');
// Datetime fallback
} elseif ($this->is_type('datetime')) {
$callback = array($this, 'validate_datetime');
// Decimal fallback
} elseif ($this->is_type('decimal')) {
$callback = array($this, 'validate_decimal');
// Intval fallback
} elseif ($this->is_numeric()) {
$callback = 'intval';
}
// Return the callback
return $callback;
}
/** Public Validators *****************************************************/
/**
* Fallback to validate a datetime value if no other is set.
*
* This assumes NO_ZERO_DATES is off or overridden.
*
* If MySQL drops support for zero dates, this method will need to be
* updated to support different default values based on the environment.
*
* @since 1.0.0
* @param string $value Default ''. A datetime value that needs validating
* @return string A valid datetime value
*/
public function validate_datetime($value = '')
{
// Handle "empty" values
if (empty($value) || '0000-00-00 00:00:00' === $value) {
$value = !empty($this->default) ? $this->default : '';
// Convert to MySQL datetime format via gmdate() && strtotime
} elseif (\function_exists('gmdate')) {
$value = \gmdate('Y-m-d H:i:s', \strtotime($value));
}
// Return the validated value
return $value;
}
/**
* Validate a decimal
*
* (Recommended decimal column length is '18,9'.)
*
* This is used to validate a mixed value before it is saved into a decimal
* column in a database table.
*
* Uses number_format() which does rounding to the last decimal if your
* value is longer than specified.
*
* @since 1.0.0
* @param mixed $value Default empty string. The decimal value to validate
* @param int $decimals Default 9. The number of decimal points to accept
* @return float
*/
public function validate_decimal($value = 0, $decimals = 9)
{
// Protect against non-numeric values
if (!\is_numeric($value)) {
$value = 0;
}
// Protect against non-numeric decimals
if (!\is_numeric($decimals)) {
$decimals = 9;
}
// Is the value negative?
$negative_exponent = $value < 0 ? -1 : 1;
// Only numbers and period
$value = \preg_replace('/[^0-9\\.]/', '', (string) $value);
// Format to number of decimals, and cast as float
$formatted = \number_format($value, $decimals, '.', '');
// Adjust for negative values
$retval = $formatted * $negative_exponent;
// Return
return $retval;
}
/**
* Validate a UUID.
*
* This uses the v4 algorithm to generate a UUID that is used to uniquely
* and universally identify a given database row without any direct
* connection or correlation to the data in that row.
*
* From http://php.net/manual/en/function.uniqid.php#94959
*
* @since 1.0.0
* @param string $value The UUID value (empty on insert, string on update)
* @return string Generated UUID.
*/
public function validate_uuid($value = '')
{
// Default URN UUID prefix
$prefix = 'urn:uuid:';
// Bail if not empty and correctly prefixed
// (UUIDs should _never_ change once they are set)
if (!empty($value) && 0 === \strpos($value, $prefix)) {
return $value;
}
// Put the pieces together
$value = \sprintf(
"{$prefix}%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
// 32 bits for "time_low"
\mt_rand(0, 0xffff),
\mt_rand(0, 0xffff),
// 16 bits for "time_mid"
\mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
\mt_rand(0, 0xfff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
\mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
\mt_rand(0, 0xffff),
\mt_rand(0, 0xffff),
\mt_rand(0, 0xffff)
);
// Return the new UUID
return $value;
}
/** Table Helpers *********************************************************/
/**
* Return a string representation of what this column's properties look like
* in a MySQL.
*
* @todo
* @since 1.0.0
* @return string
*/
public function get_create_string()
{
// Default return val
$retval = '';
// Bail if no name
if (!empty($this->name)) {
$retval .= $this->name;
}
// Type
if (!empty($this->type)) {
$retval .= " {$this->type}";
}
// Length
if (!empty($this->length)) {
$retval .= '(' . $this->length . ')';
}
// Unsigned
if (!empty($this->unsigned)) {
$retval .= " unsigned";
}
// Zerofill
if (!empty($this->zerofill)) {
// TBD
}
// Binary
if (!empty($this->binary)) {
// TBD
}
// Allow null
if (!empty($this->allow_null)) {
$retval .= " NOT NULL ";
}
// Default
if (!empty($this->default)) {
$retval .= " default '{$this->default}'";
// A literal false means no default value
} elseif (\false !== $this->default) {
// Numeric
if ($this->is_numeric()) {
$retval .= " default '0'";
} elseif ($this->is_type('datetime')) {
$retval .= " default '0000-00-00 00:00:00'";
} else {
$retval .= " default ''";
}
}
// Extra
if (!empty($this->extra)) {
$retval .= " {$this->extra}";
}
// Encoding
if (!empty($this->encoding)) {
} else {
}
// Collation
if (!empty($this->collation)) {
} else {
}
// Return the create string
return $retval;
}
}

@@ -0,0 +1,131 @@
<?php
/**
* Base Custom Database Table Compare Query Class.
*
* @package Database
* @subpackage Compare
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database\Queries;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* Class used for generating SQL for compare clauses.
*
* This class is used to generate the SQL when a `compare` argument is passed to
* the `Base` query class. It extends `Meta` so the `compare` key accepts
* the same parameters as the ones passed to `Meta`.
*
* @since 1.0.0
*/
class Compare extends Meta
{
// All supported SQL comparisons
const ALL_COMPARES = array('=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP', 'RLIKE');
// IN and BETWEEN
const IN_BETWEEN_COMPARES = array('IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN');
/**
* Generate SQL WHERE clauses for a first-order query clause.
*
* "First-order" means that it's an array with a 'key' or 'value'.
*
* @since 1.0.0
*
* @param array $clause Query clause (passed by reference).
* @param array $parent_query Parent query array.
* @param string $clause_key Optional. The array key used to name the clause in the original `$meta_query`
* parameters. If not provided, a key will be generated automatically.
* @return array {
* Array containing WHERE SQL clauses to append to a first-order query.
*
* @type string $where SQL fragment to append to the main WHERE clause.
* }
*/
public function get_sql_for_clause(&$clause, $parent_query, $clause_key = '')
{
global $wpdb;
// Default chunks
$sql_chunks = array('where' => array(), 'join' => array());
// Maybe format compare clause
if (isset($clause['compare'])) {
$clause['compare'] = \strtoupper($clause['compare']);
// Or set compare clause based on value
} else {
$clause['compare'] = isset($clause['value']) && \is_array($clause['value']) ? 'IN' : '=';
}
// Fallback to equals
if (!\in_array($clause['compare'], self::ALL_COMPARES, \true)) {
$clause['compare'] = '=';
}
// Uppercase or equals
if (isset($clause['compare_key']) && 'LIKE' === \strtoupper($clause['compare_key'])) {
$clause['compare_key'] = \strtoupper($clause['compare_key']);
} else {
$clause['compare_key'] = '=';
}
// Get comparison from clause
$compare = $clause['compare'];
/** Build the WHERE clause ********************************************/
// Column name and value.
if (\array_key_exists('key', $clause) && \array_key_exists('value', $clause)) {
$column = sanitize_key($clause['key']);
$value = $clause['value'];
// IN or BETWEEN
if (\in_array($compare, self::IN_BETWEEN_COMPARES, \true)) {
if (!\is_array($value)) {
$value = \preg_split('/[,\\s]+/', $value);
}
// Anything else
} else {
$value = \trim($value);
}
// Format WHERE from compare value(s)
switch ($compare) {
case 'IN':
case 'NOT IN':
$compare_string = '(' . \substr(\str_repeat(',%s', \count($value)), 1) . ')';
$where = $wpdb->prepare($compare_string, $value);
break;
case 'BETWEEN':
case 'NOT BETWEEN':
$value = \array_slice($value, 0, 2);
$where = $wpdb->prepare('%s AND %s', $value);
break;
case 'LIKE':
case 'NOT LIKE':
$value = '%' . $wpdb->esc_like($value) . '%';
$where = $wpdb->prepare('%s', $value);
break;
// EXISTS with a value is interpreted as '='.
case 'EXISTS':
$compare = '=';
$where = $wpdb->prepare('%s', $value);
break;
// 'value' is ignored for NOT EXISTS.
case 'NOT EXISTS':
$where = '';
break;
default:
$where = $wpdb->prepare('%s', $value);
break;
}
// Maybe add column, compare, & where to chunks
if (!empty($where)) {
$sql_chunks['where'][] = "{$column} {$compare} {$where}";
}
}
/*
* Multiple WHERE clauses (for meta_key and meta_value) should
* be joined in parentheses.
*/
if (1 < \count($sql_chunks['where'])) {
$sql_chunks['where'] = array('( ' . \implode(' AND ', $sql_chunks['where']) . ' )');
}
// Return
return $sql_chunks;
}
}

File diff suppressed because it is too large Load Diff

@@ -0,0 +1,28 @@
<?php
/**
* Base Custom Database Table Meta Query Class.
*
* @package Database
* @subpackage Meta
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.1.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database\Queries;
// Exit if accessed directly
\defined('ABSPATH') || exit;
// @todo Remove the need for this dependency
use \WP_Meta_Query;
/**
* Class for generating SQL clauses that filter a primary query according to meta.
*
* It currently extends the WP_Meta_Query class in WordPress, but in the future
* will be derived completely from other registered tables.
*
* @since 1.1.0
*/
class Meta extends WP_Meta_Query
{
}

File diff suppressed because it is too large Load Diff

@@ -0,0 +1,66 @@
<?php
/**
* Base Custom Database Table Row Class.
*
* @package Database
* @subpackage Row
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* Base database row class.
*
* This class exists solely for other classes to extend (and to encapsulate
* database schema changes for those objects) to help separate the needs of the
* application layer from the requirements of the database layer.
*
* For example, if a database column is renamed or a return value needs to be
* formatted differently, this class will make sure old values are still
* supported and new values do not conflict.
*
* @since 1.0.0
*/
class Row extends Base
{
/**
* Construct a database object.
*
* @since 1.0.0
*
* @param mixed Null by default, Array/Object if not
*/
public function __construct($item = null)
{
if (!empty($item)) {
$this->init($item);
}
}
/**
* Initialize class properties based on data array.
*
* @since 1.0.0
*
* @param array $data
*/
private function init($data = array())
{
$this->set_vars($data);
}
/**
* Determines whether the current row exists.
*
* @since 1.0.0
*
* @return bool
*/
public function exists()
{
return !empty($this->id);
}
}

@@ -0,0 +1,81 @@
<?php
/**
* Base Custom Database Table Schema Class.
*
* @package Database
* @subpackage Schema
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* A base database table schema class, which houses the collection of columns
* that a table is made out of.
*
* This class is intended to be extended for each unique database table,
* including global tables for multisite, and users tables.
*
* @since 1.0.0
*/
class Schema extends Base
{
/**
* Array of database column objects to turn into Column.
*
* @since 1.0.0
* @var array
*/
protected $columns = array();
/**
* Invoke new column objects based on array of column data.
*
* @since 1.0.0
*/
public function __construct()
{
// Bail if no columns
if (empty($this->columns) || !\is_array($this->columns)) {
return;
}
// Juggle original columns array
$columns = $this->columns;
$this->columns = array();
// Loop through columns and create objects from them
foreach ($columns as $column) {
if (\is_array($column)) {
$this->columns[] = new Column($column);
} elseif ($column instanceof Column) {
$this->columns[] = $column;
}
}
}
/**
* Return the schema in string form.
*
* @since 1.0.0
*
* @return string Calls get_create_string() on every column.
*/
protected function to_string()
{
// Default return value
$retval = '';
// Bail if no columns to convert
if (empty($this->columns)) {
return $retval;
}
// Loop through columns...
foreach ($this->columns as $column_info) {
if (\method_exists($column_info, 'get_create_string')) {
$retval .= '\\n' . $column_info->get_create_string() . ', ';
}
}
// Return the string
return $retval;
}
}

@@ -0,0 +1,836 @@
<?php
/**
* Base Custom Database Table Class.
*
* @package Database
* @subpackage Table
* @copyright Copyright (c) 2021
* @license https://opensource.org/licenses/MIT MIT
* @since 1.0.0
*/
namespace WP_Ultimo\Dependencies\BerlinDB\Database;
// Exit if accessed directly
\defined('ABSPATH') || exit;
/**
* A base database table class, which facilitates the creation of (and schema
* changes to) individual database tables.
*
* This class is intended to be extended for each unique database table,
* including global tables for multisite, and users tables.
*
* It exists to make managing database tables as easy as possible.
*
* Extending this class comes with several automatic benefits:
* - Activation hook makes it great for plugins
* - Tables store their versions in the database independently
* - Tables upgrade via independent upgrade abstract methods
* - Multisite friendly - site tables switch on "switch_blog" action
*
* @since 1.0.0
*/
abstract class Table extends Base
{
/**
* Table name, without the global table prefix.
*
* @since 1.0.0
* @var string
*/
protected $name = '';
/**
* Optional description.
*
* @since 1.0.0
* @var string
*/
protected $description = '';
/**
* Database version.
*
* @since 1.0.0
* @var mixed
*/
protected $version = '';
/**
* Is this table for a site, or global.
*
* @since 1.0.0
* @var bool
*/
protected $global = \false;
/**
* Database version key (saved in _options or _sitemeta)
*
* @since 1.0.0
* @var string
*/
protected $db_version_key = '';
/**
* Current database version.
*
* @since 1.0.0
* @var mixed
*/
protected $db_version = 0;
/**
* Table prefix, including the site prefix.
*
* @since 1.0.0
* @var string
*/
protected $table_prefix = '';
/**
* Table name.
*
* @since 1.0.0
* @var string
*/
protected $table_name = '';
/**
* Table name, prefixed from the base.
*
* @since 1.0.0
* @var string
*/
protected $prefixed_name = '';
/**
* Table schema.
*
* @since 1.0.0
* @var string
*/
protected $schema = '';
/**
* Database character-set & collation for table.
*
* @since 1.0.0
* @var string
*/
protected $charset_collation = '';
/**
* Key => value array of versions => methods.
*
* @since 1.0.0
* @var array
*/
protected $upgrades = array();
/** Methods ***************************************************************/
/**
* Hook into queries, admin screens, and more!
*
* @since 1.0.0
*/
public function __construct()
{
// Setup the database table
$this->setup();
// Bail if setup failed
if (empty($this->name) || empty($this->db_version_key)) {
return;
}
// Add the table to the database interface
$this->set_db_interface();
// Set the database schema
$this->set_schema();
// Add hooks
$this->add_hooks();
// Maybe force upgrade if testing
if ($this->is_testing()) {
$this->maybe_upgrade();
}
}
/**
* Compatibility for clone() method for PHP versions less than 7.0.
*
* See: https://github.com/sugarcalendar/core/issues/105
*
* This shim will be removed at a later date.
*
* @since 2.0.20
*
* @param string $function
* @param array $args
*/
public function __call($function = '', $args = array())
{
if ('clone' === $function) {
\call_user_func_array(array($this, '_clone'), $args);
}
}
/** Abstract **************************************************************/
/**
* Setup this database table.
*
* @since 1.0.0
*/
protected abstract function set_schema();
/** Multisite *************************************************************/
/**
* Update table version & references.
*
* Hooked to the "switch_blog" action.
*
* @since 1.0.0
*
* @param int $site_id The site being switched to
*/
public function switch_blog($site_id = 0)
{
// Update DB version based on the current site
if (!$this->is_global()) {
$this->db_version = get_blog_option($site_id, $this->db_version_key, \false);
}
// Update interface for switched site
$this->set_db_interface();
}
/** Public Helpers ********************************************************/
/**
* Maybe upgrade the database table. Handles creation & schema changes.
*
* Hooked to the `admin_init` action.
*
* @since 1.0.0
*/
public function maybe_upgrade()
{
// Bail if not upgradeable
if (!$this->is_upgradeable()) {
return;
}
// Bail if upgrade not needed
if (!$this->needs_upgrade()) {
return;
}
// Upgrade
if ($this->exists()) {
$this->upgrade();
// Install
} else {
$this->install();
}
}
/**
* Return whether this table needs an upgrade.
*
* @since 1.0.0
*
* @param mixed $version Database version to check if upgrade is needed
*
* @return bool True if table needs upgrading. False if not.
*/
public function needs_upgrade($version = \false)
{
// Use the current table version if none was passed
if (empty($version)) {
$version = $this->version;
}
// Get the current database version
$this->get_db_version();
// Is the database table up to date?
$is_current = \version_compare($this->db_version, $version, '>=');
// Return false if current, true if out of date
return \true === $is_current ? \false : \true;
}
/**
* Return whether this table can be upgraded.
*
* @since 1.0.0
*
* @return bool True if table can be upgraded. False if not.
*/
public function is_upgradeable()
{
// Bail if global and upgrading global tables is not allowed
if ($this->is_global() && !wp_should_upgrade_global_tables()) {
return \false;
}
// Kinda weird, but assume it is
return \true;
}
/**
* Return the current table version from the database.
*
* This is public method for accessing a private variable so that it cannot
* be externally modified.
*
* @since 1.0.0
*
* @return string
*/
public function get_version()
{
$this->get_db_version();
return $this->db_version;
}
/**
* Install a database table
*
* Creates the table and sets the version information if successful.
*
* @since 1.0.0
*/
public function install()
{
// Try to create the table
$created = $this->create();
// Set the DB version if create was successful
if (\true === $created) {
$this->set_db_version();
}
}
/**
* Uninstall a database table
*
* Drops the table and deletes the version information if successful and/or
* the table does not exist anymore.
*
* @since 1.0.0
*/
public function uninstall()
{
// Try to drop the table
$dropped = $this->drop();
// Delete the DB version if drop was successful or table does not exist
if (\true === $dropped || !$this->exists()) {
$this->delete_db_version();
}
}
/** Public Management *****************************************************/
/**
* Check if table already exists.
*
* @since 1.0.0
*
* @return bool
*/
public function exists()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "SHOW TABLES LIKE %s";
$like = $db->esc_like($this->table_name);
$prepared = $db->prepare($query, $like);
$result = $db->get_var($prepared);
// Does the table exist?
return $this->is_success($result);
}
/**
* Get columns from table.
*
* @since 1.2.0
*
* @return array
*/
public function columns()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "SHOW FULL COLUMNS FROM {$this->table_name}";
$result = $db->get_results($query);
// Return the results
return $this->is_success($result) ? $result : \false;
}
/**
* Create the table.
*
* @since 1.0.0
*
* @return bool
*/
public function create()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "CREATE TABLE {$this->table_name} ( {$this->schema} ) {$this->charset_collation}";
$result = $db->query($query);
// Was the table created?
return $this->is_success($result);
}
/**
* Drop the database table.
*
* @since 1.0.0
*
* @return bool
*/
public function drop()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "DROP TABLE {$this->table_name}";
$result = $db->query($query);
// Did the table get dropped?
return $this->is_success($result);
}
/**
* Truncate the database table.
*
* @since 1.0.0
*
* @return bool
*/
public function truncate()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "TRUNCATE TABLE {$this->table_name}";
$result = $db->query($query);
// Did the table get truncated?
return $this->is_success($result);
}
/**
* Delete all items from the database table.
*
* @since 1.0.0
*
* @return bool
*/
public function delete_all()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "DELETE FROM {$this->table_name}";
$result = $db->query($query);
// Return the results
return $result;
}
/**
* Clone this database table.
*
* Pair with copy().
*
* @since 1.1.0
*
* @param string $new_table_name The name of the new table, without prefix
*
* @return bool
*/
public function _clone($new_table_name = '')
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Sanitize the new table name
$table_name = $this->sanitize_table_name($new_table_name);
// Bail if new table name is invalid
if (empty($table_name)) {
return \false;
}
// Query statement
$table = $this->apply_prefix($table_name);
$query = "CREATE TABLE {$table} LIKE {$this->table_name}";
$result = $db->query($query);
// Did the table get cloned?
return $this->is_success($result);
}
/**
* Copy the contents of this table to a new table.
*
* Pair with clone().
*
* @since 1.1.0
*
* @param string $new_table_name The name of the new table, without prefix
*
* @return bool
*/
public function copy($new_table_name = '')
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Sanitize the new table name
$table_name = $this->sanitize_table_name($new_table_name);
// Bail if new table name is invalid
if (empty($table_name)) {
return \false;
}
// Query statement
$table = $this->apply_prefix($table_name);
$query = "INSERT INTO {$table} SELECT * FROM {$this->table_name}";
$result = $db->query($query);
// Did the table get copied?
return $this->is_success($result);
}
/**
* Count the number of items in the database table.
*
* @since 1.0.0
*
* @return int
*/
public function count()
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return 0;
}
// Query statement
$query = "SELECT COUNT(*) FROM {$this->table_name}";
$result = $db->get_var($query);
// Query success/fail
return \intval($result);
}
/**
* Check if column already exists.
*
* @since 1.0.0
*
* @param string $name Value
*
* @return bool
*/
public function column_exists($name = '')
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Query statement
$query = "SHOW COLUMNS FROM {$this->table_name} LIKE %s";
$like = $db->esc_like($name);
$prepared = $db->prepare($query, $like);
$result = $db->query($prepared);
// Does the column exist?
return $this->is_success($result);
}
/**
* Check if index already exists.
*
* @since 1.0.0
*
* @param string $name Value
* @param string $column Column name
*
* @return bool
*/
public function index_exists($name = '', $column = 'Key_name')
{
// Get the database interface
$db = $this->get_db();
// Bail if no database interface is available
if (empty($db)) {
return \false;
}
// Limit $column to Key or Column name, until we can do better
if (!\in_array($column, array('Key_name', 'Column_name'), \true)) {
$column = 'Key_name';
}
// Query statement
$query = "SHOW INDEXES FROM {$this->table_name} WHERE {$column} LIKE %s";
$like = $db->esc_like($name);
$prepared = $db->prepare($query, $like);
$result = $db->query($prepared);
// Does the index exist?
return $this->is_success($result);
}
/** Upgrades **************************************************************/
/**
* Upgrade this database table.
*
* @since 1.0.0
*
* @return bool
*/
public function upgrade()
{
// Get pending upgrades
$upgrades = $this->get_pending_upgrades();
// Bail if no upgrades
if (empty($upgrades)) {
$this->set_db_version();
// Return, without failure
return \true;
}
// Default result
$result = \false;
// Try to do the upgrades
foreach ($upgrades as $version => $callback) {
// Do the upgrade
$result = $this->upgrade_to($version, $callback);
// Bail if an error occurs, to avoid skipping upgrades
if (!$this->is_success($result)) {
return \false;
}
}
// Success/fail
return $this->is_success($result);
}
/**
* Return array of upgrades that still need to run.
*
* @since 1.1.0
*
* @return array Array of upgrade callbacks, keyed by their db version.
*/
public function get_pending_upgrades()
{
// Default return value
$upgrades = array();
// Bail if no upgrades, or no database version to compare to
if (empty($this->upgrades) || empty($this->db_version)) {
return $upgrades;
}
// Loop through all upgrades, and pick out the ones that need doing
foreach ($this->upgrades as $version => $callback) {
if (\true === \version_compare($version, $this->db_version, '>')) {
$upgrades[$version] = $callback;
}
}
// Return
return $upgrades;
}
/**
* Upgrade to a specific database version.
*
* @since 1.0.0
*
* @param mixed $version Database version to check if upgrade is needed
* @param string $callback Callback function or class method to call
*
* @return bool
*/
public function upgrade_to($version = '', $callback = '')
{
// Bail if no upgrade is needed
if (!$this->needs_upgrade($version)) {
return \false;
}
// Allow self-named upgrade callbacks
if (empty($callback)) {
$callback = $version;
}
// Is the callback... callable?
$callable = $this->get_callable($callback);
// Bail if no callable upgrade was found
if (empty($callable)) {
return \false;
}
// Do the upgrade
$result = \call_user_func($callable);
$success = $this->is_success($result);
// Bail if upgrade failed
if (\true !== $success) {
return \false;
}
// Set the database version to this successful version
$this->set_db_version($version);
// Return success
return \true;
}
/** Private ***************************************************************/
/**
* Setup the necessary table variables.
*
* @since 1.0.0
*/
private function setup()
{
// Bail if no database interface is available
if (!$this->get_db()) {
return;
}
// Sanitize the database table name
$this->name = $this->sanitize_table_name($this->name);
// Bail if database table name was garbage
if (\false === $this->name) {
return;
}
// Separator
$glue = '_';
// Setup the prefixed name
$this->prefixed_name = $this->apply_prefix($this->name, $glue);
// Maybe create database key
if (empty($this->db_version_key)) {
$this->db_version_key = \implode($glue, array(sanitize_key($this->db_global), $this->prefixed_name, 'version'));
}
}
/**
* Set this table up in the database interface.
*
* This must be done directly because the database interface does not
* have a common mechanism for manipulating them safely.
*
* @since 1.0.0
*/
private function set_db_interface()
{
// Get the database once, to avoid duplicate function calls
$db = $this->get_db();
// Bail if no database
if (empty($db)) {
return;
}
// Set variables for global tables
if ($this->is_global()) {
$site_id = 0;
$tables = 'ms_global_tables';
// Set variables for per-site tables
} else {
$site_id = null;
$tables = 'tables';
}
// Set the table prefix and prefix the table name
$this->table_prefix = $db->get_blog_prefix($site_id);
// Get the prefixed table name
$prefixed_table_name = "{$this->table_prefix}{$this->prefixed_name}";
// Set the database interface
$db->{$this->prefixed_name} = $this->table_name = $prefixed_table_name;
// Create the array if it does not exist
if (!isset($db->{$tables})) {
$db->{$tables} = array();
}
// Add the table to the global table array
$db->{$tables}[] = $this->prefixed_name;
// Charset
if (!empty($db->charset)) {
$this->charset_collation = "DEFAULT CHARACTER SET {$db->charset}";
}
// Collation
if (!empty($db->collate)) {
$this->charset_collation .= " COLLATE {$db->collate}";
}
}
/**
* Set the database version for the table.
*
* @since 1.0.0
*
* @param mixed $version Database version to set when upgrading/creating
*/
private function set_db_version($version = '')
{
// If no version is passed during an upgrade, use the current version
if (empty($version)) {
$version = $this->version;
}
// Update the DB version
$this->is_global() ? update_network_option(get_main_network_id(), $this->db_version_key, $version) : update_option($this->db_version_key, $version);
// Set the DB version
$this->db_version = $version;
}
/**
* Get the table version from the database.
*
* @since 1.0.0
*/
private function get_db_version()
{
$this->db_version = $this->is_global() ? get_network_option(get_main_network_id(), $this->db_version_key, \false) : get_option($this->db_version_key, \false);
}
/**
* Delete the table version from the database.
*
* @since 1.0.0
*/
private function delete_db_version()
{
$this->db_version = $this->is_global() ? delete_network_option(get_main_network_id(), $this->db_version_key) : delete_option($this->db_version_key);
}
/**
* Add class hooks to the parent application actions.
*
* @since 1.0.0
*/
private function add_hooks()
{
// Add table to the global database object
add_action('switch_blog', array($this, 'switch_blog'));
add_action('admin_init', array($this, 'maybe_upgrade'));
}
/**
* Check if the current request is from some kind of test.
*
* This is primarily used to skip 'admin_init' and force-install tables.
*
* @since 1.0.0
*
* @return bool
*/
private function is_testing()
{
return (bool) (\defined('WP_TESTS_DIR') && WP_TESTS_DIR) || \function_exists('_manually_load_plugin');
}
/**
* Check if table is global.
*
* @since 1.0.0
*
* @return bool
*/
private function is_global()
{
return \true === $this->global;
}
/**
* Try to get a callable upgrade, with some magic to avoid needing to
* do this dance repeatedly inside subclasses.
*
* @since 1.0.0
*
* @param string $callback
*
* @return mixed Callable string, or false if not callable
*/
private function get_callable($callback = '')
{
// Default return value
$callable = $callback;
// Look for global function
if (!\is_callable($callable)) {
// Fallback to local class method
$callable = array($this, $callback);
if (!\is_callable($callable)) {
// Fallback to class method prefixed with "__"
$callable = array($this, "__{$callback}");
if (!\is_callable($callable)) {
$callable = \false;
}
}
}
// Return callable string, or false if not callable
return $callable;
}
}