Z)n`^Vi< $0:6H7--4T*2-!HA[pAV̓v_{Wƭl޹yy^xoVK&R Plt0oVU hFL~;pѿh0`cЅ|K^_o헃 `8pstK}),'k57[}6k6+P|f0ev)u/Emy|\ʐwT_ո.izC=$ BX45j^ '$A`㭘ڋ&_*^(۹L.+ _yc*e؟1IYZtY8n+\ cٶT<ΟvmYIAiv0-sB c)dIP䍳ʼ3SRzL|J7̹,n^Y7q͗RfumLEal~nwռQ,tmC`M4&vD&37?H'sw8n,Yh =h`A#Bb,lj5sw'I}no p9^H[OH^2W]6&BJ]b\/S@E)>/z)mJL]$Lv18/b.Z$UNxnk{y-ҲrAGo\*L>7{P_q46:*iLXٴpz*1ꫭ) CRJIfŎ0ߝ7S#μ__&vooPiy)P$W 9-j(,d K:|$"׾J` ;{L1U[6+-xDsDN U?H+k14B_ 7LER;E?mQsNMp,B-|NvfvPksjv&e%aH"JB8S^ |0q㤸qhg*l\q]OlB/dShYF)b ;UW3wr{G;~淚ٵ"1!F?~]R9)G3teѸuԼ-*4k ^sU㙃֯h`"#BJ2hr#q#ov00STYuˊk֐( v4a)tҹwB_K==R1ZQÃlE"9ʫ?XZ RZ$ѱNi-r;+5jqK9^> S6+|)K[ħfnɆ-!6k2Zvk5gI_^|bf)2b!֑~ ˲A`ˍG9_艠+5℮(3-6?4]AҲ8^+6Ca|ɐtJ^\ʂ~٭I68)=^(}"!2ݩMWb+/i۩au#+ Q+:}Wr$zikFk #϶0ϙ?te-ಝ93[0? 2r+zOVxǽpkwlfх$* JAyz"0TKz-'TT6;E7']N$)1c2ޭu]Yuw|2.P^AgG?5^ie23j\Ws+#be}z>W˽ mSʽcx3'*bziRE ~lͺ 1;ffff{333 c33333s̎sVZݕ;uKQףW@Ķ '6iFor3>kHy#I)!MƉ쥃9Z~R#\h$N2պB jtFXy$N2aRZ]U>ӰOT[%ã=DZE]1YAIIZf^c'Lڽկ0x4F7U.|\}#I)DSvio,$M*5zb:㳮!0x<b>s߅,2K6l)rIʬ:v5," a'F(峺? ;mB݈װX5Mճo,v\I(g,_}|Ė$nIɁRěJ|< ]"}|0>(n̖)Ic9 -Sg=&L~:*ƛ.+b *28߀qX m Vm⫰R)ьT)7&;yAE*\,j+1۫ݸμzc:iUV6D&\b(uBdn{X.ѢLOћ+D]OfzCtFwQÇzN-U=逺7Utp_Sٯ>#AY¢n0oij*ǐflTM!}s.uAIzJZ"Ul,Ʋ6F1~#|-frwpK/84"htjw,uw U5( GFCJnrr&HLΙEj=\KM]a{zY#DcW8;Pj5}e R&IfL~bSbHK>LGY; u;]id[$}IR8[| bÛk/Gɗl7IIcmo=i>sHѰ$%^9iB9Hk[ pdk Λ Q5[_KF4Ob* >.zk!ޔ]|נrkñ|=Ha4'cIn1*DA_@u4GVUfJNYx7Lj[SP[x@nutF{0vq_uToW$Xw<ͳ$d!7mXslX[aE#MsEwhfk3ؼꟉ#^G{˳fqmVMGv3v_\w_kPíLۉ':͝TK%pK"8)o6}R_Hp c Ǵ`F>@{b:DkœDd]&>t8[,5p"en͸S1n;aiKLRFǃ~ķgCw?]ЈM(r_1)w{ڿwGIie$;^=/ĜN~VA0y@K@b?ɛՀw@ ea<jxH7)udH< ˌ YńXXk E+Eݺܬ;,^F5}=wd(I`[cif/uiߥ!K|l 6Hxw4ϙM1ų9`yv/̐%/.BR<&Cs<_jӲRMIAZ;v6JkO@ _pE+.`R7R!z~dRPui!4Oh3?vU" ppLyBaBDъ|R1$wG,z>E  ))M R 3zBbjd1hW_i6~܈4Ԧ>~w@AZq4ބM_!=dqIEQc@d-b R*< r?I#.)!]l[Q,la~GZdHÒĻHn ~MtgR50֪p@2F3*R 'jٰm'D@ʲЩ-l8;]w0 ~ֽ C\k9aQ3(CI 2,UVm2 Da~IDTg)fʡmk;',UcR 9O/F|qbM8ඡN9* -G@,F#|?݌Z!qC]Zh+tBU UTbMx8k.<Ⱦ/ec qK?Wu3ɖWS") l H5J+׍t#-VB"ZQfu=UqZUmP:KߕM,cJ0d ʅ3#R)c$q-IꪸYjcLũNZ,bA3\k%mqnma\iY!lZ7SeˆO2U [Y]S[Kq}ySvEo:ynGm.y}U8"3(~#uzkŦΏ3-uv[狻rXN(#K^u6uvwǰ5QL!qECFvH<:<>_\>`Dqh8Utd@kAL t< ^cx'4-zHd;̻S(ͨel^Yk™{M2`Yziw ,8U5v1|Iϔ=>Qmiok!|Rxɥ6ø29 aThx?gO>Q=Tc܏ xH#Vxsx Zi]hW tyG~9JH fT*Ǜb'zB2'>1WTE<4VHx &PnJ*1 L};O-ľGCrxW &t+iZN5Uٔ?`Հ8(?Y@yaY Ob?jEDNz ^NtηkQ ;4N6lyĐ_.JM3<;!)8{1 Oi"ނw[f1V /~uYЯX+;8U= a{R{06z7N]d_7B-r%˰4dUEEZWBgqL u+m;C ~(pTk,9$2-CC*tuG<" s9#ټudC|}KZtEJfp'?uնZJ}3 2qHR礫 n |AFʄšc2ْD g e/n;@xfBwswl]^/][V9tGkZ{pZ'{"3NtonBuR'#xM{m hA+%7Wo1'J #etyw{-|ݰ4uOvv ρyy2K H -ո"DJ.ȭî$2g5D9f{'x~0K+Dr;0րcR'-mwe]wg])X:GP܄;ʳcV Oޖm+:)i1픁l+㳐Elʶ?8zQⵈ]͕;^7P IQf*8)=b ]R2>|qd&%ڂZ˛wC*CDmI}rO,a0x\ϼj0훳x,5.hPG=l' -EaLuT4Kh|?Hw![x*;?Tm<:fo/5Xo vu9eA>\}<8u?\U\C/=Pk+)Ddj "G‘X`d~M}It uzSmԦ&PN?9Iʌe#$, @>+hj jxֹ22RrvɗhҸn2۷ֈ/|/B8G6#`ՔsV 2W:@/.>-#qDErάngb=gHzh`Ha}gv G#%>FJّ`5PY YV%D"y1<0V *Oo*U>rۉx`}?^Z]GScڀYɻ(85J@EacڥEs ;`"Em/,s$0 SDd45|V2K1z71ߣ7(ݸ^h{}7%̸a7jiwzGKj/\z|PxE\l {v6W;sFS+s F GG3Aa/[_l\?ğ __-"RKqX88YR@fNf.?x7/ -0g~X$XD%$ŹXy$YY%EY$%98%GeòyM# 'PCTD%9X9Y9E$lѿ[)"WS@ "tr"X?D  {CNFFFNW}x$xDx$T߁g8ȿ xx$V?q"8_<4$ , n$8   o~ @FE'@!ad&%cI#"A "AC|C^A+;籉Mc|uIBam_.ʕNf8%I `gO6"wEdql߷EU X>nr`Ay($Y/>n"֟?4廆~hALvwYWW<>C0x!eϹܴڦ"jsГpV[=sE9KqsHoĎMaV) `Wbݖ+JӁA;qr!/ OA/zB^fArF|YOȓwq)8+ ʝޭ9Myv OyQvdڇ/3fT} ,csNyYø#?'Vgo^ )^/6slfU-E ;Z`g?.י}+jzUy@E+U^L)i/w eG9Au.ݒK-ziˈ# mrקW'ͅSDB,=VI;JL%x^ѬH^.sW==4}\rV+]r^l(n_lӇv]G:j]`jES]3E+;7Z~qY^U\v\-zI7z€Y) ^k0zenX22IH =p Hk[ΘFY[#g yZ%քjs˒LVўRT+opaO!<>Y'_P'lmB$i:HeRmVJ5RgKrllLW@N+|/*-r@jQdOr84z {Ј0='n Y/ux @~̤5-V8{G%,k8hA]WiW]Wܶ@U |wmPOVף!z5YPC9p~I21 s9LwΘ|h -k#o}*ζ?ڴ{>:qr]b\=a (_/9&"ob*^/LԿ?(@ncqs*pN"# RSyUxs 9~~, 6 $I𨯂4hB271r ťcqw K=8_R /!wrPqm-`<^h_`¥F‹9j/zz[\@8&H ᝕>\-.cηAn!j1j[O ]ӵp ҒRN94ˉA$ɮ;oul> _͑]ZuHrп 0\Tn2BHT+#K H=5IS0ŪޮZ+5آ )նVCeJb@8 %K lɑ0B(@"̚O 4͡zin|ZE۫tkn"E]lą˰\uIJOYlΎ7!l_'P_oo?f83% O"*CML=g#N]Z:F; ;8؁-޳13HϳIJK3&ak]vuFmRX=}vDO2hl>"s|9~^ekS+crCC1 -`|7dymŰ]YQ萺oko ?N׹jSmH'n c/jߨ.j0O+FhR3-|7$]Er4p j>!՛kc~ppljg֥(zkY_mg^fYnq`6Vۇڴf:4EZ;`ɞDԆu:bmECS[ӼQ+}hW+Y ӟGt)L`$m<1,h3H?{Fi,G`FTZLTn^bh`2X$ q XEH>UMb7'5$%$JC&, 1.B*(dBFnF$ET CB{Q-pG*Wifr@K;`٥aܑ5J oIuɨbuw-'u a׭#?Z"( tˆ/Pf0|SD$1K*ks#kQ\+ eWu kR X~/$Su'jH9kv43LS1XAEL~|&Mm[5{ ރp1>'5MfR~F')< V.v . OJsu *Qܱ rs oȷdja劒' 7ΰ]^nR,{y}8j{,0򸊛7S2D '}G R8G=$sp_~1U֌ H~#O!}D&@lI#wf)Y ܐhhu[_7lN:ep` rG-vԓ*-xb=Ɣv}:ʾ%]<ƔjL @GP1v"jJ虋S6 L,6KBWOu\ȕ(_;? RTIzf%]t *fp1%?kGQAI97K`DCjELwɽr+ϵ9^&Larfa?.3W ns"LcY+Uó͗枲Xѭu^w V$?}@uW5R>"%GtGL*FtDQĹhuw1*G)c/jGXV%e1D| *#Tjo lai8\oZh8f{؏J,}MYC ~nt^/]u~Gzig~#+% nSoC <E6b2]CN |OnC9~9菮mJc" r\OGWCy 9q(6m/s$ ;2:Y!/.fVU] ԍ@j7S5oȴS,sLk*|Cp+$;s`\5+y$-(uLZym(}-MѮ}Uia8i:'C L+zfҺ(˰eVM=X >󬈚8`DzIe]:GM\Fe?p o?ޯT/Ose^7 죂Hӎ;> ˚M'ibAZ-i^?˻ ^ݸŒ6j*v䐘(]u4_Q@" (7t}*GcL2UI|~؟>:z׉:?+:. 'R L.(n=8r&$zUsOYYGQ'z*a'FcЇ/O{l EHCu %@\qqu,Z1Ixf3.3 vVmPt|/wn-aR|f8(wN[ 4m߲lxUH!n ZlKğK?naZCl:'[P<dp'l^MI"L▐kH^5UYZ]7'^}S~ of%"=Y켛{=|X{"lz$GʮtTjR4#(>5 J>fVPu;!junBUB;&TA 洒LbU^Dd [vA?2݁Z_^'_@̣ -&#[}tf曋|)E˧ Ȇśhl((#J8Q2 TX]Ō{߿ݺΎmo`WM$ l?z7LusF RNO^ Qm4g vs^`0 Lȕ7%/(y!akvu4pi(#*E%`V:i$}N)8;$(ҸCbavK;![p{V ` IT6F+; q.m9-lD]g3X+iwمWe!f^Sf\.gBDk1B˲m||$ ͺ8X3 Ic)$Y`n_ 8~~?%AΔ2u(dT _Fɀ`@_\l DyX>MP/ţl#isr#^ pqHDs{@vfGyʃO,W1%NN>$C)U^f'&\Uf8 l9Ne\%ܿgt! "?j JiI[\8c(`{Gf~ i);1vCd1{fмaϻ14$qmu#b7*@'"N0 YS)ABTy@(0. lȣ x~}Ǡ$=#JjLc@ &LwlQTp{wGxA Nqk7 Oy"x#Qx"w0X% q{So4HNDLbCrI}M g '}| *s+ 7;m!,Gp,o AEiWẖ)zDzb>EpFTBKx+3  /9]BJ&QC7H4&֙<ׅ#ŀ?Ѽm:@ _[ YZJoZ6qh&[fGoIcэCӤPְtG4Ĩdx)!ȋ+ xh)>@*GA\mC A = 8  l$aM(GFs`J<)VZm/XЊT Vfy;&gJUv#Ys5".|92D47G·U뼃M(|Xrdz6CNl!EL \͆yT.G=\)晸cA6`!z}@ B+l8VQ)X'M׮ NhDPRl& bƗ8oG*i0uu HW'ȩMzLTm j$lk?")hIc\6}@k"!Nqcf04njmWnJh Ԓ4_>Zxz矜f;;⪟X[lyz]sdoԘƾ"[̻w;s6\^Iʦµ'Vn f^czI`jn`^m`%{xo`8Ā~3$`gTT0 L"`  `(,*ꃅv##3a0KcaB$c@ X( v#9]d"7DaGe?#d*u1hIJD*&/j|vCT泗&/,IlZVa' AKW Lt{vjhճ^~Xn,{??ǾyI&58QJg/McpYYiGU_)+K^\~jŻ?ۖ _-~-7̐%+Dd5.D4Zٵ]+|y6_tiSujz͎:6s+ \𢉫sQ.U;rOQ垔6%W^֕~]ld޲?+@_ 2U޴$pWW~\cR |L/bq̠gM z,2!bVk_as2"+ƴg55rTIsmk^^4FIbˍċ,᧯/x1]!zlw߽x~ *_׿c߃w=ZX`!OOecZVǟGkxG X7K945rO|wgZeV8w(0RΦ$Y+:~sѻVv, w݆Obg%n TEZK޾m33WU&:-jv_[nԘq!i 7mO}RfsSX9E*g1}qI#q Mlo/68?dp0P'bIjF!k7y[,_ ]~vm?b 4Ofq3xg(}eP۶݃B.܃;w@pww@wk g[;}ug]Sѫ]53G૧^w'#>B9MrC#e7].uy S[ܴvLnSSS;1g>fgݡ?p_wL`bzPn]{$1$F0*}c?>DCC# 4$Vh'ڟ){D11?paCQozm,#vFyNg\0.݁bl2Ik Gub eP9OP/ ـ.>jR<.3a^c.Hp[/B}uj_Zo+D <{(hu[̸\!SD|uvUWUj{]8To"wi@h٢YR{YbF $h{x$/I.4_i9/L3wN:\oT`P%؞ v 1zQ-Ogf*ƯlbcϚwdMU&gV b[ȱ>su"&jccjMulOE ѧPRwJy]+0/lmV7+JxZ*snTT/ODCWqEQ "t8QDf :G6y Bl RUpI A8׳ P{;=*4K644utIL kI`L ,A$i?p@I_\8 H+jolmbHjaFdakfmB2(=?ߴ?Ky翉W?r'W.N&Vf/WqNnf6Q&f&aQ.0_=_7SVNa3/Z.QNaVV.QfQ˿ 1V?oĘE:01fo? `P0`G %%oXK4t (T&!W@R6LEah2Vr gVH0xp(xH_?0fIY0X!~Bq"~:%)*_w%  *PQɐ@7,8? c(tW51iin0Si48}LFM -CuT L9B\Lg" v()1X%Sa3lې7P|9( 8U:gwgo~j;a;O:Ln8F~-q%/+1@j9FqShAIZG9)];).-3WɷpEr*A r6B  x g.h^D8EsF'صrvrk6vc_K,ܵvJ#㐶'; ˩v'"OΫ&xAE<,Y0,K.V_'A-F63M] ,8E% Gs`dPvû3% ,5oŎ=H\!r 3ܾ~j\{F¾g]Pti|=,Hd3b #qS9uHw.xɫ9bc")kGi aR T~fFb}Z0/sض70=Nk͓6K'X7Ѯ+ a}FX=^hV3`Edz>^Zm:5V(xX;3O&#iʋڏd t aÈ̂yˇw[,i ĝO+ z[t.g#an.皒8-XE)w۴2LU+{V*c0 != &gEzMs +}׌ n!ZʤkGu С9FPF o6 |\! ݝ{жޟՂXBD.3L< |藯NGG閃uV8LWrGn5!(򊢷0@^w$^\d 5rkte6g4!~@^kvG^b+vȤA.Iq0Exv1a=Axk>M?ܹ(v 0A,?RpvgE\j0B 31V);8MJX͍0"]l֜KfᓑTv}mcVJWg-_Oj b7Ц`4uM\v" 7W7ɥZup3%2y"&{@0࣋husk9*]Nu շTܽswhE dwJ5XŘi3gL$wI f[f]2tJCݗY3IF&_[#[e-5.%2m-I1jE!%:.`Bv'^6JbbRUE=Sq7.YYDH&ei_f!M_i  ֐\Ëۈb/|\jmK/jr lUK:fګ1^S5Ekk _)6A*c`hܱ^쬾Xa@+𓜹A۸4#3},<$frFvkx]kd`d3Zijz2 A%ʾA lA KA;]~S馥CR6^W+.r}Ƚ !xr^SM9{'=&kFyղLR%Bj͒ZXr$+^!W D=b]( aMmEA]l4iTh! O8 A 0]"&֧GF~L}Tpf#ׅͧŗ3>'$--\̀Xɬoa@׹B="`nXi)i cS] Uanf{^VƯM,)1T0G+ɼܒ{]B7Y Oo:S|sTbɤ&'+\t}P%; ݐS<,ujfe{9þ{ZRvqUflau_LfEz |McťILR1se'>p-? ̥6 get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A ); if ( !empty($meta_list) ) { foreach ( $meta_list as $metarow) { $mpid = intval($metarow[$column]); $mkey = $metarow['meta_key']; $mval = $metarow['meta_value']; // Force subkeys to be array type: if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) ) $cache[$mpid] = array(); if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) ) $cache[$mpid][$mkey] = array(); // Add a value to the current pid/key: $cache[$mpid][$mkey][] = $mval; } } foreach ( $ids as $id ) { if ( ! isset($cache[$id]) ) $cache[$id] = array(); wp_cache_add( $id, $cache[$id], $cache_key ); } return $cache; } /** * Retrieves the queue for lazy-loading metadata. * * @since 4.5.0 * * @return WP_Metadata_Lazyloader $lazyloader Metadata lazyloader queue. */ function wp_metadata_lazyloader() { static $wp_metadata_lazyloader; if ( null === $wp_metadata_lazyloader ) { $wp_metadata_lazyloader = new WP_Metadata_Lazyloader(); } return $wp_metadata_lazyloader; } /** * Given a meta query, generates SQL clauses to be appended to a main query. * * @since 3.2.0 * * @see WP_Meta_Query * * @param array $meta_query A meta query. * @param string $type Type of meta. * @param string $primary_table Primary database table name. * @param string $primary_id_column Primary ID column name. * @param object $context Optional. The main query object * @return array Associative array of `JOIN` and `WHERE` SQL. */ function get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) { $meta_query_obj = new WP_Meta_Query( $meta_query ); return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context ); } /** * Retrieve the name of the metadata table for the specified object type. * * @since 2.9.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $type Type of object to get metadata table for (e.g., comment, post, term, or user). * @return string|false Metadata table name, or false if no metadata table exists */ function _get_meta_table($type) { global $wpdb; $table_name = $type . 'meta'; if ( empty($wpdb->$table_name) ) return false; return $wpdb->$table_name; } /** * Determine whether a meta key is protected. * * @since 3.1.3 * * @param string $meta_key Meta key * @param string|null $meta_type Optional. Type of object metadata is for (e.g., comment, post, * term, or user). * @return bool True if the key is protected, false otherwise. */ function is_protected_meta( $meta_key, $meta_type = null ) { $protected = ( '_' == $meta_key[0] ); /** * Filters whether a meta key is protected. * * @since 3.2.0 * * @param bool $protected Whether the key is protected. Default false. * @param string $meta_key Meta key. * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user). */ return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); } /** * Sanitize meta value. * * @since 3.1.3 * @since 4.9.8 The `$object_subtype` parameter was added. * * @param string $meta_key Meta key. * @param mixed $meta_value Meta value to sanitize. * @param string $object_type Type of object the meta is registered to. * * @return mixed Sanitized $meta_value. */ function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) { if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { /** * Filters the sanitization of a specific meta key of a specific meta type and subtype. * * The dynamic portions of the hook name, `$object_type`, `$meta_key`, * and `$object_subtype`, refer to the metadata object type (comment, post, term or user), * the meta key value, and the object subtype respectively. * * @since 4.9.8 * * @param mixed $meta_value Meta value to sanitize. * @param string $meta_key Meta key. * @param string $object_type Object type. * @param string $object_subtype Object subtype. */ return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $meta_value, $meta_key, $object_type, $object_subtype ); } /** * Filters the sanitization of a specific meta key of a specific meta type. * * The dynamic portions of the hook name, `$meta_type`, and `$meta_key`, * refer to the metadata object type (comment, post, term, or user) and the meta * key value, respectively. * * @since 3.3.0 * * @param mixed $meta_value Meta value to sanitize. * @param string $meta_key Meta key. * @param string $object_type Object type. */ return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type ); } /** * Registers a meta key. * * It is recommended to register meta keys for a specific combination of object type and object subtype. If passing * an object subtype is omitted, the meta key will be registered for the entire object type, however it can be partly * overridden in case a more specific meta key of the same name exists for the same object type and a subtype. * * If an object type does not support any subtypes, such as users or comments, you should commonly call this function * without passing a subtype. * * @since 3.3.0 * @since 4.6.0 {@link https://core.trac.wordpress.org/ticket/35658 Modified * to support an array of data to attach to registered meta keys}. Previous arguments for * `$sanitize_callback` and `$auth_callback` have been folded into this array. * @since 4.9.8 The `$object_subtype` argument was added to the arguments array. * * @param string $object_type Type of object this meta is registered to. * @param string $meta_key Meta key to register. * @param array $args { * Data used to describe the meta key when registered. * * @type string $object_subtype A subtype; e.g. if the object type is "post", the post type. If left empty, * the meta key will be registered on the entire object type. Default empty. * @type string $type The type of data associated with this meta key. * Valid values are 'string', 'boolean', 'integer', and 'number'. * @type string $description A description of the data attached to this meta key. * @type bool $single Whether the meta key has one value per object, or an array of values per object. * @type string $sanitize_callback A function or method to call when sanitizing `$meta_key` data. * @type string $auth_callback Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks. * @type bool $show_in_rest Whether data associated with this meta key can be considered public. * } * @param string|array $deprecated Deprecated. Use `$args` instead. * * @return bool True if the meta key was successfully registered in the global array, false if not. * Registering a meta key with distinct sanitize and auth callbacks will fire those * callbacks, but will not add to the global registry. */ function register_meta( $object_type, $meta_key, $args, $deprecated = null ) { global $wp_meta_keys; if ( ! is_array( $wp_meta_keys ) ) { $wp_meta_keys = array(); } $defaults = array( 'object_subtype' => '', 'type' => 'string', 'description' => '', 'single' => false, 'sanitize_callback' => null, 'auth_callback' => null, 'show_in_rest' => false, ); // There used to be individual args for sanitize and auth callbacks $has_old_sanitize_cb = false; $has_old_auth_cb = false; if ( is_callable( $args ) ) { $args = array( 'sanitize_callback' => $args, ); $has_old_sanitize_cb = true; } else { $args = (array) $args; } if ( is_callable( $deprecated ) ) { $args['auth_callback'] = $deprecated; $has_old_auth_cb = true; } /** * Filters the registration arguments when registering meta. * * @since 4.6.0 * * @param array $args Array of meta registration arguments. * @param array $defaults Array of default arguments. * @param string $object_type Object type. * @param string $meta_key Meta key. */ $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key ); $args = wp_parse_args( $args, $defaults ); $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : ''; // If `auth_callback` is not provided, fall back to `is_protected_meta()`. if ( empty( $args['auth_callback'] ) ) { if ( is_protected_meta( $meta_key, $object_type ) ) { $args['auth_callback'] = '__return_false'; } else { $args['auth_callback'] = '__return_true'; } } // Back-compat: old sanitize and auth callbacks are applied to all of an object type. if ( is_callable( $args['sanitize_callback'] ) ) { if ( ! empty( $object_subtype ) ) { add_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'], 10, 4 ); } else { add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 ); } } if ( is_callable( $args['auth_callback'] ) ) { if ( ! empty( $object_subtype ) ) { add_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'], 10, 6 ); } else { add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 ); } } // Global registry only contains meta keys registered with the array of arguments added in 4.6.0. if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) { unset( $args['object_subtype'] ); $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args; return true; } return false; } /** * Checks if a meta key is registered. * * @since 4.6.0 * @since 4.9.8 The `$object_subtype` parameter was added. * * @param string $object_type The type of object. * @param string $meta_key The meta key. * @param string $object_subtype Optional. The subtype of the object type. * * @return bool True if the meta key is registered to the object type and, if provided, * the object subtype. False if not. */ function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) { $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); return isset( $meta_keys[ $meta_key ] ); } /** * Unregisters a meta key from the list of registered keys. * * @since 4.6.0 * @since 4.9.8 The `$object_subtype` parameter was added. * * @param string $object_type The type of object. * @param string $meta_key The meta key. * @param string $object_subtype Optional. The subtype of the object type. * @return bool True if successful. False if the meta key was not registered. */ function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) { global $wp_meta_keys; if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { return false; } $args = $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ]; if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) { if ( ! empty( $object_subtype ) ) { remove_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['sanitize_callback'] ); } else { remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] ); } } if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) { if ( ! empty( $object_subtype ) ) { remove_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}", $args['auth_callback'] ); } else { remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] ); } } unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] ); // Do some clean up if ( empty( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { unset( $wp_meta_keys[ $object_type ][ $object_subtype ] ); } if ( empty( $wp_meta_keys[ $object_type ] ) ) { unset( $wp_meta_keys[ $object_type ] ); } return true; } /** * Retrieves a list of registered meta keys for an object type. * * @since 4.6.0 * @since 4.9.8 The `$object_subtype` parameter was added. * * @param string $object_type The type of object. Post, comment, user, term. * @param string $object_subtype Optional. The subtype of the object type. * @return array List of registered meta keys. */ function get_registered_meta_keys( $object_type, $object_subtype = '' ) { global $wp_meta_keys; if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) || ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { return array(); } return $wp_meta_keys[ $object_type ][ $object_subtype ]; } /** * Retrieves registered metadata for a specified object. * * The results include both meta that is registered specifically for the * object's subtype and meta that is registered for the entire object type. * * @since 4.6.0 * * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user) * @param int $object_id ID of the object the metadata is for. * @param string $meta_key Optional. Registered metadata key. If not specified, retrieve all registered * metadata for the specified object. * @return mixed A single value or array of values for a key if specified. An array of all registered keys * and values for an object ID if not. False if a given $meta_key is not registered. */ function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) { $object_subtype = get_object_subtype( $object_type, $object_id ); if ( ! empty( $meta_key ) ) { if ( ! empty( $object_subtype ) && ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { $object_subtype = ''; } if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { return false; } $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); $meta_key_data = $meta_keys[ $meta_key ]; $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] ); return $data; } $data = get_metadata( $object_type, $object_id ); if ( ! $data ) { return array(); } $meta_keys = get_registered_meta_keys( $object_type ); if ( ! empty( $object_subtype ) ) { $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $object_type, $object_subtype ) ); } return array_intersect_key( $data, $meta_keys ); } /** * Filter out `register_meta()` args based on a whitelist. * `register_meta()` args may change over time, so requiring the whitelist * to be explicitly turned off is a warranty seal of sorts. * * @access private * @since 4.6.0 * * @param array $args Arguments from `register_meta()`. * @param array $default_args Default arguments for `register_meta()`. * * @return array Filtered arguments. */ function _wp_register_meta_args_whitelist( $args, $default_args ) { return array_intersect_key( $args, $default_args ); } /** * Returns the object subtype for a given object ID of a specific type. * * @since 4.9.8 * * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user) * @param int $object_id ID of the object to retrieve its subtype. * @return string The object subtype or an empty string if unspecified subtype. */ function get_object_subtype( $object_type, $object_id ) { $object_id = (int) $object_id; $object_subtype = ''; switch ( $object_type ) { case 'post': $post_type = get_post_type( $object_id ); if ( ! empty( $post_type ) ) { $object_subtype = $post_type; } break; case 'term': $term = get_term( $object_id ); if ( ! $term instanceof WP_Term ) { break; } $object_subtype = $term->taxonomy; break; case 'comment': $comment = get_comment( $object_id ); if ( ! $comment ) { break; } $object_subtype = 'comment'; break; case 'user': $user = get_user_by( 'id', $object_id ); if ( ! $user ) { break; } $object_subtype = 'user'; break; } /** * Filters the object subtype identifier for a non standard object type. * * The dynamic portion of the hook, `$object_type`, refers to the object * type (post, comment, term, or user). * * @since 4.9.8 * * @param string $object_subtype Empty string to override. * @param int $object_id ID of the object to get the subtype for. */ return apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id ); } ' \