....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 51.91.236.193  /  Your IP : 216.73.216.177
Web Server : Apache
System : Linux webm019.cluster128.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
User : thillelirn ( 8290)
PHP Version : 8.0.30
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/thillelirn/sexo_tlse/wp-content/plugins/burst-statistics/includes/Traits/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/thillelirn/sexo_tlse/wp-content/plugins/burst-statistics/includes/Traits/trait-sanitize.php
<?php
namespace Burst\Traits;

use Burst\Admin\Statistics\Query_Data;

/**
 * Trait containing sanitization methods for consistent data cleaning throughout the application.
 */
trait Sanitize {
	use Helper;

	/**
	 * Sanitize hash fragment from URL.
	 * Allows alphanumeric, /, ?, =, &, _, -, ., % characters (% for URL encoding).
	 *
	 * @param string $hash The hash fragment to sanitize (including the # character).
	 * @return string Sanitized hash fragment.
	 */
	private static function sanitize_hash_fragment( string $hash ): string {
		if ( empty( $hash ) ) {
			return '';
		}

		// Sanitize hash: allow alphanumeric, /, ?, =, &, _, -, ., % characters.
		// Hash fragments are client-side only, but we sanitize to prevent XSS if displayed.
		return preg_replace( '/[^#a-zA-Z0-9\/?=&_\-.%]/', '', $hash );
	}

	/**
	 * Sanitize a relative URL, ensuring it starts with a slash and doesn't contain the domain.
	 *
	 * @param string $url URL to sanitize.
	 * @return string Sanitized URL.
	 */
	public function sanitize_relative_url( string $url ): string {
		$url = sanitize_text_field( $url );
		if ( empty( $url ) ) {
			return '/';
		}

		// Remove protocol and domain if present (make URL relative).
		$url_without_protocol = preg_replace( '(^https?://)', '', $url );
		if ( $url_without_protocol !== $url ) {
			// URL had a protocol, so also remove the domain.
			$parts = explode( '/', $url_without_protocol, 2 );
			if ( count( $parts ) === 2 ) {
				$url = '/' . $parts[1];
			} else {
				$url = '/';
			}
		}

		// Ensure URL starts with a slash.
		if ( strpos( $url, '/' ) !== 0 ) {
			$url = '/' . $url;
		}

		return trailingslashit( filter_var( $url, FILTER_SANITIZE_URL ) );
	}

	/**
	 * Sanitize an IP field, with each IP on a new line.
	 *
	 * @param string $value The IP field value to sanitize.
	 * @return string Sanitized IP field.
	 */
	public function sanitize_ip_field( string $value ): string {
		$ips = explode( PHP_EOL, $value );
		// Remove whitespace.
		$ips = array_map( 'trim', $ips );
		$ips = array_filter(
			$ips,
			function ( $line ) {
				return $line !== '';
			}
		);
		// Remove duplicates.
		$ips = array_unique( $ips );
		// Sanitize each ip.
		$ips = array_map( 'sanitize_text_field', $ips );
		return implode( PHP_EOL, $ips );
	}

	/**
	 * Sanitize a field value based on its type.
	 *
	 * @param mixed  $value The value to sanitize.
	 * @param string $type The field type.
	 * @return mixed Sanitized value.
	 */
	// phpcs:disable
	public function sanitize_field( $value, string $type ) {
		// phpcs:enable

		$type = $this->sanitize_field_type( $type );

		switch ( $type ) {
			case 'checkbox':
			case 'anonymous_usage_data':
			case 'hidden':
				return (int) $value;
			case 'checkbox_group':
			case 'user_role_blocklist':
				if ( ! is_array( $value ) ) {
					$value = [];
				}
				return array_map( 'sanitize_text_field', $value );
			case 'email':
				return sanitize_email( $value );
			case 'number':
				return (int) $value;
			case 'ip_blocklist':
				return $this->sanitize_ip_field( $value );
			case 'email_reports':
				return $this->sanitize_email_reports( $value );
			case 'license':
				return defined( 'BURST_PRO' ) && class_exists( '\\Burst\\Pro\\Admin\\Licensing\\Licensing' ) ? ( new \Burst\Pro\Admin\Licensing\Licensing() )->sanitize_license( $value ) : '';
			case 'textarea':
				return wp_kses_post( $value );
			default:
				return sanitize_text_field( $value );
		}
	}

	/**
	 * Sanitize type against list of allowed field types.
	 *
	 * @param string $type The field type to sanitize.
	 * @return string Sanitized field type.
	 */
	public function sanitize_field_type( string $type ): string {
		$types   = $this->allowed_field_types();
		$default = $this->default_field_type();

		if ( in_array( $type, $types, true ) ) {
			return $type;
		}

		return $default;
	}

	/**
	 * Sanitize a status.
	 *
	 * @param string $status The status to sanitize.
	 * @return string Sanitized status.
	 */
	public function sanitize_status( string $status ): string {
		$statuses = $this->allowed_goal_statuses();
		$default  = $this->default_status();

		if ( in_array( $status, $statuses, true ) ) {
			return $status;
		}

		return $default;
	}

	/**
	 * Sanitize an interval string.
	 *
	 * @param string $interval The interval to sanitize.
	 * @return string Sanitized interval.
	 */
	public function sanitize_interval( string $interval ): string {
		$intervals = $this->allowed_intervals();
		$default   = $this->default_interval();

		if ( in_array( $interval, $intervals, true ) ) {
			return $interval;
		}

		return $default;
	}

	/**
	 * Sanitize a goal metric.
	 *
	 * @param string $metric The goal metric to sanitize.
	 * @return string Sanitized goal metric.
	 */
	public function sanitize_goal_conversion_metric( string $metric ): string {
		$metrics = $this->allowed_goal_metrics();
		$default = $this->default_goal_metric();

		if ( in_array( $metric, $metrics, true ) ) {
			return $metric;
		}

		return $default;
	}

	/**
	 * Sanitize archive status.
	 *
	 * @param string $status The archive status to sanitize.
	 * @return string Sanitized archive status.
	 */
	public function sanitize_archive_status( string $status ): string {
		$statuses = $this->allowed_archive_statuses();
		$default  = $this->default_archive_status();

		if ( in_array( $status, $statuses, true ) ) {
			return $status;
		}

		return $default;
	}

	/**
	 * Sanitize lookup table type.
	 *
	 * @param string $type The lookup table type to sanitize.
	 * @return string Sanitized lookup table type.
	 */
	public function sanitize_lookup_table_type( string $type ): string {
		$types   = $this->allowed_lookup_table_types();
		$default = $this->default_lookup_table_type();

		if ( in_array( $type, $types, true ) ) {
			return $type;
		}

		return $default;
	}

	/**
	 * Sanitize a collection of email reports.
	 *
	 * @param array $email_reports Array of email reports to sanitize.
	 * @return array<array<string, mixed>> Sanitized email reports.
	 */
	public function sanitize_email_reports( array $email_reports ): array {
		$sanitized_email_reports = [];
		foreach ( $email_reports as $report ) {
			if ( ! isset( $report['email'] ) ) {
				continue;
			}

			$sanitized_report          = [];
			$sanitized_report['email'] = sanitize_email( $report['email'] );
			if ( isset( $report['frequency'] ) ) {
				$sanitized_report['frequency'] = $this->sanitize_interval( $report['frequency'] );
			}
			$sanitized_email_reports[] = $sanitized_report;
		}

		return $sanitized_email_reports;
	}

	/**
	 * Sanitize and destructure a URL.
	 *
	 * Ensures the URL is safe and valid, then extracts its components.
	 *
	 * @param string|null $url The input URL.
	 * @return array{
	 *     scheme: string,
	 *     host: string,
	 *     path: string,
	 *     parameters: string
	 * }
	 */
	public function sanitize_url( ?string $url ): array {
		$url_destructured = [
			'scheme'     => 'https',
			'host'       => '',
			'path'       => '',
			'parameters' => '',
		];

		if ( empty( $url ) ) {
			return $url_destructured;
		}

		if ( ! function_exists( 'wp_kses_bad_protocol' ) ) {
			require_once ABSPATH . '/wp-includes/kses.php';
		}

		$sanitized_url = filter_var( $url, FILTER_SANITIZE_URL );
		// Validate the URL.
		if ( ! filter_var( $sanitized_url, FILTER_VALIDATE_URL ) ) {
			return $url_destructured;
		}

		if ( ! function_exists( 'wp_parse_url' ) ) {
			require_once ABSPATH . '/wp-includes/http.php';
		}
		$url = wp_parse_url( esc_url_raw( $sanitized_url ) );
		if ( isset( $url['host'] ) ) {
			$path                            = $url['path'] ?? '';
			$url_destructured['host']        = $url['host'];
			$url_destructured['scheme']      = $url['scheme'];
			$url_destructured['path']        = trailingslashit( $path );
			$url_destructured['parameters']  = $url['query'] ?? '';
			$url_destructured['parameters'] .= $url['fragment'] ?? '';
		}
		return $url_destructured;
	}

	/**
	 * Sanitize a user ID.
	 *
	 * @param string|null $uid User ID to sanitize.
	 * @return string Sanitized user ID.
	 */
	public function sanitize_uid( ?string $uid ): string {
		if ( $uid === null || strlen( $uid ) === 0 || ! preg_match( '/^[a-z0-9-]+$/', $uid ) ) {
			return '';
		}

		return $uid;
	}

	/**
	 * Sanitize a fingerprint.
	 *
	 * @param string|null $fingerprint Fingerprint to sanitize.
	 * @return string Sanitized fingerprint.
	 */
	public function sanitize_fingerprint( ?string $fingerprint ): string {
		if ( $fingerprint === null || strlen( $fingerprint ) === 0 || ! preg_match( '/^[a-z0-9-]+$/', $fingerprint ) ) {
			return '';
		}

		return str_starts_with( $fingerprint, 'f-' ) ? $fingerprint : 'f-' . $fingerprint;
	}

	/**
	 * Sanitize a referrer URL.
	 *
	 * @param string|null $referrer Referrer URL to sanitize.
	 * @return string Sanitized referrer URL.
	 */
	public function sanitize_referrer( ?string $referrer ): string {
		if ( empty( $referrer ) ) {
			return '';
		}

		if ( ! defined( 'BURST_PATH' ) ) {
			$dir     = plugin_dir_path( __FILE__ );
			$src_pos = strpos( $dir, '/includes/' );
			$dir     = $src_pos !== false ? substr( $dir, 0, $src_pos + 1 ) : $dir;
			define( 'BURST_PATH', $dir );
		}
		$referrer = filter_var( $referrer, FILTER_SANITIZE_URL );
		// we use parse_url instead of wp_parse_url so we don't need to load a wp file here.
        //phpcs:ignore
        $referrer_host = parse_url( $referrer, PHP_URL_HOST );
		// No referrer header = direct traffic.
		if ( empty( $referrer_host ) ) {
			return '';
		}

		// Sanitize current host.
		if ( isset( $_SERVER['HTTP_HOST'] ) ) {
			$current_host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) );
		} elseif ( isset( $_SERVER['SERVER_NAME'] ) ) {
			$current_host = sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) );
		} else {
			// we use parse_url so we don't need to load a wp file here.
            //phpcs:ignore
			$current_host = parse_url( site_url(), PHP_URL_HOST );
		}

		$current_host  = preg_replace( '/^www\./i', '', $current_host );
		$referrer_host = preg_replace( '/^www\./i', '', $referrer_host );

		// don't track if referrer is the same as current host.
		// if referrer_url starts with current_host, then it is not a referrer.
		if ( str_starts_with( $referrer_host, $current_host ) ) {
			return '';
		}

		$ref_spam_list = file( BURST_PATH . 'lib/vendor/matomo/referrer-spam-list/spammers.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
		$ref_spam_list = apply_filters( 'burst_referrer_spam_list', $ref_spam_list );
		if ( array_search( $referrer_host, $ref_spam_list, true ) ) {
			return 'spammer';
		}

		return untrailingslashit( $referrer_host );
	}

	/**
	 * Sanitize time on page.
	 *
	 * @param string|null $time_on_page Time on page to sanitize.
	 * @return int Sanitized time on page.
	 */
	public function sanitize_time_on_page( ?string $time_on_page ): int {
		return (int) $time_on_page;
	}


	/**
	 * Configuration file for validation rules
	 * These values define valid options for various fields throughout the application
	 * All values can be filtered using WordPress hooks
	 */

	/**
	 * Allowed goal statuses
	 *
	 * @return array<int, string> List of valid goal statuses
	 */
	public function allowed_goal_statuses(): array {
		return apply_filters(
			'burst_allowed_goal_statuses',
			[
				'all',
				'active',
				'inactive',
				'archived',
			]
		);
	}

	/**
	 * Default status (fallback when an invalid status is provided)
	 *
	 * @return string Default status
	 */
	public function default_status(): string {
		return apply_filters( 'burst_default_status', 'inactive' );
	}

	/**
	 * Allowed field types
	 *
	 * @return array<int, string> List of valid field types
	 */
	public function allowed_field_types(): array {
		return apply_filters(
			'burst_allowed_field_types',
			[
				'hidden',
				'database',
				'checkbox',
				'radio',
				'text',
				'textarea',
				'number',
				'email',
				'select',
				'ip_blocklist',
				'email_reports',
				'user_role_blocklist',
				'checkbox_group',
				'license',
				'anonymous_usage_data',
			]
		);
	}

	/**
	 * Default field type (fallback when an invalid field type is provided)
	 *
	 * @return string Default field type
	 */
	public function default_field_type(): string {
		return apply_filters( 'burst_default_field_type', 'checkbox' );
	}

	/**
	 * Allowed interval types
	 *
	 * @return array<int, string> List of valid interval types
	 */
	public function allowed_intervals(): array {
		return apply_filters(
			'burst_allowed_intervals',
			[
				'hour',
				'day',
				'week',
				'month',
			]
		);
	}

	/**
	 * Default interval (fallback when an invalid interval is provided)
	 *
	 * @return string Default interval
	 */
	public function default_interval(): string {
		return apply_filters( 'burst_default_interval', 'day' );
	}

	/**
	 * Allowed goal metric types
	 *
	 * @return array<int, string> List of valid goal metric names
	 */
	public function allowed_goal_metrics(): array {
		return apply_filters(
			'burst_allowed_goal_metrics',
			[
				'pageviews',
				'visitors',
				'sessions',
			]
		);
	}

	/**
	 * Default goal metric (fallback when an invalid goal metric is provided)
	 *
	 * @return string Default goal metric
	 */
	public function default_goal_metric(): string {
		return apply_filters( 'burst_default_goal_metric', 'pageviews' );
	}

	/**
	 * Allowed archive statuses
	 *
	 * @return array<int, string> List of valid archive statuses
	 */
	public function allowed_archive_statuses(): array {
		return apply_filters(
			'burst_allowed_archive_statuses',
			[
				'archived',
				'restored',
				'archiving',
				'deleted',
			]
		);
	}

	/**
	 * Default archive status
	 *
	 * @return string Default archive status
	 */
	public function default_archive_status(): string {
		return apply_filters( 'burst_default_archive_status', 'archived' );
	}

	/**
	 * Allowed lookup table types
	 *
	 * @return array<int, string> List of valid lookup table types
	 */
	public function allowed_lookup_table_types(): array {
		return apply_filters(
			'burst_allowed_lookup_table_types',
			[
				'browser',
				'browser_version',
				'device',
				'platform',
			]
		);
	}

	/**
	 * Default lookup table type
	 *
	 * @return string Default lookup table type
	 */
	public function default_lookup_table_type(): string {
		return apply_filters( 'burst_default_lookup_table_type', 'browser' );
	}

	/**
	 * Configuration for filter validation
	 *
	 * @return array<string, array<string, string>> Filter validation configuration
	 */
	public function filter_validation_config(): array {
		return apply_filters(
			'burst_filter_validation_config',
			[
				'goal_id'     => [
					'sanitize' => 'absint',
					'type'     => 'int',
				],
				'bounces'     => [
					'sanitize' => [ $this, 'sanitize_include_exclude' ],
					'type'     => 'string',
				],
				'page_id'     => [
					'sanitize' => 'absint',
					'type'     => 'int',
				],
				'page_url'    => [
					'sanitize' => 'sanitize_text_field',
					'type'     => 'string',
				],
				'referrer'    => [
					'sanitize' => 'sanitize_text_field',
					'type'     => 'string',
				],
				'device'      => [
					'sanitize' => [ $this, 'sanitize_device_filter' ],
					'type'     => 'string',
				],
				'new_visitor' => [
					'sanitize' => [ $this, 'sanitize_include_exclude' ],
					'type'     => 'string',
				],
			]
		);
	}

	/**
	 * Default metric (fallback when an invalid metric is provided)
	 *
	 * @return string Default metric name
	 */
	public function default_metric(): string {
		return apply_filters( 'burst_default_metric', 'pageviews' );
	}

	/**
	 * Sanitize device filter value
	 *
	 * @param string $device Device value to sanitize.
	 * @return string Sanitized device value
	 */
	public function sanitize_device_filter( string $device ): string {
		$allowed_devices = [ 'desktop', 'tablet', 'mobile', 'other' ];

		if ( in_array( $device, $allowed_devices, true ) ) {
			return $device;
		}

		return '';
	}

	/**
	 * Sanitize include or exclude values
	 *
	 * @param string $value value to sanitize.
	 * @return string Sanitized value
	 */
	public function sanitize_include_exclude( string $value ): string {
		$allowed = [ 'include', 'exclude' ];

		if ( in_array( $value, $allowed, true ) ) {
			return $value;
		}

		return 'exclude';
	}

	/**
	 * Sanitize and convert a boolean value.
	 *
	 * @param string $value The value to sanitize.
	 * @return bool Sanitized boolean value.
	 */
	public function sanitize_and_convert_boolean( string $value ): bool {
		if ( $value === 'include' ) {
			return true;
		}
		if ( $value === 'exclude' ) {
			return false;
		}
		return false;
	}

	/**
	 * Allowed goal types
	 *
	 * This function returns an array of allowed goal types
	 * It uses the goal_fields configuration to extract valid goal types
	 *
	 * @return array<int, string> List of valid goal types
	 */
	public function allowed_goal_types(): array {
		// Get the goal types from the goal_fields array, which is dynamically built.
		// This ensures we always have the most up-to-date list.
		$fields = require_once __DIR__ . '/goal-fields.php';

		// Find the type field in the goal fields.
		$type_field = array_filter(
			$fields,
			static function ( $goal ) {
				return isset( $goal['id'] ) && $goal['id'] === 'type';
			}
		);

		$type_field = reset( $type_field );
		$goal_types = isset( $type_field['options'] ) ? array_keys( $type_field['options'] ) : [ 'clicks' ];

		return apply_filters( 'burst_allowed_goal_types', $goal_types );
	}

	/**
	 * Default goal type (fallback when an invalid goal type is provided)
	 *
	 * @return string Default goal type
	 */
	public function default_goal_type(): string {
		return apply_filters( 'burst_default_goal_type', 'clicks' );
	}

	/**
	 * Get available arguments for a specific data type
	 *
	 * @param string $type The data type for which to get available arguments.
	 * @return array<int, string> List of available arguments for the specified data type
	 */
	public function get_data_available_args( string $type ): array {
		$default_args = [ 'filters', 'metrics', 'group_by', 'goal_id', 'date_start', 'date_end' ];

		// Allow filtering of available args by type.
		return apply_filters( 'burst_get_data_available_args', $default_args, $type );
	}

	/**
	 * Sanitize date string for use in date queries.
	 *
	 * @param string|null $date Date string to sanitize (expected format: Y-m-d).
	 * @return string Sanitized date string in Y-m-d format or empty string if invalid.
	 */
	public function normalize_date( ?string $date ): string {
		if ( empty( $date ) ) {
			return '';
		}

		// Remove any non-date characters and trim.
		$date = trim( sanitize_text_field( $date ) );

		// Try to create DateTime object from Y-m-d format.
		$datetime = \DateTime::createFromFormat( 'Y-m-d H:i:s', $date, wp_timezone() );
		// Check if the date was parsed successfully and matches the input exactly.
		if ( ! $datetime || $datetime->format( 'Y-m-d H:i:s' ) !== $date ) {
			return '';
		}

		// Return the unix timestamp as string instead of int.
		return (string) self::convert_date_to_unix( $datetime->format( 'Y-m-d H:i:s' ) );
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit