Your IP : 216.73.216.162


Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/
Upload File :
Current File : /home/x/b/o/xbodynamge/namtation/wp-content/Query.php.tar

home/xbodynamge/namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Query.php000064400000027332151120300110026254 0ustar00<?php
namespace AIOSEO\Plugin\Common\Sitemap;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AIOSEO\Plugin\Common\Utils as CommonUtils;

/**
 * Handles all complex queries for the sitemap.
 *
 * @since 4.0.0
 */
class Query {
	/**
	 * Returns all eligble sitemap entries for a given post type.
	 *
	 * @since 4.0.0
	 *
	 * @param  mixed $postTypes      The post type(s). Either a singular string or an array of strings.
	 * @param  array $additionalArgs Any additional arguments for the post query.
	 * @return array|int             The post objects or the post count.
	 */
	public function posts( $postTypes, $additionalArgs = [] ) {
		$includedPostTypes = $postTypes;
		$postTypesArray    = ! is_array( $postTypes ) ? [ $postTypes ] : $postTypes;
		if ( is_array( $postTypes ) ) {
			$includedPostTypes = implode( "', '", $postTypes );
		}

		if (
			empty( $includedPostTypes ) ||
			( 'attachment' === $includedPostTypes && 'disabled' !== aioseo()->dynamicOptions->searchAppearance->postTypes->attachment->redirectAttachmentUrls )
		) {
			return [];
		}

		// Set defaults.
		$maxAge = '';
		$fields = implode( ', ', [
			'p.ID',
			'p.post_excerpt',
			'p.post_type',
			'p.post_password',
			'p.post_parent',
			'p.post_date_gmt',
			'p.post_modified_gmt',
			'ap.priority',
			'ap.frequency'
		] );

		if ( in_array( aioseo()->sitemap->type, [ 'html', 'rss' ], true ) ) {
			$fields .= ', p.post_title';
		}

		if ( 'general' !== aioseo()->sitemap->type || ! aioseo()->sitemap->helpers->excludeImages() ) {
			$fields .= ', ap.images';
		}

		// Order by highest priority first (highest priority at the top),
		// then by post modified date (most recently updated at the top).
		$orderBy = 'ap.priority DESC, p.post_modified_gmt DESC';

		// Override defaults if passed as additional arg.
		foreach ( $additionalArgs as $name => $value ) {
			// Attachments need to be fetched with all their fields because we need to get their post parent further down the line.
			$$name = esc_sql( $value );
			if ( 'root' === $name && $value && 'attachment' !== $includedPostTypes ) {
				$fields = 'p.ID, p.post_type';
			}
			if ( 'count' === $name && $value ) {
				$fields = 'count(p.ID) as total';
			}
		}

		$query = aioseo()->core->db
			->start( aioseo()->core->db->db->posts . ' as p', true )
			->select( $fields )
			->leftJoin( 'aioseo_posts as ap', 'ap.post_id = p.ID' )
			->where( 'p.post_status', 'attachment' === $includedPostTypes ? 'inherit' : 'publish' )
			->whereRaw( "p.post_type IN ( '$includedPostTypes' )" );

		$homePageId = (int) get_option( 'page_on_front' );

		if ( ! is_array( $postTypes ) ) {
			if ( ! aioseo()->helpers->isPostTypeNoindexed( $includedPostTypes ) ) {
				$query->whereRaw( "( `ap`.`robots_noindex` IS NULL OR `ap`.`robots_default` = 1 OR `ap`.`robots_noindex` = 0 OR post_id = $homePageId )" );
			} else {
				$query->whereRaw( "( `ap`.`robots_default` = 0 AND `ap`.`robots_noindex` = 0 OR post_id = $homePageId )" );
			}
		} else {
			$robotsMetaSql = [];
			foreach ( $postTypes as $postType ) {
				if ( ! aioseo()->helpers->isPostTypeNoindexed( $postType ) ) {
					$robotsMetaSql[] = "( `p`.`post_type` = '$postType' AND ( `ap`.`robots_noindex` IS NULL OR `ap`.`robots_default` = 1 OR `ap`.`robots_noindex` = 0 OR post_id = $homePageId ) )";
				} else {
					$robotsMetaSql[] = "( `p`.`post_type` = '$postType' AND ( `ap`.`robots_default` = 0 AND `ap`.`robots_noindex` = 0 OR post_id = $homePageId ) )";
				}
			}
			$query->whereRaw( '( ' . implode( ' OR ', $robotsMetaSql ) . ' )' );
		}

		$excludedPosts = aioseo()->sitemap->helpers->excludedPosts();

		if ( $excludedPosts ) {
			$query->whereRaw( "( `p`.`ID` NOT IN ( $excludedPosts ) OR post_id = $homePageId )" );
		}

		// Exclude posts assigned to excluded terms.
		$excludedTerms = aioseo()->sitemap->helpers->excludedTerms();
		if ( $excludedTerms ) {
			$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
			$query->whereRaw("
				( `p`.`ID` NOT IN
					(
						SELECT `tr`.`object_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		if ( $maxAge ) {
			$query->whereRaw( "( `p`.`post_date_gmt` >= '$maxAge' )" );
		}

		if (
			'rss' === aioseo()->sitemap->type ||
			(
				aioseo()->sitemap->indexes &&
				empty( $additionalArgs['root'] ) &&
				empty( $additionalArgs['count'] )
			)
		) {
			$query->limit( aioseo()->sitemap->linksPerIndex, aioseo()->sitemap->offset );
		}

		$isStaticHomepage = 'page' === get_option( 'show_on_front' );
		if ( $isStaticHomepage ) {
			$excludedPostIds = array_map( 'intval', explode( ',', $excludedPosts ) );
			$blogPageId      = (int) get_option( 'page_for_posts' );

			if ( in_array( 'page', $postTypesArray, true ) ) {
				// Exclude the blog page from the pages post type.
				if ( $blogPageId ) {
					$query->whereRaw( "`p`.`ID` != $blogPageId" );
				}

				// Custom order by statement to always move the home page to the top.
				if ( $homePageId ) {
					$orderBy = "case when `p`.`ID` = $homePageId then 0 else 1 end, $orderBy";
				}
			}

			// Include the blog page in the posts post type unless manually excluded.
			if (
				$blogPageId &&
				! in_array( $blogPageId, $excludedPostIds, true ) &&
				in_array( 'post', $postTypesArray, true )
			) {
				// We are using a database class hack to get in an OR clause to
				// bypass all the other WHERE statements and just include the
				// blog page ID manually.
				$query->whereRaw( "1=1 OR `p`.`ID` = $blogPageId" );

				// Custom order by statement to always move the blog posts page to the top.
				$orderBy = "case when `p`.`ID` = $blogPageId then 0 else 1 end, $orderBy";
			}
		}

		$query->orderByRaw( $orderBy );
		$query = $this->filterPostQuery( $query, $postTypes );

		// Return the total if we are just counting the posts.
		if ( ! empty( $additionalArgs['count'] ) ) {
			return (int) $query->run( true, 'var' )
				->result();
		}

		$posts = $query->run()
			->result();

		// Convert ID from string to int.
		foreach ( $posts as $post ) {
			$post->ID = (int) $post->ID;
		}

		return $this->filterPosts( $posts );
	}

	/**
	 * Filters the post query.
	 *
	 * @since 4.1.4
	 *
	 * @param  \AIOSEO\Plugin\Common\Utils\Database $query    The query.
	 * @param  string                               $postType The post type.
	 * @return \AIOSEO\Plugin\Common\Utils\Database           The filtered query.
	 */
	private function filterPostQuery( $query, $postType ) {
		switch ( $postType ) {
			case 'product':
				return $this->excludeHiddenProducts( $query );
			default:
				break;
		}

		return $query;
	}

	/**
	 * Adds a condition to the query to exclude hidden WooCommerce products.
	 *
	 * @since 4.1.4
	 *
	 * @param  \AIOSEO\Plugin\Common\Utils\Database $query The query.
	 * @return \AIOSEO\Plugin\Common\Utils\Database        The filtered query.
	 */
	private function excludeHiddenProducts( $query ) {
		if (
			! aioseo()->helpers->isWooCommerceActive() ||
			! apply_filters( 'aioseo_sitemap_woocommerce_exclude_hidden_products', true )
		) {
			return $query;
		}

		static $hiddenProductIds = null;
		if ( null === $hiddenProductIds ) {
			$tempDb         = new CommonUtils\Database();
			$hiddenProducts = $tempDb->start( 'term_relationships as tr' )
				->select( 'tr.object_id' )
				->join( 'term_taxonomy as tt', 'tr.term_taxonomy_id = tt.term_taxonomy_id' )
				->join( 'terms as t', 'tt.term_id = t.term_id' )
				->where( 't.name', 'exclude-from-catalog' )
				->run()
				->result();

			if ( empty( $hiddenProducts ) ) {
				return $query;
			}

			$hiddenProductIds = [];
			foreach ( $hiddenProducts as $hiddenProduct ) {
				$hiddenProductIds[] = (int) $hiddenProduct->object_id;
			}
			$hiddenProductIds = esc_sql( implode( ', ', $hiddenProductIds ) );
		}

		$query->whereRaw( "p.ID NOT IN ( $hiddenProductIds )" );

		return $query;
	}

	/**
	 * Filters the queried posts.
	 *
	 * @since 4.0.0
	 *
	 * @param  array $posts          The posts.
	 * @return array $remainingPosts The remaining posts.
	 */
	public function filterPosts( $posts ) {
		$remainingPosts = [];
		foreach ( $posts as $post ) {
			switch ( $post->post_type ) {
				case 'attachment':
					if ( ! $this->isInvalidAttachment( $post ) ) {
						$remainingPosts[] = $post;
					}
					break;
				default:
					$remainingPosts[] = $post;
					break;
			}
		}

		return $remainingPosts;
	}

	/**
	 * Excludes attachments if their post parent isn't published or parent post type isn't registered anymore.
	 *
	 * @since 4.0.0
	 *
	 * @param  Object  $post The post.
	 * @return boolean       Whether the attachment is invalid.
	 */
	private function isInvalidAttachment( $post ) {
		if ( empty( $post->post_parent ) ) {
			return false;
		}

		$parent = get_post( $post->post_parent );
		if ( ! is_object( $parent ) ) {
			return false;
		}

		if (
			'publish' !== $parent->post_status ||
			! in_array( $parent->post_type, get_post_types(), true ) ||
			$parent->post_password
		) {
			return true;
		}

		return false;
	}

	/**
	 * Returns all eligible sitemap entries for a given taxonomy.
	 *
	 * @since 4.0.0
	 *
	 * @param  string    $taxonomy       The taxonomy.
	 * @param  array     $additionalArgs Any additional arguments for the term query.
	 * @return array|int                 The term objects or the term count.
	 */
	public function terms( $taxonomy, $additionalArgs = [] ) {
		// Set defaults.
		$fields  = 't.term_id';
		$offset  = aioseo()->sitemap->offset;

		// Override defaults if passed as additional arg.
		foreach ( $additionalArgs as $name => $value ) {
			$$name = esc_sql( $value );
			if ( 'root' === $name && $value ) {
				$fields = 't.term_id, tt.count';
			}
			if ( 'count' === $name && $value ) {
				$fields = 'count(t.term_id) as total';
			}
		}

		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
		$termTaxonomyTable      = aioseo()->core->db->db->prefix . 'term_taxonomy';

		// Include all terms that have assigned posts or whose children have assigned posts.
		$query = aioseo()->core->db
			->start( aioseo()->core->db->db->terms . ' as t', true )
			->select( $fields )
			->leftJoin( 'term_taxonomy as tt', '`tt`.`term_id` = `t`.`term_id`' )
			->whereRaw( "
			( `t`.`term_id` IN
				(
					SELECT `tt`.`term_id`
					FROM `$termTaxonomyTable` as tt
					WHERE `tt`.`taxonomy` = '$taxonomy'
					AND 
						(
							`tt`.`count` > 0 OR
							EXISTS (
								SELECT 1
								FROM `$termTaxonomyTable` as tt2
								WHERE `tt2`.`parent` = `tt`.`term_id` 
								AND `tt2`.`count` > 0
							)
						)
				)
			)" );

		$excludedTerms = aioseo()->sitemap->helpers->excludedTerms();
		if ( $excludedTerms ) {
			$query->whereRaw("
				( `t`.`term_id` NOT IN
					(
						SELECT `tr`.`term_taxonomy_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		if (
			aioseo()->sitemap->indexes &&
			empty( $additionalArgs['root'] ) &&
			empty( $additionalArgs['count'] )
		) {
			$query->limit( aioseo()->sitemap->linksPerIndex, $offset );
		}

		// Return the total if we are just counting the terms.
		if ( ! empty( $additionalArgs['count'] ) ) {
			return (int) $query->run( true, 'var' )
				->result();
		}

		$terms = $query->orderBy( 't.term_id ASC' )
			->run()
			->result();

		foreach ( $terms as $term ) {
			// Convert ID from string to int.
			$term->term_id = (int) $term->term_id;
			// Add taxonomy name to object manually instead of querying it to prevent redundant join.
			$term->taxonomy = $taxonomy;
		}

		return $terms;
	}

	/**
	 * Wipes all data and forces the plugin to rescan the site for images.
	 *
	 * @since 4.0.13
	 *
	 * @return void
	 */
	public function resetImages() {
		aioseo()->core->db
			->update( 'aioseo_posts' )
			->set(
				[
					'images'          => null,
					'image_scan_date' => null
				]
			)
			->run();
	}
}lebauwcentre/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/psr7/src/Query.php000064400000006671151140447770031554 0ustar00home/xbodynamge<?php

namespace YoastSEO_Vendor\GuzzleHttp\Psr7;

final class Query
{
    /**
     * Parse a query string into an associative array.
     *
     * If multiple values are found for the same key, the value of that key
     * value pair will become an array. This function does not parse nested
     * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
     * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
     *
     * @param string   $str         Query string to parse
     * @param int|bool $urlEncoding How the query string is encoded
     *
     * @return array
     */
    public static function parse($str, $urlEncoding = \true)
    {
        $result = [];
        if ($str === '') {
            return $result;
        }
        if ($urlEncoding === \true) {
            $decoder = function ($value) {
                return \rawurldecode(\str_replace('+', ' ', $value));
            };
        } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
            $decoder = 'rawurldecode';
        } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
            $decoder = 'urldecode';
        } else {
            $decoder = function ($str) {
                return $str;
            };
        }
        foreach (\explode('&', $str) as $kvp) {
            $parts = \explode('=', $kvp, 2);
            $key = $decoder($parts[0]);
            $value = isset($parts[1]) ? $decoder($parts[1]) : null;
            if (!isset($result[$key])) {
                $result[$key] = $value;
            } else {
                if (!\is_array($result[$key])) {
                    $result[$key] = [$result[$key]];
                }
                $result[$key][] = $value;
            }
        }
        return $result;
    }
    /**
     * Build a query string from an array of key value pairs.
     *
     * This function can use the return value of `parse()` to build a query
     * string. This function does not modify the provided keys when an array is
     * encountered (like `http_build_query()` would).
     *
     * @param array     $params   Query string parameters.
     * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
     *                            to encode using RFC3986, or PHP_QUERY_RFC1738
     *                            to encode using RFC1738.
     *
     * @return string
     */
    public static function build(array $params, $encoding = \PHP_QUERY_RFC3986)
    {
        if (!$params) {
            return '';
        }
        if ($encoding === \false) {
            $encoder = function ($str) {
                return $str;
            };
        } elseif ($encoding === \PHP_QUERY_RFC3986) {
            $encoder = 'rawurlencode';
        } elseif ($encoding === \PHP_QUERY_RFC1738) {
            $encoder = 'urlencode';
        } else {
            throw new \InvalidArgumentException('Invalid type');
        }
        $qs = '';
        foreach ($params as $k => $v) {
            $k = $encoder($k);
            if (!\is_array($v)) {
                $qs .= $k;
                if ($v !== null) {
                    $qs .= '=' . $encoder($v);
                }
                $qs .= '&';
            } else {
                foreach ($v as $vv) {
                    $qs .= $k;
                    if ($vv !== null) {
                        $qs .= '=' . $encoder($vv);
                    }
                    $qs .= '&';
                }
            }
        }
        return $qs ? (string) \substr($qs, 0, -1) : '';
    }
}
home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Html/Query.php000064400000014575151140731540025772 0ustar00<?php
namespace AIOSEO\Plugin\Common\Sitemap\Html;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Handles all queries for the HTML sitemap.
 *
 * @since 4.1.3
 */
class Query {
	/**
	 * Returns all eligible sitemap entries for a given post type.
	 *
	 * @since 4.1.3
	 *
	 * @param  string $postType   The post type.
	 * @param  array  $attributes The attributes.
	 * @return array              The post objects.
	 */
	public function posts( $postType, $attributes ) {
		$fields  = '`ID`, `post_title`,';
		$fields .= '`post_parent`, `post_date_gmt`, `post_modified_gmt`';

		$orderBy = '';
		switch ( $attributes['order_by'] ) {
			case 'last_updated':
				$orderBy = 'post_modified_gmt';
				break;
			case 'alphabetical':
				$orderBy = 'post_title';
				break;
			case 'id':
				$orderBy = 'ID';
				break;
			case 'publish_date':
			default:
				$orderBy = 'post_date_gmt';
				break;
		}

		switch ( strtolower( $attributes['order'] ) ) {
			case 'desc':
				$orderBy .= ' DESC';
				break;
			default:
				$orderBy .= ' ASC';
		}

		$query = aioseo()->core->db
			->start( 'posts' )
			->select( $fields )
			->where( 'post_status', 'publish' )
			->where( 'post_type', $postType );

		$excludedPosts = $this->getExcludedObjects( $attributes );
		if ( $excludedPosts ) {
			$query->whereRaw( "( `ID` NOT IN ( $excludedPosts ) )" );
		}

		$posts = $query->orderBy( $orderBy )
			->run()
			->result();

		foreach ( $posts as $post ) {
			$post->ID = (int) $post->ID;
		}

		return $posts;
	}

	/**
	 * Returns all eligble sitemap entries for a given taxonomy.
	 *
	 * @since 4.1.3
	 *
	 * @param  string $taxonomy   The taxonomy name.
	 * @param  array  $attributes The attributes.
	 * @return array              The term objects.
	 */
	public function terms( $taxonomy, $attributes = [] ) {
		$fields                 = 't.term_id, t.name, tt.parent';
		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
		$termTaxonomyTable      = aioseo()->core->db->db->prefix . 'term_taxonomy';

		$orderBy = '';
		switch ( $attributes['order_by'] ) {
			case 'alphabetical':
				$orderBy = 't.name';
				break;
			// We can only sort by date after getting the terms.
			case 'id':
			case 'publish_date':
			case 'last_updated':
			default:
				$orderBy = 't.term_id';
				break;
		}

		switch ( strtolower( $attributes['order'] ) ) {
			case 'desc':
				$orderBy .= ' DESC';
				break;
			default:
				$orderBy .= ' ASC';
		}

		$query = aioseo()->core->db
			->start( 'terms as t' )
			->select( $fields )
			->join( 'term_taxonomy as tt', 't.term_id = tt.term_id' )
			->whereRaw( "
			( `t`.`term_id` IN
				(
					SELECT `tt`.`term_id`
					FROM `$termTaxonomyTable` as tt
					WHERE `tt`.`taxonomy` = '$taxonomy'
					AND `tt`.`count` > 0
				)
			)" );

		$excludedTerms = $this->getExcludedObjects( $attributes, false );
		if ( $excludedTerms ) {
			$query->whereRaw("
				( `t`.`term_id` NOT IN
					(
						SELECT `tr`.`term_taxonomy_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		$terms = $query->orderBy( $orderBy )
			->run()
			->result();

		foreach ( $terms as $term ) {
			$term->term_id  = (int) $term->term_id;
			$term->taxonomy = $taxonomy;
		}

		$shouldSort = false;
		if ( 'last_updated' === $attributes['order_by'] ) {
			$shouldSort = true;
			foreach ( $terms as $term ) {
				$term->timestamp = strtotime( aioseo()->sitemap->content->getTermLastModified( $term->term_id ) );
			}
		}

		if ( 'publish_date' === $attributes['order_by'] ) {
			$shouldSort = true;
			foreach ( $terms as $term ) {
				$term->timestamp = strtotime( $this->getTermPublishDate( $term->term_id ) );
			}
		}

		if ( $shouldSort ) {
			if ( 'asc' === strtolower( $attributes['order'] ) ) {
				usort( $terms, function( $term1, $term2 ) {
					return $term1->timestamp > $term2->timestamp ? 1 : 0;
				} );
			} else {
				usort( $terms, function( $term1, $term2 ) {
					return $term1->timestamp < $term2->timestamp ? 1 : 0;
				} );
			}
		}

		return $terms;
	}

	/**
	 * Returns a list of date archives that can be included.
	 *
	 * @since 4.1.3
	 *
	 * @return array The date archives.
	 */
	public function archives() {
		$result = aioseo()->core->db
			->start( 'posts', false, 'SELECT DISTINCT' )
			->select( 'YEAR(post_date) AS year, MONTH(post_date) AS month' )
			->where( 'post_type', 'post' )
			->where( 'post_status', 'publish' )
			->whereRaw( "post_password=''" )
			->orderBy( 'year DESC' )
			->orderBy( 'month DESC' )
			->run()
			->result();

		$dates = [];
		foreach ( $result as $date ) {
			$dates[ $date->year ][ $date->month ] = 1;
		}

		return $dates;
	}

	/**
	 * Returns the publish date for a given term.
	 * This is the publish date of the oldest post that is assigned to the term.
	 *
	 * @since 4.1.3
	 *
	 * @param  int $termId The term ID.
	 * @return int         The publish date timestamp.
	 */
	public function getTermPublishDate( $termId ) {
		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';

		$post = aioseo()->core->db
			->start( 'posts as p' )
			->select( 'MIN(`p`.`post_date_gmt`) as publish_date' )
			->whereRaw( "
			( `p`.`ID` IN
				(
					SELECT `tr`.`object_id`
					FROM `$termRelationshipsTable` as tr
					WHERE `tr`.`term_taxonomy_id` = '$termId'
				)
			)" )
			->run()
			->result();

		return ! empty( $post[0]->publish_date ) ? strtotime( $post[0]->publish_date ) : 0;
	}

	/**
	 * Returns a comma-separated string of excluded object IDs.
	 *
	 * @since 4.1.3
	 *
	 * @param  array   $attributes The attributes.
	 * @param  boolean $posts      Whether the objects are posts.
	 * @return string              The excluded object IDs.
	 */
	private function getExcludedObjects( $attributes, $posts = true ) {
		$excludedObjects = $posts
			? aioseo()->sitemap->helpers->excludedPosts()
			: aioseo()->sitemap->helpers->excludedTerms();
		$key             = $posts ? 'excluded_posts' : 'excluded_terms';

		if ( ! empty( $attributes[ $key ] ) ) {
			$ids = explode( ',', $excludedObjects );

			$extraIds = [];
			if ( is_array( $attributes[ $key ] ) ) {
				$extraIds = $attributes[ $key ];
			}
			if ( is_string( $attributes[ $key ] ) ) {
				$extraIds = array_map( 'trim', explode( ',', $attributes[ $key ] ) );
			}

			$ids = array_filter( array_merge( $ids, $extraIds ), 'is_numeric' );

			$excludedObjects = esc_sql( implode( ', ', $ids ) );
		}

		return $excludedObjects;
	}
}home/xbodynamge/www/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/psr7/src/Query.php000064400000006671151142375060027771 0ustar00<?php

namespace YoastSEO_Vendor\GuzzleHttp\Psr7;

final class Query
{
    /**
     * Parse a query string into an associative array.
     *
     * If multiple values are found for the same key, the value of that key
     * value pair will become an array. This function does not parse nested
     * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
     * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
     *
     * @param string   $str         Query string to parse
     * @param int|bool $urlEncoding How the query string is encoded
     *
     * @return array
     */
    public static function parse($str, $urlEncoding = \true)
    {
        $result = [];
        if ($str === '') {
            return $result;
        }
        if ($urlEncoding === \true) {
            $decoder = function ($value) {
                return \rawurldecode(\str_replace('+', ' ', $value));
            };
        } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
            $decoder = 'rawurldecode';
        } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
            $decoder = 'urldecode';
        } else {
            $decoder = function ($str) {
                return $str;
            };
        }
        foreach (\explode('&', $str) as $kvp) {
            $parts = \explode('=', $kvp, 2);
            $key = $decoder($parts[0]);
            $value = isset($parts[1]) ? $decoder($parts[1]) : null;
            if (!isset($result[$key])) {
                $result[$key] = $value;
            } else {
                if (!\is_array($result[$key])) {
                    $result[$key] = [$result[$key]];
                }
                $result[$key][] = $value;
            }
        }
        return $result;
    }
    /**
     * Build a query string from an array of key value pairs.
     *
     * This function can use the return value of `parse()` to build a query
     * string. This function does not modify the provided keys when an array is
     * encountered (like `http_build_query()` would).
     *
     * @param array     $params   Query string parameters.
     * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
     *                            to encode using RFC3986, or PHP_QUERY_RFC1738
     *                            to encode using RFC1738.
     *
     * @return string
     */
    public static function build(array $params, $encoding = \PHP_QUERY_RFC3986)
    {
        if (!$params) {
            return '';
        }
        if ($encoding === \false) {
            $encoder = function ($str) {
                return $str;
            };
        } elseif ($encoding === \PHP_QUERY_RFC3986) {
            $encoder = 'rawurlencode';
        } elseif ($encoding === \PHP_QUERY_RFC1738) {
            $encoder = 'urlencode';
        } else {
            throw new \InvalidArgumentException('Invalid type');
        }
        $qs = '';
        foreach ($params as $k => $v) {
            $k = $encoder($k);
            if (!\is_array($v)) {
                $qs .= $k;
                if ($v !== null) {
                    $qs .= '=' . $encoder($v);
                }
                $qs .= '&';
            } else {
                foreach ($v as $vv) {
                    $qs .= $k;
                    if ($vv !== null) {
                        $qs .= '=' . $encoder($vv);
                    }
                    $qs .= '&';
                }
            }
        }
        return $qs ? (string) \substr($qs, 0, -1) : '';
    }
}
crosstraining/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/psr7/src/Query.php000064400000006671151142506120031744 0ustar00home/xbodynamge<?php

namespace YoastSEO_Vendor\GuzzleHttp\Psr7;

final class Query
{
    /**
     * Parse a query string into an associative array.
     *
     * If multiple values are found for the same key, the value of that key
     * value pair will become an array. This function does not parse nested
     * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
     * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
     *
     * @param string   $str         Query string to parse
     * @param int|bool $urlEncoding How the query string is encoded
     *
     * @return array
     */
    public static function parse($str, $urlEncoding = \true)
    {
        $result = [];
        if ($str === '') {
            return $result;
        }
        if ($urlEncoding === \true) {
            $decoder = function ($value) {
                return \rawurldecode(\str_replace('+', ' ', $value));
            };
        } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
            $decoder = 'rawurldecode';
        } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
            $decoder = 'urldecode';
        } else {
            $decoder = function ($str) {
                return $str;
            };
        }
        foreach (\explode('&', $str) as $kvp) {
            $parts = \explode('=', $kvp, 2);
            $key = $decoder($parts[0]);
            $value = isset($parts[1]) ? $decoder($parts[1]) : null;
            if (!isset($result[$key])) {
                $result[$key] = $value;
            } else {
                if (!\is_array($result[$key])) {
                    $result[$key] = [$result[$key]];
                }
                $result[$key][] = $value;
            }
        }
        return $result;
    }
    /**
     * Build a query string from an array of key value pairs.
     *
     * This function can use the return value of `parse()` to build a query
     * string. This function does not modify the provided keys when an array is
     * encountered (like `http_build_query()` would).
     *
     * @param array     $params   Query string parameters.
     * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
     *                            to encode using RFC3986, or PHP_QUERY_RFC1738
     *                            to encode using RFC1738.
     *
     * @return string
     */
    public static function build(array $params, $encoding = \PHP_QUERY_RFC3986)
    {
        if (!$params) {
            return '';
        }
        if ($encoding === \false) {
            $encoder = function ($str) {
                return $str;
            };
        } elseif ($encoding === \PHP_QUERY_RFC3986) {
            $encoder = 'rawurlencode';
        } elseif ($encoding === \PHP_QUERY_RFC1738) {
            $encoder = 'urlencode';
        } else {
            throw new \InvalidArgumentException('Invalid type');
        }
        $qs = '';
        foreach ($params as $k => $v) {
            $k = $encoder($k);
            if (!\is_array($v)) {
                $qs .= $k;
                if ($v !== null) {
                    $qs .= '=' . $encoder($v);
                }
                $qs .= '&';
            } else {
                foreach ($v as $vv) {
                    $qs .= $k;
                    if ($vv !== null) {
                        $qs .= '=' . $encoder($vv);
                    }
                    $qs .= '&';
                }
            }
        }
        return $qs ? (string) \substr($qs, 0, -1) : '';
    }
}
home/xbodynamge/namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Html/Query.php000064400000014575151144445400027207 0ustar00<?php
namespace AIOSEO\Plugin\Common\Sitemap\Html;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Handles all queries for the HTML sitemap.
 *
 * @since 4.1.3
 */
class Query {
	/**
	 * Returns all eligible sitemap entries for a given post type.
	 *
	 * @since 4.1.3
	 *
	 * @param  string $postType   The post type.
	 * @param  array  $attributes The attributes.
	 * @return array              The post objects.
	 */
	public function posts( $postType, $attributes ) {
		$fields  = '`ID`, `post_title`,';
		$fields .= '`post_parent`, `post_date_gmt`, `post_modified_gmt`';

		$orderBy = '';
		switch ( $attributes['order_by'] ) {
			case 'last_updated':
				$orderBy = 'post_modified_gmt';
				break;
			case 'alphabetical':
				$orderBy = 'post_title';
				break;
			case 'id':
				$orderBy = 'ID';
				break;
			case 'publish_date':
			default:
				$orderBy = 'post_date_gmt';
				break;
		}

		switch ( strtolower( $attributes['order'] ) ) {
			case 'desc':
				$orderBy .= ' DESC';
				break;
			default:
				$orderBy .= ' ASC';
		}

		$query = aioseo()->core->db
			->start( 'posts' )
			->select( $fields )
			->where( 'post_status', 'publish' )
			->where( 'post_type', $postType );

		$excludedPosts = $this->getExcludedObjects( $attributes );
		if ( $excludedPosts ) {
			$query->whereRaw( "( `ID` NOT IN ( $excludedPosts ) )" );
		}

		$posts = $query->orderBy( $orderBy )
			->run()
			->result();

		foreach ( $posts as $post ) {
			$post->ID = (int) $post->ID;
		}

		return $posts;
	}

	/**
	 * Returns all eligble sitemap entries for a given taxonomy.
	 *
	 * @since 4.1.3
	 *
	 * @param  string $taxonomy   The taxonomy name.
	 * @param  array  $attributes The attributes.
	 * @return array              The term objects.
	 */
	public function terms( $taxonomy, $attributes = [] ) {
		$fields                 = 't.term_id, t.name, tt.parent';
		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
		$termTaxonomyTable      = aioseo()->core->db->db->prefix . 'term_taxonomy';

		$orderBy = '';
		switch ( $attributes['order_by'] ) {
			case 'alphabetical':
				$orderBy = 't.name';
				break;
			// We can only sort by date after getting the terms.
			case 'id':
			case 'publish_date':
			case 'last_updated':
			default:
				$orderBy = 't.term_id';
				break;
		}

		switch ( strtolower( $attributes['order'] ) ) {
			case 'desc':
				$orderBy .= ' DESC';
				break;
			default:
				$orderBy .= ' ASC';
		}

		$query = aioseo()->core->db
			->start( 'terms as t' )
			->select( $fields )
			->join( 'term_taxonomy as tt', 't.term_id = tt.term_id' )
			->whereRaw( "
			( `t`.`term_id` IN
				(
					SELECT `tt`.`term_id`
					FROM `$termTaxonomyTable` as tt
					WHERE `tt`.`taxonomy` = '$taxonomy'
					AND `tt`.`count` > 0
				)
			)" );

		$excludedTerms = $this->getExcludedObjects( $attributes, false );
		if ( $excludedTerms ) {
			$query->whereRaw("
				( `t`.`term_id` NOT IN
					(
						SELECT `tr`.`term_taxonomy_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		$terms = $query->orderBy( $orderBy )
			->run()
			->result();

		foreach ( $terms as $term ) {
			$term->term_id  = (int) $term->term_id;
			$term->taxonomy = $taxonomy;
		}

		$shouldSort = false;
		if ( 'last_updated' === $attributes['order_by'] ) {
			$shouldSort = true;
			foreach ( $terms as $term ) {
				$term->timestamp = strtotime( aioseo()->sitemap->content->getTermLastModified( $term->term_id ) );
			}
		}

		if ( 'publish_date' === $attributes['order_by'] ) {
			$shouldSort = true;
			foreach ( $terms as $term ) {
				$term->timestamp = strtotime( $this->getTermPublishDate( $term->term_id ) );
			}
		}

		if ( $shouldSort ) {
			if ( 'asc' === strtolower( $attributes['order'] ) ) {
				usort( $terms, function( $term1, $term2 ) {
					return $term1->timestamp > $term2->timestamp ? 1 : 0;
				} );
			} else {
				usort( $terms, function( $term1, $term2 ) {
					return $term1->timestamp < $term2->timestamp ? 1 : 0;
				} );
			}
		}

		return $terms;
	}

	/**
	 * Returns a list of date archives that can be included.
	 *
	 * @since 4.1.3
	 *
	 * @return array The date archives.
	 */
	public function archives() {
		$result = aioseo()->core->db
			->start( 'posts', false, 'SELECT DISTINCT' )
			->select( 'YEAR(post_date) AS year, MONTH(post_date) AS month' )
			->where( 'post_type', 'post' )
			->where( 'post_status', 'publish' )
			->whereRaw( "post_password=''" )
			->orderBy( 'year DESC' )
			->orderBy( 'month DESC' )
			->run()
			->result();

		$dates = [];
		foreach ( $result as $date ) {
			$dates[ $date->year ][ $date->month ] = 1;
		}

		return $dates;
	}

	/**
	 * Returns the publish date for a given term.
	 * This is the publish date of the oldest post that is assigned to the term.
	 *
	 * @since 4.1.3
	 *
	 * @param  int $termId The term ID.
	 * @return int         The publish date timestamp.
	 */
	public function getTermPublishDate( $termId ) {
		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';

		$post = aioseo()->core->db
			->start( 'posts as p' )
			->select( 'MIN(`p`.`post_date_gmt`) as publish_date' )
			->whereRaw( "
			( `p`.`ID` IN
				(
					SELECT `tr`.`object_id`
					FROM `$termRelationshipsTable` as tr
					WHERE `tr`.`term_taxonomy_id` = '$termId'
				)
			)" )
			->run()
			->result();

		return ! empty( $post[0]->publish_date ) ? strtotime( $post[0]->publish_date ) : 0;
	}

	/**
	 * Returns a comma-separated string of excluded object IDs.
	 *
	 * @since 4.1.3
	 *
	 * @param  array   $attributes The attributes.
	 * @param  boolean $posts      Whether the objects are posts.
	 * @return string              The excluded object IDs.
	 */
	private function getExcludedObjects( $attributes, $posts = true ) {
		$excludedObjects = $posts
			? aioseo()->sitemap->helpers->excludedPosts()
			: aioseo()->sitemap->helpers->excludedTerms();
		$key             = $posts ? 'excluded_posts' : 'excluded_terms';

		if ( ! empty( $attributes[ $key ] ) ) {
			$ids = explode( ',', $excludedObjects );

			$extraIds = [];
			if ( is_array( $attributes[ $key ] ) ) {
				$extraIds = $attributes[ $key ];
			}
			if ( is_string( $attributes[ $key ] ) ) {
				$extraIds = array_map( 'trim', explode( ',', $attributes[ $key ] ) );
			}

			$ids = array_filter( array_merge( $ids, $extraIds ), 'is_numeric' );

			$excludedObjects = esc_sql( implode( ', ', $ids ) );
		}

		return $excludedObjects;
	}
}xbodynamge/namtation/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/psr7/src/Query.php000064400000006671151144506310031054 0ustar00home<?php

namespace YoastSEO_Vendor\GuzzleHttp\Psr7;

final class Query
{
    /**
     * Parse a query string into an associative array.
     *
     * If multiple values are found for the same key, the value of that key
     * value pair will become an array. This function does not parse nested
     * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
     * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
     *
     * @param string   $str         Query string to parse
     * @param int|bool $urlEncoding How the query string is encoded
     *
     * @return array
     */
    public static function parse($str, $urlEncoding = \true)
    {
        $result = [];
        if ($str === '') {
            return $result;
        }
        if ($urlEncoding === \true) {
            $decoder = function ($value) {
                return \rawurldecode(\str_replace('+', ' ', $value));
            };
        } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
            $decoder = 'rawurldecode';
        } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
            $decoder = 'urldecode';
        } else {
            $decoder = function ($str) {
                return $str;
            };
        }
        foreach (\explode('&', $str) as $kvp) {
            $parts = \explode('=', $kvp, 2);
            $key = $decoder($parts[0]);
            $value = isset($parts[1]) ? $decoder($parts[1]) : null;
            if (!isset($result[$key])) {
                $result[$key] = $value;
            } else {
                if (!\is_array($result[$key])) {
                    $result[$key] = [$result[$key]];
                }
                $result[$key][] = $value;
            }
        }
        return $result;
    }
    /**
     * Build a query string from an array of key value pairs.
     *
     * This function can use the return value of `parse()` to build a query
     * string. This function does not modify the provided keys when an array is
     * encountered (like `http_build_query()` would).
     *
     * @param array     $params   Query string parameters.
     * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
     *                            to encode using RFC3986, or PHP_QUERY_RFC1738
     *                            to encode using RFC1738.
     *
     * @return string
     */
    public static function build(array $params, $encoding = \PHP_QUERY_RFC3986)
    {
        if (!$params) {
            return '';
        }
        if ($encoding === \false) {
            $encoder = function ($str) {
                return $str;
            };
        } elseif ($encoding === \PHP_QUERY_RFC3986) {
            $encoder = 'rawurlencode';
        } elseif ($encoding === \PHP_QUERY_RFC1738) {
            $encoder = 'urlencode';
        } else {
            throw new \InvalidArgumentException('Invalid type');
        }
        $qs = '';
        foreach ($params as $k => $v) {
            $k = $encoder($k);
            if (!\is_array($v)) {
                $qs .= $k;
                if ($v !== null) {
                    $qs .= '=' . $encoder($v);
                }
                $qs .= '&';
            } else {
                foreach ($v as $vv) {
                    $qs .= $k;
                    if ($vv !== null) {
                        $qs .= '=' . $encoder($vv);
                    }
                    $qs .= '&';
                }
            }
        }
        return $qs ? (string) \substr($qs, 0, -1) : '';
    }
}
home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Query.php000064400000027332151146132550025063 0ustar00<?php
namespace AIOSEO\Plugin\Common\Sitemap;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AIOSEO\Plugin\Common\Utils as CommonUtils;

/**
 * Handles all complex queries for the sitemap.
 *
 * @since 4.0.0
 */
class Query {
	/**
	 * Returns all eligble sitemap entries for a given post type.
	 *
	 * @since 4.0.0
	 *
	 * @param  mixed $postTypes      The post type(s). Either a singular string or an array of strings.
	 * @param  array $additionalArgs Any additional arguments for the post query.
	 * @return array|int             The post objects or the post count.
	 */
	public function posts( $postTypes, $additionalArgs = [] ) {
		$includedPostTypes = $postTypes;
		$postTypesArray    = ! is_array( $postTypes ) ? [ $postTypes ] : $postTypes;
		if ( is_array( $postTypes ) ) {
			$includedPostTypes = implode( "', '", $postTypes );
		}

		if (
			empty( $includedPostTypes ) ||
			( 'attachment' === $includedPostTypes && 'disabled' !== aioseo()->dynamicOptions->searchAppearance->postTypes->attachment->redirectAttachmentUrls )
		) {
			return [];
		}

		// Set defaults.
		$maxAge = '';
		$fields = implode( ', ', [
			'p.ID',
			'p.post_excerpt',
			'p.post_type',
			'p.post_password',
			'p.post_parent',
			'p.post_date_gmt',
			'p.post_modified_gmt',
			'ap.priority',
			'ap.frequency'
		] );

		if ( in_array( aioseo()->sitemap->type, [ 'html', 'rss' ], true ) ) {
			$fields .= ', p.post_title';
		}

		if ( 'general' !== aioseo()->sitemap->type || ! aioseo()->sitemap->helpers->excludeImages() ) {
			$fields .= ', ap.images';
		}

		// Order by highest priority first (highest priority at the top),
		// then by post modified date (most recently updated at the top).
		$orderBy = 'ap.priority DESC, p.post_modified_gmt DESC';

		// Override defaults if passed as additional arg.
		foreach ( $additionalArgs as $name => $value ) {
			// Attachments need to be fetched with all their fields because we need to get their post parent further down the line.
			$$name = esc_sql( $value );
			if ( 'root' === $name && $value && 'attachment' !== $includedPostTypes ) {
				$fields = 'p.ID, p.post_type';
			}
			if ( 'count' === $name && $value ) {
				$fields = 'count(p.ID) as total';
			}
		}

		$query = aioseo()->core->db
			->start( aioseo()->core->db->db->posts . ' as p', true )
			->select( $fields )
			->leftJoin( 'aioseo_posts as ap', 'ap.post_id = p.ID' )
			->where( 'p.post_status', 'attachment' === $includedPostTypes ? 'inherit' : 'publish' )
			->whereRaw( "p.post_type IN ( '$includedPostTypes' )" );

		$homePageId = (int) get_option( 'page_on_front' );

		if ( ! is_array( $postTypes ) ) {
			if ( ! aioseo()->helpers->isPostTypeNoindexed( $includedPostTypes ) ) {
				$query->whereRaw( "( `ap`.`robots_noindex` IS NULL OR `ap`.`robots_default` = 1 OR `ap`.`robots_noindex` = 0 OR post_id = $homePageId )" );
			} else {
				$query->whereRaw( "( `ap`.`robots_default` = 0 AND `ap`.`robots_noindex` = 0 OR post_id = $homePageId )" );
			}
		} else {
			$robotsMetaSql = [];
			foreach ( $postTypes as $postType ) {
				if ( ! aioseo()->helpers->isPostTypeNoindexed( $postType ) ) {
					$robotsMetaSql[] = "( `p`.`post_type` = '$postType' AND ( `ap`.`robots_noindex` IS NULL OR `ap`.`robots_default` = 1 OR `ap`.`robots_noindex` = 0 OR post_id = $homePageId ) )";
				} else {
					$robotsMetaSql[] = "( `p`.`post_type` = '$postType' AND ( `ap`.`robots_default` = 0 AND `ap`.`robots_noindex` = 0 OR post_id = $homePageId ) )";
				}
			}
			$query->whereRaw( '( ' . implode( ' OR ', $robotsMetaSql ) . ' )' );
		}

		$excludedPosts = aioseo()->sitemap->helpers->excludedPosts();

		if ( $excludedPosts ) {
			$query->whereRaw( "( `p`.`ID` NOT IN ( $excludedPosts ) OR post_id = $homePageId )" );
		}

		// Exclude posts assigned to excluded terms.
		$excludedTerms = aioseo()->sitemap->helpers->excludedTerms();
		if ( $excludedTerms ) {
			$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
			$query->whereRaw("
				( `p`.`ID` NOT IN
					(
						SELECT `tr`.`object_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		if ( $maxAge ) {
			$query->whereRaw( "( `p`.`post_date_gmt` >= '$maxAge' )" );
		}

		if (
			'rss' === aioseo()->sitemap->type ||
			(
				aioseo()->sitemap->indexes &&
				empty( $additionalArgs['root'] ) &&
				empty( $additionalArgs['count'] )
			)
		) {
			$query->limit( aioseo()->sitemap->linksPerIndex, aioseo()->sitemap->offset );
		}

		$isStaticHomepage = 'page' === get_option( 'show_on_front' );
		if ( $isStaticHomepage ) {
			$excludedPostIds = array_map( 'intval', explode( ',', $excludedPosts ) );
			$blogPageId      = (int) get_option( 'page_for_posts' );

			if ( in_array( 'page', $postTypesArray, true ) ) {
				// Exclude the blog page from the pages post type.
				if ( $blogPageId ) {
					$query->whereRaw( "`p`.`ID` != $blogPageId" );
				}

				// Custom order by statement to always move the home page to the top.
				if ( $homePageId ) {
					$orderBy = "case when `p`.`ID` = $homePageId then 0 else 1 end, $orderBy";
				}
			}

			// Include the blog page in the posts post type unless manually excluded.
			if (
				$blogPageId &&
				! in_array( $blogPageId, $excludedPostIds, true ) &&
				in_array( 'post', $postTypesArray, true )
			) {
				// We are using a database class hack to get in an OR clause to
				// bypass all the other WHERE statements and just include the
				// blog page ID manually.
				$query->whereRaw( "1=1 OR `p`.`ID` = $blogPageId" );

				// Custom order by statement to always move the blog posts page to the top.
				$orderBy = "case when `p`.`ID` = $blogPageId then 0 else 1 end, $orderBy";
			}
		}

		$query->orderByRaw( $orderBy );
		$query = $this->filterPostQuery( $query, $postTypes );

		// Return the total if we are just counting the posts.
		if ( ! empty( $additionalArgs['count'] ) ) {
			return (int) $query->run( true, 'var' )
				->result();
		}

		$posts = $query->run()
			->result();

		// Convert ID from string to int.
		foreach ( $posts as $post ) {
			$post->ID = (int) $post->ID;
		}

		return $this->filterPosts( $posts );
	}

	/**
	 * Filters the post query.
	 *
	 * @since 4.1.4
	 *
	 * @param  \AIOSEO\Plugin\Common\Utils\Database $query    The query.
	 * @param  string                               $postType The post type.
	 * @return \AIOSEO\Plugin\Common\Utils\Database           The filtered query.
	 */
	private function filterPostQuery( $query, $postType ) {
		switch ( $postType ) {
			case 'product':
				return $this->excludeHiddenProducts( $query );
			default:
				break;
		}

		return $query;
	}

	/**
	 * Adds a condition to the query to exclude hidden WooCommerce products.
	 *
	 * @since 4.1.4
	 *
	 * @param  \AIOSEO\Plugin\Common\Utils\Database $query The query.
	 * @return \AIOSEO\Plugin\Common\Utils\Database        The filtered query.
	 */
	private function excludeHiddenProducts( $query ) {
		if (
			! aioseo()->helpers->isWooCommerceActive() ||
			! apply_filters( 'aioseo_sitemap_woocommerce_exclude_hidden_products', true )
		) {
			return $query;
		}

		static $hiddenProductIds = null;
		if ( null === $hiddenProductIds ) {
			$tempDb         = new CommonUtils\Database();
			$hiddenProducts = $tempDb->start( 'term_relationships as tr' )
				->select( 'tr.object_id' )
				->join( 'term_taxonomy as tt', 'tr.term_taxonomy_id = tt.term_taxonomy_id' )
				->join( 'terms as t', 'tt.term_id = t.term_id' )
				->where( 't.name', 'exclude-from-catalog' )
				->run()
				->result();

			if ( empty( $hiddenProducts ) ) {
				return $query;
			}

			$hiddenProductIds = [];
			foreach ( $hiddenProducts as $hiddenProduct ) {
				$hiddenProductIds[] = (int) $hiddenProduct->object_id;
			}
			$hiddenProductIds = esc_sql( implode( ', ', $hiddenProductIds ) );
		}

		$query->whereRaw( "p.ID NOT IN ( $hiddenProductIds )" );

		return $query;
	}

	/**
	 * Filters the queried posts.
	 *
	 * @since 4.0.0
	 *
	 * @param  array $posts          The posts.
	 * @return array $remainingPosts The remaining posts.
	 */
	public function filterPosts( $posts ) {
		$remainingPosts = [];
		foreach ( $posts as $post ) {
			switch ( $post->post_type ) {
				case 'attachment':
					if ( ! $this->isInvalidAttachment( $post ) ) {
						$remainingPosts[] = $post;
					}
					break;
				default:
					$remainingPosts[] = $post;
					break;
			}
		}

		return $remainingPosts;
	}

	/**
	 * Excludes attachments if their post parent isn't published or parent post type isn't registered anymore.
	 *
	 * @since 4.0.0
	 *
	 * @param  Object  $post The post.
	 * @return boolean       Whether the attachment is invalid.
	 */
	private function isInvalidAttachment( $post ) {
		if ( empty( $post->post_parent ) ) {
			return false;
		}

		$parent = get_post( $post->post_parent );
		if ( ! is_object( $parent ) ) {
			return false;
		}

		if (
			'publish' !== $parent->post_status ||
			! in_array( $parent->post_type, get_post_types(), true ) ||
			$parent->post_password
		) {
			return true;
		}

		return false;
	}

	/**
	 * Returns all eligible sitemap entries for a given taxonomy.
	 *
	 * @since 4.0.0
	 *
	 * @param  string    $taxonomy       The taxonomy.
	 * @param  array     $additionalArgs Any additional arguments for the term query.
	 * @return array|int                 The term objects or the term count.
	 */
	public function terms( $taxonomy, $additionalArgs = [] ) {
		// Set defaults.
		$fields  = 't.term_id';
		$offset  = aioseo()->sitemap->offset;

		// Override defaults if passed as additional arg.
		foreach ( $additionalArgs as $name => $value ) {
			$$name = esc_sql( $value );
			if ( 'root' === $name && $value ) {
				$fields = 't.term_id, tt.count';
			}
			if ( 'count' === $name && $value ) {
				$fields = 'count(t.term_id) as total';
			}
		}

		$termRelationshipsTable = aioseo()->core->db->db->prefix . 'term_relationships';
		$termTaxonomyTable      = aioseo()->core->db->db->prefix . 'term_taxonomy';

		// Include all terms that have assigned posts or whose children have assigned posts.
		$query = aioseo()->core->db
			->start( aioseo()->core->db->db->terms . ' as t', true )
			->select( $fields )
			->leftJoin( 'term_taxonomy as tt', '`tt`.`term_id` = `t`.`term_id`' )
			->whereRaw( "
			( `t`.`term_id` IN
				(
					SELECT `tt`.`term_id`
					FROM `$termTaxonomyTable` as tt
					WHERE `tt`.`taxonomy` = '$taxonomy'
					AND 
						(
							`tt`.`count` > 0 OR
							EXISTS (
								SELECT 1
								FROM `$termTaxonomyTable` as tt2
								WHERE `tt2`.`parent` = `tt`.`term_id` 
								AND `tt2`.`count` > 0
							)
						)
				)
			)" );

		$excludedTerms = aioseo()->sitemap->helpers->excludedTerms();
		if ( $excludedTerms ) {
			$query->whereRaw("
				( `t`.`term_id` NOT IN
					(
						SELECT `tr`.`term_taxonomy_id`
						FROM `$termRelationshipsTable` as tr
						WHERE `tr`.`term_taxonomy_id` IN ( $excludedTerms )
					)
				)" );
		}

		if (
			aioseo()->sitemap->indexes &&
			empty( $additionalArgs['root'] ) &&
			empty( $additionalArgs['count'] )
		) {
			$query->limit( aioseo()->sitemap->linksPerIndex, $offset );
		}

		// Return the total if we are just counting the terms.
		if ( ! empty( $additionalArgs['count'] ) ) {
			return (int) $query->run( true, 'var' )
				->result();
		}

		$terms = $query->orderBy( 't.term_id ASC' )
			->run()
			->result();

		foreach ( $terms as $term ) {
			// Convert ID from string to int.
			$term->term_id = (int) $term->term_id;
			// Add taxonomy name to object manually instead of querying it to prevent redundant join.
			$term->taxonomy = $taxonomy;
		}

		return $terms;
	}

	/**
	 * Wipes all data and forces the plugin to rescan the site for images.
	 *
	 * @since 4.0.13
	 *
	 * @return void
	 */
	public function resetImages() {
		aioseo()->core->db
			->update( 'aioseo_posts' )
			->set(
				[
					'images'          => null,
					'image_scan_date' => null
				]
			)
			->run();
	}
}