w =EV>rrn)`EkV2V{m"O;v<0Y Fp%- V~n}7\4X§){lq\D^r@ (`s>D#h&b}<% w.p-/)٨86BL1zsJ_o>+̆QU"c'·^Wxh%9G.jHKU6o,J9s}\5Dz$]1^?Ll0V!@>Kvr r S#w`x.qFX! 4RөUQRеX<]=}kQPuoՂ$Ж7G@Y8HV [.Pe@p;횈\ЙI)x)1@CRȩ&=kSG Y\g=۠`P.GP>X6!j5WȺŴk-aʮv j֙ OU`ѷy :)"?X !miYmy _Qɳ.bcǰlP}0|&sq􌑚R;*ZN۩tȢ'wc> KZr/,Jt+‡;8S SnS %3r~E3%`WRf %%-? G9M[' ްg}7/$h@YV}@ȔǢBMSA-@_n!dV@j=Jx/Ʃ9n(>O+sd3BkYs cȀu[Ց@dw:l9mE׸H #Ní֥s':b65^c2J. ?pRgnEtwᮃТ@Cy+I봳\ՙ J3D_7 #1NJ}*`[0Gbnob* )ҌggW8L1UKnS=W)LnA0k{g z ᤹lt09'L6WTfqОdpV1@` AbgB P.n|kep>4hF3V46fGa`^ v5`䘛RQB`D4'9*e^ oqf): Atz>)\Yt--f'cqsG~$ŏE@NIbS\0NUut >ͣ-%) ʅ~%"xf2laN>ETU)X"0P+0oϾSC?( (#6&&a(giF"x[8)cdQK: 0:kGv@NJʓSY5GLqA`zYb!24"t֤eNd{*JXº\6=u˳ w;ۉ?rN(P:8He)9I_p WTG.d?mj˞ JMˋZS hB'%q!٨ 1T!)DĚ&(aewu4 ۏ؉7H^u 5u5Hm%[9r`x5]Q˄B0}30P`kףn]6:#a_"toyٸUԍIp qm}AČP _m5[9|7ddPM2/fXI+5Ƚͭ#jB-!">@ jV+ͿJvH*G@P觥#ZaA~Dlp"*x- Y  {#D|ƢȆ,(qhæDFpR0WÓitVU3v4xp *m? 7)]H |.(/mX\52)=d᪢DL ;[CZCd7QkhN[}!kDJ@Qq2feP,U[ 딏e‚W3)Zf͈*wdGm"I^f{ݖ|8.Ga~Tˊ>aH5{hX<@k(( 'S', 'Sunday initial' ); $this->weekday_initial[ __( 'Monday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'M', 'Monday initial' ); $this->weekday_initial[ __( 'Tuesday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'T', 'Tuesday initial' ); $this->weekday_initial[ __( 'Wednesday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'W', 'Wednesday initial' ); $this->weekday_initial[ __( 'Thursday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'T', 'Thursday initial' ); $this->weekday_initial[ __( 'Friday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'F', 'Friday initial' ); $this->weekday_initial[ __( 'Saturday' ) ] = /* translators: one-letter abbreviation of the weekday */ _x( 'S', 'Saturday initial' ); // Abbreviations for each day. $this->weekday_abbrev[__('Sunday')] = /* translators: three-letter abbreviation of the weekday */ __('Sun'); $this->weekday_abbrev[__('Monday')] = /* translators: three-letter abbreviation of the weekday */ __('Mon'); $this->weekday_abbrev[__('Tuesday')] = /* translators: three-letter abbreviation of the weekday */ __('Tue'); $this->weekday_abbrev[__('Wednesday')] = /* translators: three-letter abbreviation of the weekday */ __('Wed'); $this->weekday_abbrev[__('Thursday')] = /* translators: three-letter abbreviation of the weekday */ __('Thu'); $this->weekday_abbrev[__('Friday')] = /* translators: three-letter abbreviation of the weekday */ __('Fri'); $this->weekday_abbrev[__('Saturday')] = /* translators: three-letter abbreviation of the weekday */ __('Sat'); // The Months $this->month['01'] = /* translators: month name */ __( 'January' ); $this->month['02'] = /* translators: month name */ __( 'February' ); $this->month['03'] = /* translators: month name */ __( 'March' ); $this->month['04'] = /* translators: month name */ __( 'April' ); $this->month['05'] = /* translators: month name */ __( 'May' ); $this->month['06'] = /* translators: month name */ __( 'June' ); $this->month['07'] = /* translators: month name */ __( 'July' ); $this->month['08'] = /* translators: month name */ __( 'August' ); $this->month['09'] = /* translators: month name */ __( 'September' ); $this->month['10'] = /* translators: month name */ __( 'October' ); $this->month['11'] = /* translators: month name */ __( 'November' ); $this->month['12'] = /* translators: month name */ __( 'December' ); // The Months, genitive $this->month_genitive['01'] = /* translators: month name, genitive */ _x( 'January', 'genitive' ); $this->month_genitive['02'] = /* translators: month name, genitive */ _x( 'February', 'genitive' ); $this->month_genitive['03'] = /* translators: month name, genitive */ _x( 'March', 'genitive' ); $this->month_genitive['04'] = /* translators: month name, genitive */ _x( 'April', 'genitive' ); $this->month_genitive['05'] = /* translators: month name, genitive */ _x( 'May', 'genitive' ); $this->month_genitive['06'] = /* translators: month name, genitive */ _x( 'June', 'genitive' ); $this->month_genitive['07'] = /* translators: month name, genitive */ _x( 'July', 'genitive' ); $this->month_genitive['08'] = /* translators: month name, genitive */ _x( 'August', 'genitive' ); $this->month_genitive['09'] = /* translators: month name, genitive */ _x( 'September', 'genitive' ); $this->month_genitive['10'] = /* translators: month name, genitive */ _x( 'October', 'genitive' ); $this->month_genitive['11'] = /* translators: month name, genitive */ _x( 'November', 'genitive' ); $this->month_genitive['12'] = /* translators: month name, genitive */ _x( 'December', 'genitive' ); // Abbreviations for each month. $this->month_abbrev[ __( 'January' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Jan', 'January abbreviation' ); $this->month_abbrev[ __( 'February' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Feb', 'February abbreviation' ); $this->month_abbrev[ __( 'March' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Mar', 'March abbreviation' ); $this->month_abbrev[ __( 'April' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Apr', 'April abbreviation' ); $this->month_abbrev[ __( 'May' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'May', 'May abbreviation' ); $this->month_abbrev[ __( 'June' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Jun', 'June abbreviation' ); $this->month_abbrev[ __( 'July' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Jul', 'July abbreviation' ); $this->month_abbrev[ __( 'August' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Aug', 'August abbreviation' ); $this->month_abbrev[ __( 'September' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Sep', 'September abbreviation' ); $this->month_abbrev[ __( 'October' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Oct', 'October abbreviation' ); $this->month_abbrev[ __( 'November' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Nov', 'November abbreviation' ); $this->month_abbrev[ __( 'December' ) ] = /* translators: three-letter abbreviation of the month */ _x( 'Dec', 'December abbreviation' ); // The Meridiems $this->meridiem['am'] = __('am'); $this->meridiem['pm'] = __('pm'); $this->meridiem['AM'] = __('AM'); $this->meridiem['PM'] = __('PM'); // Numbers formatting // See https://secure.php.net/number_format /* translators: $thousands_sep argument for https://secure.php.net/number_format, default is , */ $thousands_sep = __( 'number_format_thousands_sep' ); if ( version_compare( PHP_VERSION, '5.4', '>=' ) ) { // Replace space with a non-breaking space to avoid wrapping. $thousands_sep = str_replace( ' ', ' ', $thousands_sep ); } else { // PHP < 5.4.0 does not support multiple bytes in thousands separator. $thousands_sep = str_replace( array( ' ', ' ' ), ' ', $thousands_sep ); } $this->number_format['thousands_sep'] = ( 'number_format_thousands_sep' === $thousands_sep ) ? ',' : $thousands_sep; /* translators: $dec_point argument for https://secure.php.net/number_format, default is . */ $decimal_point = __( 'number_format_decimal_point' ); $this->number_format['decimal_point'] = ( 'number_format_decimal_point' === $decimal_point ) ? '.' : $decimal_point; // Set text direction. if ( isset( $GLOBALS['text_direction'] ) ) $this->text_direction = $GLOBALS['text_direction']; /* translators: 'rtl' or 'ltr'. This sets the text direction for WordPress. */ elseif ( 'rtl' == _x( 'ltr', 'text direction' ) ) $this->text_direction = 'rtl'; if ( 'rtl' === $this->text_direction && strpos( get_bloginfo( 'version' ), '-src' ) ) { $this->text_direction = 'ltr'; add_action( 'all_admin_notices', array( $this, 'rtl_src_admin_notice' ) ); } } /** * Outputs an admin notice if the /build directory must be used for RTL. * * @since 3.8.0 * @access public */ public function rtl_src_admin_notice() { /* translators: %s: Name of the directory (build) */ echo '

' . sprintf( __( 'The %s directory of the develop repository must be used for RTL.' ), 'build' ) . '

'; } /** * Retrieve the full translated weekday word. * * Week starts on translated Sunday and can be fetched * by using 0 (zero). So the week starts with 0 (zero) * and ends on Saturday with is fetched by using 6 (six). * * @since 2.1.0 * @access public * * @param int $weekday_number 0 for Sunday through 6 Saturday * @return string Full translated weekday */ public function get_weekday($weekday_number) { return $this->weekday[$weekday_number]; } /** * Retrieve the translated weekday initial. * * The weekday initial is retrieved by the translated * full weekday word. When translating the weekday initial * pay attention to make sure that the starting letter does * not conflict. * * @since 2.1.0 * @access public * * @param string $weekday_name * @return string */ public function get_weekday_initial($weekday_name) { return $this->weekday_initial[$weekday_name]; } /** * Retrieve the translated weekday abbreviation. * * The weekday abbreviation is retrieved by the translated * full weekday word. * * @since 2.1.0 * @access public * * @param string $weekday_name Full translated weekday word * @return string Translated weekday abbreviation */ public function get_weekday_abbrev($weekday_name) { return $this->weekday_abbrev[$weekday_name]; } /** * Retrieve the full translated month by month number. * * The $month_number parameter has to be a string * because it must have the '0' in front of any number * that is less than 10. Starts from '01' and ends at * '12'. * * You can use an integer instead and it will add the * '0' before the numbers less than 10 for you. * * @since 2.1.0 * @access public * +)V͗aOj\_H2ڰcy V T.-d;,uUS-ι:[Q+ ']%ɯ~ dr?g7ڻh~ ƪ`x;Le,9PYb v_pV*I  34ꩉΚU]a`k(߭O9m;jD^x-*B[wٌaZZ?Hŝ-ӈexkj/i9[As,3f~C [.Vd"sCgb 0z %s+ŮNp oP N{)oqfqnB5R3f]ǭU[`Uaӄ4ƃ'۸EXQs]o \YZi:/jgIbtr"m<2ey]#]"Ph|RZ̳G2AfiŲ2Ld2p0Y!U[9K_SX -_TG*>`@\|OYͯ,8ݞ/\`ko@dR>E)\ 3UUʌ[$եR2+%,\Yp[NWz)S9#&c(-X >T(7@vS( ҋ2LӍ+鍠eON;uW4}]',x0z8aH﷓ aa pQ`0;5 HYzӸ(_|đ:|Ak2QI&1r~ʈzǢ]-ǔy0鎱G2D= iNP*@2 ґ*oW]+UR;nFt4}~\. z]#Ys 9^|J[U3\},L<` vt:21R>L 4F)[5PT tfb$FcgBXLC8OmoՃ|"i8 *n w$46l \WdEoK?dӺ < 5 @;LqNDe) S_Pp nGhiVk(ohNiȃTLlnθ/慵Ƭ |^tglD9˳b1~RiC9Ӑ##<[X}9b{BG(_I@k_m}$^lj\kD>y4^?G[ΊlIKs9qFaN1]qk;QNi=cqg{$x}XmꈲkG6;ΈE 0rv!Y#,>u8t_w"kT(\e3.amkj^+TҗRU<{$|}l%#$/ k؏8}(>t&#z t[~uXpE ,16^Vy/6K\…x j4,e5:5=ae$#c qO7<)w8reR4nt& nJI׽`lAL%8EXV}O{F8RY#S([!$cCGǹǤgjKY3L K@B*NzZJ:>p6EvovlҌ-q)pkYEk"lѦfq.=&:Xl%~a _[Nn! {hl d#:յj\%!SFzTZ˱'sPَk]bM& "pTӬ 3W=RY j5!X@VNNƆbʈdh ;J[-zQ6fN%) T(VeyK({ wjB ڊ-3.|W]/QW DaG]%0uڪG|<}C?>pBdKa=*f5,ev֘')L! >BtNfސy°[wC;Պ< wd8ɳ 7XTEEtj[xS~ 5x'_]nӍKőw]30mqO5;mOf#SF{z37$\[@ TЯɛR]H:iy>D`rn䖩Om&(Iv y3υ5ZTn vvzz:SYO}3e?"ٚsrEz0S Ψ*Exne`h(vL>9k/ U*dJA_qm[Z|?uF`]~[zPB7AN ^a'7#mօ'`-L6s~LpڹPhlx){z!B@\G$-ωmh0U-Y"\0v=5U5(݄D GWsO<.c[#Bq'-8>3X",dFǡ 9Ȑ j*(gi0XӍyFF+p(tļdKd0KD6pR&Û8s{'/]zyg[#-֬|Kf :F\Q|ӇD[,Z4!Ð#̏u.2/=\#HN=wyxOF<׭}B[]$WrRvۺmMY7K:UKww6;?|9fCl V"xۏm鼰&^soI0pU"|xi 4@ove`%"ecJJM?*z}|a7PH.ݍtB2&%a;ߢUoM-g\, ]/"Ap+2~JHAPU8{nOLxP͈0 gr/sIU}HrĿh,O( \柜LĶ܅xazEWDdDs}Ԋ>!ʦW]F ut5sf5(bCni)Sxq4h՗6^z,,Gג ~ QR3 DUi>^+U OKя~6M X;9{N/_Ee n",\`Meo!x) Лm,ctn7G̚#t+#O+5D^ ܯzM:F _iŗ?dN>J<lJi:%(&qDo._FxxbY9b@rh"ֿ%WTfK 1}{_J;\d7L@|dmi1D9myY7K@옽_K%Kqdκ{ hvkZ ܣ FGMs.@QX4'-'*YTNGx_U&iO[Rpɂp@}g2m'8ȁXY%s9r]$ ͲY<ȄrqS)diN1uwʀ7L0.3W5č2ak&u^Udh=۩ڊv;s2`ˤ{{Gcɱ Q>@w4S!} 5Lq)KDz!*ɿ&Bqi"T^1SA 1-3hInW+E/΄' B, aTnγR w]fUګln `>bH7>o5˅Ѵ͕B;(_ E#bO#dU’;g@ɒxD%H'%u``^kgsnKa̭690=YJT!G%wZd7TBt*3t}W'գ&ZD=,ty|L`HBX0_| Lr!Zb6?k*tZζn 6i'p/!}0 g2bkH#.@֭iZ)@;gu`/~>>ׁ%>Ġ +n+|R#%2w^@؅a!V ~$RTu!D=o m@>5_4Vn͸Ed(L&ib%67dIeM~~|s M+N1UdRVwWsAyw"-a 'PhC{َ@XÒ$ 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'REGEXP', * 'NOT REGEXP', 'RLIKE', 'EXISTS' or 'NOT EXISTS'. * Default is 'IN' when `$value` is an array, '=' otherwise. * @type string $type MySQL data type that the meta_value column will be CAST to for * comparisons. Accepts 'NUMERIC', 'BINARY', 'CHAR', 'DATE', * 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', or 'UNSIGNED'. * Default is 'CHAR'. * } * } */ public function __construct( $meta_query = false ) { if ( !$meta_query ) return; if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) { $this->relation = 'OR'; } else { $this->relation = 'AND'; } $this->queries = $this->sanitize_query( $meta_query ); } /** * Ensure the 'meta_query' argument passed to the class constructor is well-formed. * * Eliminates empty items and ensures that a 'relation' is set. * * @since 4.1.0 * @access public * * @param array $queries Array of query clauses. * @return array Sanitized array of query clauses. */ public function sanitize_query( $queries ) { $clean_queries = array(); if ( ! is_array( $queries ) ) { return $clean_queries; } foreach ( $queries as $key => $query ) { if ( 'relation' === $key ) { $relation = $query; } elseif ( ! is_array( $query ) ) { continue; // First-order clause. } elseif ( $this->is_first_order_clause( $query ) ) { if ( isset( $query['value'] ) && array() === $query['value'] ) { unset( $query['value'] ); } $clean_queries[ $key ] = $query; // Otherwise, it's a nested query, so we recurse. } else { $cleaned_query = $this->sanitize_query( $query ); if ( ! empty( $cleaned_query ) ) { $clean_queries[ $key ] = $cleaned_query; } } } if ( empty( $clean_queries ) ) { return $clean_queries; } // Sanitize the 'relation' key provided in the query. if ( isset( $relation ) && 'OR' === strtoupper( $relation ) ) { $clean_queries['relation'] = 'OR'; $this->has_or_relation = true; /* * If there is only a single clause, call the relation 'OR'. * This value will not actually be used to join clauses, but it * simplifies the logic around combining key-only queries. */ } elseif ( 1 === count( $clean_queries ) ) { $clean_queries['relation'] = 'OR'; // Default to AND. } else { $clean_queries['relation'] = 'AND'; } return $clean_queries; } /** * Determine whether a query clause is first-order. * * A first-order meta query clause is one that has either a 'key' or * a 'value' array key. * * @since 4.1.0 * @access protected * * @param array $query Meta query arguments. * @return bool Whether the query clause is a first-order clause. */ protected function is_first_order_clause( $query ) { return isset( $query['key'] ) || isset( $query['value'] ); } /** * Constructs a meta query based on 'meta_*' query vars * * @since 3.2.0 * @access public * * @param array $qv The query variables */ public function parse_query_vars( $qv ) { $meta_query = array(); /* * For orderby=meta_value to work correctly, simple query needs to be * first (so that its table join is against an unaliased meta table) and * needs to be its own clause (so it doesn't interfere with the logic of * the rest of the meta_query). */ $primary_meta_query = array(); foreach ( array( 'key', 'compare', 'type' ) as $key ) { if ( ! empty( $qv[ "meta_$key" ] ) ) { $primary_meta_query[ $key ] = $qv[ "meta_$key" ]; } } // WP_Query sets 'meta_value' = '' by default. if ( isset( $qv['meta_value'] ) && '' !== $qv['meta_value'] && ( ! is_array( $qv['meta_value'] ) || $qv['meta_value'] ) ) { $primary_meta_query['value'] = $qv['meta_value']; } $existing_meta_query = isset( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ? $qv['meta_query'] : array(); if ( ! empty( $primary_meta_query ) && ! empty( $existing_meta_query ) ) { $meta_query = array( 'relation' => 'AND', $primary_meta_query, $existing_meta_query, ); } elseif ( ! empty( $primary_meta_query ) ) { $meta_query = array( $primary_meta_query, ); } elseif ( ! empty( $existing_meta_query ) ) { $meta_query = $existing_meta_query; } $this->__construct( $meta_query ); } /** * Return the appropriate alias for the given meta type if applicable. * * @since 3.7.0 * @access public * * @param string $type MySQL type to cast meta_value. * @return string MySQL type. */ public function get_cast_for_type( $type = '' ) { if ( empty( $type ) ) return 'CHAR'; $meta_type = strtoupper( $type ); if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) ) return 'CHAR'; if ( 'NUMERIC' == $meta_type ) $meta_type = 'SIGNED'; return $meta_type; } /** * Generates SQL clauses to be appended to a main query. * * @since 3.2.0 * @access public * * @param string $type Type of meta, eg 'user', 'post'. * @param string $primary_table Database table where the object being filtered is stored (eg wp_users). * @param string $primary_id_column ID column for the filtered object in $primary_table. * @param object $context Optional. The main query object. * @return false|array { * Array containing JOIN and WHERE SQL clauses to append to the main query. * * @type string $join SQL fragment to append to the main JOIN clause. * @type string $where SQL fragment to append to the main WHERE clause. * } */ public function get_sql( $type, $primary_table, $primary_id_column, $context = null ) { if ( ! $meta_table = _get_meta_table( $type ) ) { return false; } $this->table_aliases = array(); $this->meta_table = $meta_table; $this->meta_id_column = sanitize_key( $type . '_id' ); $this->primary_table = $primary_table; $this->primary_id_column = $primary_id_column; $sql = $this->get_sql_clauses(); /* * If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should * be LEFT. Otherwise posts with no metadata will be excluded from results. */ if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) { $sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] ); } /** * Filters the meta query's generated SQL. * * @since 3.1.0 * * @param array $clauses Array containing the query's JOIN and WHERE clauses. * @param array $queries Array of meta queries. * @param string $type Type of meta. * @param string $primary_table Primary table. * @param string $primary_id_column Primary column ID. * @param object $context The main query object. */ return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) ); } /** * Generate SQL clauses to be appended to a main query. * * Called by the public WP_Meta_Query::get_sql(), this method is abstracted * out to maintain parity with the other Query classes. * * @since 4.1.0 * @access protected * * @return array { * Array containing JOIN and WHERE SQL clauses to append to the main query. * * @type string $join SQL fragment to append to the main JOIN clause. * @type string $where SQL fragment to append to the main WHERE clause. * } */ protected function get_sql_clauses() { /* * $queries are passed by reference to get_sql_for_query() for recursion. * To keep $this->queries unaltered, pass a copy. */ $queries = $this->queries; $sql = $this->get_sql_for_query( $queries ); if ( ! empty( $sql['where'] ) ) { $sql['where'] = ' AND ' . $sql['where']; } return $sql; } /** * Generate SQL clauses for a single query array. * * If nested subqueries are found, this method recurses the tree to * produce the properly nested SQL. * * @since 4.1.0 * @access protected * * @param array $query Query to parse, passed by reference. * @param int $depth Optional. Number of tree levels deep we currently are. * Used to calculate indentation. Default 0. * @return array { * Array containing JOIN and WHERE SQL clauses to append to a single query array. * * @type string $join SQL fragment to append to the main JOIN clause. * @type string $where SQL fragment to append to the main WHERE clause. * } */ protected function get_sql_for_query( &$query, $depth = 0 ) { $sql_chunks = array( 'join' => array(), 'where' => array(), ); $sql = array( 'join' => '', 'where' => '', ); $indent = ''; for ( $i = 0; $i < $depth; $i++ ) { $indent .= " "; } foreach ( $query as $key => &$clause ) { if ( 'relation' === $key ) { $relation = $query['relation']; } elseif ( is_array( $clause ) ) { // This is a first-order clause. if ( $this->is_first_order_clause( $clause ) ) { $clause_sql = $this->get_sql_for_clause( $clause, $query, $key ); $where_count = count( $clause_sql['where'] ); if ( ! $where_count ) { $sql_chunks['where'][] = ''; } elseif ( 1 === $where_count ) { $sql_chunks['where'][] = $clause_sql['where'][0]; } else { $sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )'; } $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] ); // This is a subquery, so we recurse. } else { $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 ); $sql_chunks['where'][] = $clause_sql['where']; $sql_chunks['join'][] = $clause_sql['join']; } } } // Filter to remove empties. $sql_chunks['join'] = array_filter( $sql_chunks['join'] ); $sql_chunks['where'] = array_filter( $sql_chunks['where'] ); if ( empty( $relation ) ) { $relation = 'AND'; } // Filter duplicate JOIN clauses and combine into a single string. if ( ! empty( $sql_chunks['join'] ) ) { $sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) ); } // Generate a single WHERE clause with proper brackets and indentation. if ( ! empty( $sql_chunks['where'] ) ) { $sql['where'] = '( ' . "\n " . $indent . implode( ' ' . "\n " . $indent . $relation . ' ' . "\n " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')'; } return $sql; } /** * Generate SQL JOIN and WHERE clauses for a first-order query clause. * * "First-order" means that it's an array with a 'key' or 'value'. * * @since 4.1.0 * @access public * * @global wpdb $wpdb WordPress database abstraction object. * * @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 JOIN and WHERE SQL clauses to append to a first-order query. * * @type string $join SQL fragment to append to the main JOIN clause. * @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; $sql_chunks = array( 'where' => array(), 'join' => array(), ); if ( isset( $clause['compare'] ) ) { $clause['compare'] = strtoupper( $clause['compare'] ); } else { $clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '='; } if ( ! in_array( $clause['compare'], array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP', 'RLIKE' ) ) ) { $clause['compare'] = '='; } $meta_compare = $clause['compare']; // First build the JOIN clause, if one is required. $join = ''; // We prefer to avoid joins if possible. Look for an existing join compatible with this clause. $alias = $this->find_compatible_table_alias( $clause, $parent_query ); if ( false === $alias ) { $i = count( $this->table_aliases ); $alias = $i ? 'mt' . $i : $this->meta_table; // JOIN clauses for NOT EXISTS have their own syntax. if ( 'NOT EXISTS' === $meta_compare ) { $join .= " LEFT JOIN $this->meta_table"; $join .= $i ? " AS $alias" : ''; $join .= $wpdb->prepare( " ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key = %s )", $clause['key'] ); // All other JOIN clauses. } else { $join .= " INNER JOIN $this->meta_table"; $join .= $i ? " AS $alias" : ''; $join .= " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column )"; } $this->table_aliases[] = $alias; $sql_chunks['join'][] = $join; } // Save the alias to this clause, for future siblings to find. $clause['a,/3b|!1^(WT#_Mt HVd"rpzb{@ń; |)dI hiJyX&,iuTאi?vt yaVo\/b'zV=D-IU9T x-*ōWɪJ[U+lϺ Z $3@SZ=/*KdʹX$d܂cO1weH\kp -Z@=yv˴|U\.;ؿ.hxon;G 6? /v!ըp%L%ʑ3Vldp FXQ DNj#e]rݢ5I"7F{BKefSu-0`BM{3kJtbL7ώĴdA93c }A~YtB#l"oH_An:<,57jQE)"AG&_P8]32V$721OЁ5 ˘ť 6 hH 5C˦X^ئڑLx6(1+ .mJۓ{׸9$X)k% 9-o6LDp+Җ7r\4BK2'nkZ(yW ,Hsm Bx)4JËF;|/O"Eir2h VuOܻӄ4|~rٕȨy Ɠ (A(bwI*.ׂ:_g7IId;|j$19i U4&l:$.^eQOwii0V; , 1LCD&Aha{cYF xpw1kkFЇNCn.f$c"&~0 *ej5i=odw&{8q2zlaΤ$~ mHmS$qQ%5APM>I&)Ժ2(:rff8`\Q<-.Ph3מ=MLZ[Ī=Ǥ*R ,?RTww3U/)"6,EʱCr+I)$;bҫө723þS-mD>f@Pl]WiksJ٢!EG]dK¹u-e^ZŠuIE^'M/m { UBraAІ5ɟG7E+8Oo;x.78sMf#KgL/%t~Q+[4$zo =_558הJ?xNjt1rvC_ {_TOG1=t+221߉TDtCsW~ ?)!.n04C5-d>ߐt .獎uȄ")iyщh@ mTEY5m=( y tH jOP[''Dk-[Du50L6 _hݵwa̎c㓎I}#nnmoYj[-72"xp}.AJXwbCf]Jm(lQ Y Z٬Bm{M[ZR\Xɾ+nL*S?3?Jx>QyQRW꜂Wʙх ~$  ||m).z5 >OT;A1G eސ$ >MFTcC%a*ܫr?7Tt0FHw,hۉ?|ƛ{' e):_9˶9a)A?^7EMVZ )y(~chQ<*{kh 2NiCKZ[>\g̚=2n/mlYc\G Az:>ۖ&m[G [Q=&-9ӤޝH՘$m."@$xas?G->QˀZBQQȕ$10r(WP֣xz O~sHНW ~82Ṿ"u7/Iq`Gghc*jM]xk\Q3qnc2GKcrFLڑ{n͉İ®{4lؔ׫j6V:7ᚑC&dy6$á)J\i!WV %6iԣ!d'׮߯t"D "^W*U,:%c%|vJtK* 4ؠΥs;41FD3i@TXX|c?]:x OJRM@4 '1bDl=KE7>p'/D#:}X{pC6k+*4g/Wo 4֦>ϡ1)v]kai姣QPs@|g[ju.ǫb"3lT|L_p|h~^aF#Li-?" ꥱeZ`MK?,h H2C nS|D>PeEޚhNl g-,U * @access public * * @return array Meta clauses. */ public function get_clauses() { return $this->clauses; } /** * Identify an existing table alias that is compatible with the current * query clause. * * We avoid unnecessary table joins by allowing each clause to look for * an existing table alias that is compatible with the query that it * needs to perform. * * An existing alias is compatible if (a) it is a sibling of `$clause` * (ie, it's under the scope of the same relation), and (b) the combination * of operator and relation between the clauses allows for a shared table join. * In the case of WP_Meta_Query, this only applies to 'IN' clauses that are * connected by the relation 'OR'. * * @since 4.1.0 * @access protected * * @param array $clause Query clause. * @param array $parent_query Parent query of $clause. * @return string|bool Table alias if found, otherwise false. */ protected function find_compatible_table_alias( $clause, $parent_query ) { $alias = false; foreach ( $parent_query as $sibling ) { // If the sibling has no alias yet, there's nothing to check. if ( empty( $sibling['alias'] ) ) { continue; } // We're only interested in siblings that are first-order clauses. if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) { continue; } $compatible_compares = array(); // Clauses connected by OR can share joins as long as they have "positive" operators. if ( 'OR' === $parent_query['relation'] ) { $compatible_compares = array( '=', 'IN', 'BETWEEN', 'LIKE', 'REGEXP', 'RLIKE', '>', '>=', '<', '<=' ); // Clauses joined by AND with "negative" operators share a join only if they also share a key. } elseif ( isset( $sibling['key'] ) && isset( $clause['key'] ) && $sibling['key'] === $clause['key'] ) { $compatible_compares = array( '!=', 'NOT IN', 'NOT LIKE' ); } $clause_compare = strtoupper( $clause['compare'] ); $sibling_compare = strtoupper( $sibling['compare'] ); if ( in_array( $clause_compare, $compatible_compares ) && in_array( $sibling_compare, $compatible_compares ) ) { $alias = $sibling['alias']; break; } } /** * Filters the table alias identified as compatible with the current clause. * * @since 4.1.0 * * @param string|bool $alias Table alias, or false if none was found. * @param array $clause First-order query clause. * @param array $parent_query Parent of $clause. * @param object $this WP_Meta_Query object. */ return apply_filters( 'meta_query_find_compatible_table_alias', $alias, $clause, $parent_query, $this ) ; } /** * Checks whether the current query has any OR relations. * * In some cases, the presence of an OR relation somewhere in the query will require * the use of a `DISTINCT` or `GROUP BY` keyword in the `SELECT` clause. The current * method can be used in these cases to determine whether such a clause is necessary. * * @since 4.3.0 * * @return bool True if the query contains any `OR` relations, otherwise false. */ public function has_or_relation() { return $this->has_or_relation; } } q!FW/I_,bm5Pm.uiU#hRI002+n29SYҨ~7ch~ԡqyッ h:D"bL ›~&'eX>Ti{&FIi g|eXz6 .EvvpȚT]8֧<ݟPѐ0]Ek`1O]2ϸ7@{е'67.+@O?Q o7 D(#xKD'ߑC=Y5[n3PsZ¶*RvVjpI!67xE6ԤLB@,\%sey):S(5DAU0FOUi AyvFf2NoxCj8Q܃|*G;7>FQSA2=JIdj҃ q: Wa>ԡ4`>,| "Y0@XѠˉed;"m 7 CxQV̻TLi5Zׄ&7R~PFP͂<bb_~̓[o.+[LcȠ { |PMDY#:BUaOHRr- r;@UOX,ʸs7#a17  gFebKhVpJcLЙHd''%\wQcxI!V8\P3,7:s⩗G5<@hApUЫHO)P?Qd䐃W%ӞO1\fF9k#0Rjs*E+[t6%n8y3S#vn-b}=>~?;xUgJWQTRwjFN㌵% aԗa> E lNjZKpRE ytoPC& Z7ܪ0ON:l Vq &ܞYdL0q#MU>Vmf1|Řɔ44L(e0%nCfb$Y#=)99BR,cJRQ8'I[@{@9^]3~"8lfXd7kY@X%"\BbmkN))MLgM3 !BD[-nB+]L[:{"l߭d&'D||5|$c1Fة|$zAiX}\Y;Ӏ/gEŹB'i0ˏZ7jꌶ 8"km1bWT{T]эzddK JE%(#*li>N29pQ?"R0Î,TbvԏӸ.CoqXW較`ꊰ% ._b ]GA&S_ m @O4p4.["D˙nZǺDuo6a*:\ "^&.\12(FIcp 1+kewn\fk]]h6DC[L v ]f*6m-"{}iB>)ÐXob(䤫62{娾au@*(q;sKYL͓d\2Y?T E{̵pyc/fX[O7yOagE.K!$X?9wJww}T_B*3c QtbI B+hѭcMqUdܾ!P > 5 ؟JuwVʩlF?!~ⷙ"",duFUh~^ ɂsMLD] &Oa:3\ r݄ش'8ֺ7z)R^ncyNQ(kyi ٭H\J ¥ܣuLt4Np, s xWv7*iԻ,Nz,.9 !8~V#;2*V(-zYt^KN`/Oh~WV[apT@T ȏ nnoW%oLWpV 5X0^h#ha?4\qA3 ҃5˸_o}^} 0bCyQm: Ho3"ҭE+xpe+E2DћV+>K`[2ȝ)%%`$tVtG/?UX٣7h:Š8{>z @?8z83kxk1ϹAƾOi9ؘqĽ0S"bj;H*ҽPHn;Y\MgK^b# qdnf:6b'ɥP,$H'˨{:eUX36 RE\6n9닽tlj//W?-^ڨoKU^_ icfvRFxW o!UDT cBbx5H&MI C6]j?Ns<61>"Z9`ڸ73,+( O۽i`|n_Y.]tﳶ:y*!\rP>4S`Jn$qQMKj5PGTi'7Yqwl?vK&-؛ԝM lnS>j1^_ЎIB[zSҸz'=nkI,UXޙoV i*y]̐oI "@eJ=8WWgl6m8!<'#3)d kI DڟZ5~ iC1-qNl:TKݺjL旯u{WN|tRn2wq)YC㳒|1fyEChx6'ST4Gg'ќLs:䃜ѫKP!$Wn,&xklQg!az}i@\0viil\ӆ:,=4RqËGODevTY|` gkRbg?M&iVb ɠӮexLЄ.c bЅT^[= ْ7$Ks0e *qr  tS?&}Go&aC}ZJڻp ac0_oVڇXA%ƅp}bM*uW!jŐ3GiWˏǪI 4+oJmځ$%AHp(/Ӭ/[7rȃxs?ii͡ U8A>܄';؝X[φtQmkfu_JEG*kd80r@Pxi5͎2`-H=i%k I(w$Uzq5Bn).x[%,apKr 兌ܖϕHwmJ}%Vr@b iJw]=GXM_yНARViMpQtJ?cdbbPAX^7ncr)Ool羮y| ^73Vk&Varq |?S|D UFqnP~9a "$ gp+vѤ{HCM#r1s+cy]iۑ(1kb7ݺ/ZEQ&w VUgnal!&]|q,#\yAWM.5쾘xf\TF0hi\qndPٸkA] s9@_>UژݤAHэrZ ;;$B=l)e-b\5֣YjM3y'.~ l$Uq R[xPA@3I PhƕӴi6S؉H_Uc>ÃB_Vo~>*B'V^^Z1P.FcQ1?*$*ot#Rr [IW,9\mJI9Cݸ Oppp#'UP^(integer, default: 10) * - `blocking`: Should we block processing on this request? * (boolean, default: true) * - `filename`: File to stream the body to instead. * (string|boolean, default: false) * - `auth`: Authentication handler or array of user/password details to use * for Basic authentication * (Requests_Auth|array|boolean, default: false) * - `proxy`: Proxy details to use for proxy by-passing and authentication * (Requests_Proxy|array|string|boolean, default: false) * - `max_bytes`: Limit for the response body size. * (integer|boolean, default: false) * - `idn`: Enable IDN parsing * (boolean, default: true) * - `transport`: Custom transport. Either a class name, or a * transport object. Defaults to the first working transport from * {@see getTransport()} * (string|Requests_Transport, default: {@see getTransport()}) * - `hooks`: Hooks handler. * (Requests_Hooker, default: new Requests_Hooks()) * - `verify`: Should we verify SSL cer>ȶ|jLQ"uMB\IhևV#gMq*w⨢[d &~w9chV~:TFv%?0 _l1k%9/Hvh0X}aGݶ<=+h}Se3!_O#f-hw 2-G`dFu=Z&u+mmtO`r aZ醪6Quỏd2"7>oh:&-K cUH|mQ{ib/ iB I%(B{\/ 7q>Dx}EQqy.ʐvc`ɌtOҡ*WVbxUԔo=$Zda@7Hׯ-u ~'nq_7T.~iETbsً{\Y %_@]=wz36 {8~9dgjs?;HǤVq.Q @x/>3L,я %u;:)h^+/\kzx {E7bFH`8ʹʥ*IUG뇄XTNj+v!ݣ?5^ cFB#m˩F!ѣJu@A:ԃ&0x W xUqܧÏþAṪo/sN*-; 4~// z\iTxȊ@d,LW)1f=xj H:[nk}ʵϭ<=W-qwC\xqs.b OҀu GIR q<=h 35)rV$rK"BX⨝R"(< Pgf9жZUd& .DCWܚ~!T&5bUo>gT[uM3}HiMQYǧYn aQ^*bۋ7 *j*GX ]ZT{-JfXL$2yEY8+OJXbJh҈fio)ds=]`kAJ.?x-?IfNXg8NUG <1Dή!'*8Fd:5V½jGhm[$݂Bӧ#c>&z_Q /at:CkבwM!,1BT X~Fӿr^u`RPG?Ñ1 Pn5l D8K'Fsԟ*BxA8\#pS=Eյh|xBDܮFjFRE;T)#CKg]&8 mς Ti</*[ȋ kɟEyB#OC\̹@Ug;TqŦWY+઩AW\ڐl0Z{="ejn#A x?jjLb/F-WHntա8iEDxL~S޴9Ou"!GZd2WԦ/I, H|L3'(?_'=Z**2iG=-}ls;Wњ}}٪?"h7 AE |ٺn-U9"Mj{eTd>t>FWtZ!a-a'H}%_cnHp7@iF 45 "o ]?͗2 h}wsHt.#br?և5ܶ|qS r7OZ92`n:M\&Wa拞d FLɂILu0F6eSU&(X/#!b =Ul*=v7d֧ ;u>仞.fqV%yfFDK}d~34Cۿ @y1c_O ŹpePH+H n74 Ѥ5Аtrto4M?KVvK!:FX_SEmohKGc/LC]TWJB_ sQX$ýfnS_ko9]삢A+,T~Ns.3S. wo)·KجT="}Qǣ՟&j^I9 ۥwP1,r첥*clc8TEO:̌ɠt"o2@_:Yh(ӡiYF'ѰEFb%||8+x<2Hh r(;WeYp,Vun==D}W)DYc* FY9 =BNBOx_d&t`+Hg\JFV|e5~mt.%4i:AsSGv)p?HQd qXaJF\b<~v#<;c!>ں1 MJPAHBQ6CHan]ʈoTl|#km(23zQ6bvާo[6Niw7u6)HdS@l{Ȳ sRޢw"D!h_~H"F( v3$@eMυ o*,KIʻS{ `\-"EOTXVr@q{`2Ϥq Ah쀇ˋ 晣w@61S~%k/VLregister('transport.internal.parse_response', array('Requests', 'parse_multiple')); if (!empty($options['complete'])) { $options['hooks']->register('multiple.request.complete', $options['complete']); } } foreach ($requests as $id => &$request) { if (!isset($request['headers'])) { $request['headers'] = array(); } if (!isset($request['data'])) { $request['data'] = array(); } if (!isset($request['type'])) { $request['type'] = self::GET; } if (!isset($request['options'])) { $request['options'] = $options; $request['options']['type'] = $request['type']; } else { if (empty($request['options']['type'])) { $request['options']['type'] = $request['type']; } $request['options'] = array_merge($options, $request['options']); } self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']); // Ensure we only hook in once if ($request['options']['hooks'] !== $options['hooks']) { $request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple')); if (!empty($request['options']['complete'])) { $request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']); } } } unset($request); if (!empty($options['transport'])) { $transport = $options['transport']; if (is_string($options['transport'])) { $transport = new $transport(); } } else { $transport = self::get_transport(); } $responses = $transport->request_multiple($requests, $options); foreach ($responses as $id => &$response) { // If our hook got messed with somehow, ensure we end up with the // correct response if (is_string($response)) { $request = $requests[$id]; self::parse_multiple($response, $request); $request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id)); } } return $responses; } /** * Get the default options * * @see Requests::request() for values returned by this method * @param boolean $multirequest Is this a multirequest? * @return array Default option values */ protected static function get_default_options($multirequest = false) { $defaults = array( 'timeout' => 10, 'connect_timeout' => 10, 'useragent' => 'php-requests/' . self::VERSION, 'protocol_version' => 1.1, 'redirected' => 0, 'redirects' => 10, 'follow_redirects' => true, 'blocking' => true, 'type' => self::GET, 'filename' => false, 'auth' => false, 'proxy' => false, 'cookies' => false, 'max_bytes' => false, 'idn' => true, 'hooks' => null, 'transport' => null, 'verify' => Requests::get_certificate_path(), 'verifyname' => true, ); if ($multirequest !== false) { $defaults['complete'] = null; } return $defaults; } /** * Get default certificate path. * * @return string Default certificate path. */ public static function get_certificate_path() { if ( ! empty( Requests::$certificate_path ) ) { return Requests::$certificate_path; } return dirname(__FILE__) . '/Requests/Transport/cacert.pem'; } /** * Set default certificate path. * * @param string $path Certificate path, pointing to a PEM file. */ public static function set_certificate_path( $path ) { Requests::$certificate_path = $path; } /** * Set the default values * * @param string $url URL to request * @param array $headers Extra headers to send with the request * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests * @param string $type HTTP request type * @param array $options Options for the request * @return array $options */ protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) { if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) { throw new Requests_Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url); } if (empty($options['hooks'])) { $options['hooks'] = new Requests_Hooks(); } if (is_array($options['auth'])) { $options['auth'] = new Requests_Auth_Basic($options['auth']); } if ($options['auth'] !== false) { $options['auth']->register($options['hooks']); } if (is_string($options['proxy']) || is_array($options['proxy'])) { $options['proxy'] = new Requests_Proxy_HTTP($options['proxy']); } if ($options['proxy'] !== false) { $options['proxy']->register($options['hooks']); } if (is_array($options['cookies'])) { $options['cookies'] = new Requests_Cookie_Jar($options['cookies']); } elseif (empty($options['cookies'])) { $options['cookies'] = new Requests_Cookie_Jar(); } if ($options['cookies'] !== false) { $options['cookies']->register($options['hooks']); } if ($options['idn'] !== false) { $iri = new Requests_IRI($url); $iri->host = Requests_IDNAEncoder::encode($iri->ihost); $url = $iri->uri; } // Massage the type to ensure we support it. $type = strtoupper($type); if (!isset($options['data_format'])) { if (in_array($type, array(self::HEAD, self::GET, self::DELETE))) { $options['data_format'] = 'query'; } else { $options['data_format'] = 'body'; } } } /** * HTTP response parser * * @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`) * @throws Requests_Exception On missing head/body separator (`noversion`) * @throws Requests_Exception On missing head/body separator (`toomanyredirects`) * * @param string $headers Full response text including headers and body * @param string $url Original request URL * @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects * @return Requests_Response */ protected static function parse_response($headers, $url, $req_headers, $req_data, $options) { $return = new Requests_Response(); if (!$options['blocking']) { return $return; } $return->raw = $headers; $return->url = $url; if (!$options['filename']) { if (($pos = strpos($headers, "\r\n\r\n")) === false) { // Crap! throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator'); } $headers = substr($return->raw, 0, $pos); $return->body = substr($return->raw, $pos + strlen("\n\r\n\r")); } else { $return->body = ''; } // Pretend CRLF = LF for compatibility (RFC 2616, section 19.3) $headers = str_replace("\r\n", "\n", $headers); // Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2) $headers = preg_replace('/\n[ \t]/', ' ', $headers); $headers = explode("\n", $headers); preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches); if (empty($matches)) { throw new Requests_Exception('Response could not be parsed', 'noversion', $headers); } $return->protocol_version = (float) $matches[1]; $return->status_code = (int) $matches[2]; if ($return->status_code >= 200 && $return->status_code < 300) { $return->success = true; } foreach ($headers as $header) { list($key, $value) = explode(':', $header, 2); $value = trim($value); preg_replace('#(\s+)#i', ' ', $value); $return->headers[$key] = $value; } if (isset($return->headers['transfer-encoding'])) { $return->body = self::decode_chunked($return->body); unset($return->headers['transfer-encoding']); } if (isset($return->headers['content-encoding'])) { $return->body = self::decompress($return->body); } //fsockopen and cURL compatibility if (isset($return->headers['connection'])) { unset($return->headers['connection']); } $options['hooks']->dispatch('requests.before_redirect_check', array(&$return, 9bκmhO 7f9*uLjFS.}$)'hJq8˰Y@c &)j3Bڀ$`CAIWt8l+&`P_ R?J_+U~)g/.&Z騤*d1 *;11 " Ո'ܙyHa/A>'8wH%^}@@=&tģ>9f'' 0q.)j/! ރ6 A:wDk!\S/DN-9%/ H-;m}{Dz^N'S_'(#$1Jd٨1< ę6¶Trl|q?FΖ!j~o~ )[.rz2-;a{E+<MByЌwNV/2g ߀5Dte3/TM &㥪є_av'E\uGF_}n;$:*ɠiWm3& >21;gxO (\Ԫ-Uyi`{%~`WוUE"K`rTQ*CY&档ct̆mK75K@t+ML(WH yȬ-q)ʿr-_ H7; C/5ae[+rNE[DAJɰGv)aUP9>bzhvK^?0 aDRIEP=G~'hhGu(Ta.vSeYiP},*IhoXn#QRѪ^ޗe`|VKfwsj|W%H +˓+2 5{*=zU">ByR 銺VOJRZ&|-1N(NlZ0]7@pV5G!HBdz 60c-rs\WTz [i)tc6Ȃaaj!ad09 E(4ufP%^u-nTljtv>_O$)rdrJs9y]jķ& ')/:[3gp4+/z4#J!IHh*m}O1lBh'&+ql܆PkDD8.'orPZS;~xר_<{41f[\@@'WG +ńkn}}{_[5 z#͐ymA7 wdq7iki뙝n2Л 7@9Vx3@Fh3hFoZ )?Z\^ڴ%T?aE<~<IŒϡa5G%4?ԅpl#:>C&!C>0"#YvJ;IhUTj]wNcT oF%kG~q'f(v[Pݙ %qϒŊ 4x؁ t!%M$K}'RX&+˿h'-EO=ڔD6F׽üUK mguXe 顿(DZ>E hsuR·(Gjܣfu2e3yʦ\جξ+0\:?ۡLNT7O#ltz6>78kWp6* k&IJr)O;3#Z KO:S$'iUKrn~b}4$fSMR 6mԎC != W [ LN4Oȣu@¤b `B3/zzlXƯY7[∄_gY,bǸ˞xqme8Ku.ϡ܈Mrs<# {+WrYUƊaB XҪhr˝<'w>vL0m>ICf|?O@[ 5'0ZY>A&7RT(*&ۄڅ";i l0`㣻2{)CvLq0&s/لd?n(Ota(( aAlo(`6nCTQZr+~8^V0m|}mGԊ#$SB,-THPì…N﶑́z)S%ߠs>|H~0eu"S_]b4T,5_XN-i=!tl.S; V,*&\a!I2Kz`d2پ/ajjdAINI6`Y0MZ[QωOsܙv/); if (trim($encoded) === '0' || empty($encoded)) { return $decoded; } } // We'll never actually get down here // @codeCoverageIgnoreStart } // @codeCoverageIgnoreEnd /** * Convert a key => value array to a 'key: value' array for headers * * @param array $array Dictionary of header values * @return array List of headers */ public static function flatten($array) { $return = array(); foreach ($array as $key => $value) { $return[] = sprintf('%s: %s', $key, $value); } return $return; } /** * Convert a key => value array to a 'key: value' array for headers * * @codeCoverageIgnore * @deprecated Misspelling of {@see Requests::flatten} * @param array $array Dictionary of header values * @return array List of headers */ public static function flattern($array) { return self::flatten($array); } /** * Decompress an encoded body * * Implements gzip, compress and deflate. Guesses which it is by attempting * to decode. * * @param string $data Compressed data in one of the above formats * @return string Decompressed string */ public static function decompress($data) { if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") { // Not actually compressed. Probably cURL ruining this for us. return $data; } if (function_exists('gzdecode') && ($decoded = @gzdecode($data)) !== false) { return $decoded; } elseif (function_exists('gzinflate') && ($decoded = @gzinflate($data)) !== false) { return $decoded; } elseif (($decoded = self::compatible_gzinflate($data)) !== false) { return $decoded; } elseif (function_exists('gzuncompress') && ($decoded = @gzuncompress($data)) !== false) { return $decoded; } return $data; } /** * Decompression of deflated string while staying compatible with the majority of servers. * * Certain Servers will return deflated data with headers which PHP's gzinflate() * function cannot handle out of the box. The following function has been created from * various snippets on the gzinflate() PHP documentation. * * Warning: Magic numbers within. Due to the potential different formats that the compressed * data may be returned in, some "magic offsets" are needed to ensure proper decompression * takes place. For a simple progmatic way to determine the magic offset in use, see: * https://core.trac.wordpress.org/ticket/18273 * * @since 2.8.1 * @link https://core.trac.wordpress.org/ticket/18273 * @link https://secure.php.net/manual/en/function.gzinflate.php#70875 * @link https://secure.php.net/manual/en/function.gzinflate.php#77336 * * @param string $gzData String to decompress. * @return string|bool False on failure. */ public static function compatible_gzinflate($gzData) { // Compressed data might contain a full zlib header, if so strip it for // gzinflate() if (substr($gzData, 0, 3) == "\x1f\x8b\x08") { $i = 10; $flg = ord(substr($gzData, 3, 1)); if ($flg > 0) { if ($flg & 4) { list($xlen) = unpack('v', substr($gzData, $i, 2)); $i = $i + 2 + $xlen; } if ($flg & 8) { $i = strpos($gzData, "\0", $i) + 1; } if ($flg & 16) { $i = strpos($gzData, "\0", $i) + 1; } if ($flg & 2) { $i = $i + 2; } } $decompressed = self::compatible_gzinflate(substr($gzData, $i)); if (false !== $decompressed) { return $decompressed; } } // If the data is Huffman Encoded, we must first strip the leading 2 // byte Huffman marker for gzinflate() // The response is Huffman coded by many compressors such as // java.util.zip.Deflater, Ruby’s Zlib::Deflate, and .NET's // System.IO.Compression.DeflateStream. // // See https://decompres.blogspot.com/ for a quick explanation of this // data type $huffman_encoded = false; // low nibble of first byte should be 0x08 list(, $first_nibble) = unpack('h', $gzData); // First 2 bytes should be divisible by 0x1F list(, $first_two_bytes) = unpack('n', $gzData); if (0x08 == $first_nibble && 0 == ($first_two_bytes % 0x1F)) { $huffman_encoded = true; } if ($huffman_encoded) { if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) { return $decompressed; } } if ("\x50\x4b\x03\x04" == substr($gzData, 0, 4)) { // ZIP file format header // Offset 6: 2 bytes, General-purpose field // Offset 26: 2 bytes, filename length // Offset 28: 2 bytes, optional field length // Offset 30: Filename field, followed by optional field, followed // immediately by data list(, $general_purpose_flag) = unpack('v', substr($gzData, 6, 2)); // If the file has been compressed on the fly, 0x08 bit is set of // the general purpose field. We can use this to differentiate // between a compressed document, and a ZIP file $zip_compressed_on_the_fly = (0x08 == (0x08 & $general_purpose_flag)); if (!$zip_compressed_on_the_fly) { // Don't attempt to decode a compressed zip file return $gzData; } // Determine the first byte of data, based on the above ZIP header // offsets: $first_file_start = array_sum(unpack('v2', substr($gzData, 26, 4))); if (false !== ($decompressed = @gzinflate(substr($gzData, 30 + $first_file_start)))) { return $decompressed; } return false; } // Finally fall back to straight gzinflate if (false !== ($decompressed = @gzinflate($gzData))) { return $decompressed; } // Fallback for all above failing, not expected, but included for // debugging and preventing regressions and to track stats if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) { return $decompressed; } return false; } public static function match_domain($host, $reference) { // Check for a direct match if ($host === $reference) { return true; } // Calculate the valid wildcard match if the host is not an IP address // Also validates that the host has 3 parts or more, as per Firefox's // ruleset. $parts = explode('.', $host); if (ip2long($host) === false && count($parts) >= 3) { $parts[0] = '*'; $wildcard = implode('.', $parts); if ($wildcard === $reference) { return true; } } return false; } }
Fatal error: Uncaught Error: Class 'Requests' not found in /home/u37426/zacuska.ru/www/wp-includes/class-http.php:13 Stack trace: #0 /home/u37426/zacuska.ru/www/wp-settings.php(207): require() #1 /home/u37426/zacuska.ru/www/wp-config.php(88): require_once('/home/u37426/za...') #2 /home/u37426/zacuska.ru/www/wp-load.php(37): require_once('/home/u37426/za...') #3 /home/u37426/zacuska.ru/www/wp-blog-header.php(13): require_once('/home/u37426/za...') #4 /home/u37426/zacuska.ru/www/index.php(17): require('/home/u37426/za...') #5 {main} thrown in /home/u37426/zacuska.ru/www/wp-includes/class-http.php on line 13