$key = preg_replace( '/[^a-z0-9_\-]/', '', $key ); return apply_filters( 'sanitize_key', $key, $raw_key ); } /** * Sanitizes title or use fallback title. * * Specifically, HTML and PHP tags are stripped. Further actions can be added * via the plugin API. If $title is empty and $fallback_title is set, the latter * will be used. * * @since 1.0.0 * * @param string $title The string to be sanitized. * @param string $fallback_title Optional. A title to use if $title is empty. * @param string $context Optional. The operation for which the string is sanitized * @return string The sanitized string. */ function sanitize_title($title, $fallback_title = '', $context = 'save') { $raw_title = $title; if ( 'save' == $context ) $title = remove_accents($title); $title = apply_filters('sanitize_title', $title, $raw_title, $context); rray[$key]) ) $array[$key] = ''; } $array_keys = array('category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and'); foreach ( $array_keys as $key ) { if ( !isset($array[$key]) ) $array[$key] = array(); } return $array; } /** * Parse a query string and set query type booleans. * * @since 1.5.0 * @access public * * @param string|array $query Optional query. */ function parse_query( $query = '' ) { if ( ! empty( $query ) ) { $this->init(); $this->query = $this->query_vars = wp_parse_args( $query ); } elseif ( ! isset( $this->query ) ) { $this->query = $this->query_vars; } $this->query_vars = $this->fill_query_vars($this->query_vars); $qv = &$this->query_vars; $this->query_vars_changed = true; if ( ! empty($qv['robots']) ) $this->is_robots = true; $qv['p'] = absint($qv['p']); $qv['page_id'] = absint($qv['page_id']); $qv['year'] = absint($qv['year']); $qv['monthnum'] = absint($qv['monthnum']); $qv['day'] = absint($qv['day']); $qv['w'] = absint($qv['w']); $qv['m'] = absint($qv['m']); $qv['paged'] = absint($qv['paged']); $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers $qv['pagename'] = trim( $qv['pagename'] ); $qv['name'] = trim( $qv['name'] ); if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']); if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']); if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']); // Compat. Map subpost to attachment. if ( '' != $qv['subpost'] ) $qv['attachment'] = $qv['subpost']; if ( '' != $qv['subpost_id'] ) $qv['attachment_id'] = $qv['subpost_id']; $qv['attachment_id'] = absint($qv['attachment_id']); if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) { $this->is_single = true; $this->is_attachment = true; } elseif ( '' != $qv['name'] ) { $this->is_single = true; } elseif ( $qv['p'] ) { $this->is_single = true; } elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) { // If year, month, day, hour, minute, and second are set, a single // post is being queried. $this->is_single = true; } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) { $this->is_page = true; $this->is_single = false; } else { // Look for archive queries. Dates, categories, authors, search, post type archives. if ( !empty($qv['s']) ) { $this->is_search = true; } if ( '' !== $qv['second'] ) { $this->is_time = true; $this->is_date = true; } if ( '' !== $qv['minute'] ) { $this->is_time = true; $this->is_date = true; } if ( '' !== $qv['hour'] ) { $this->is_time = true; $this->is_date = true; } if ( $qv['day'] ) { if ( ! $this->is_date ) { $this->is_day = true; $this->is_date = true; } } if ( $qv['monthnum'] ) { if ( ! $this->is_date ) { $this->is_month = true; $this->is_date = true; } } if ( $qv['year'] ) { if ( ! $this->is_date ) { $this->is_year = true; $this->is_date = true; } } if ( $qv['m'] ) { $this->is_date = true; if ( strlen($qv['m']) > 9 ) { $this->is_time = true; } else if ( strlen($qv['m']) > 7 ) { $this->is_day = true; } else if ( strlen($qv['m']) > 5 ) { $this->is_month = true; } else { $this->is_year = true; } } if ( '' != $qv['w'] ) { $this->is_date = true; } $this->query_vars_hash = false; $this->parse_tax_query( $qv ); foreach ( $this->tax_query->queries as $tax_query ) { if ( 'NOT IN' != $tax_query['operator'] ) { switch ( $tax_query['taxonomy'] ) { case 'category': $this->is_category = true; break; case 'post_tag': $this->is_tag = true; break; default: $this->is_tax = true; } } } unset( $tax_query ); if ( empty($qv['author']) || ($qv['author'] == '0') ) { $this->is_author = false; } else { $this->is_author = true; } if ( '' != $qv['author_name'] ) $this->is_author = true; if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) { $post_type_obj = get_post_type_object( $qv['post_type'] ); if ( ! empty( $post_type_obj->has_archive ) ) $this->is_post_type_archive = true; } if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax ) $this->is_archive = true; } if ( '' != $qv['feed'] ) $this->is_feed = true; if ( '' != $qv['tb'] ) $this->is_trackback = true; if ( '' != $qv['paged'] && ( intval($qv['paged']) > 1 ) ) $this->is_paged = true; if ( '' != $qv['comments_popup'] ) $this->is_comments_popup = true; // if we're previewing inside the write screen if ( '' != $qv['preview'lter); return $p; } /** * Retrieves a page given its path. * * @since 2.1.0 * @uses $wpdb * * @param string $page_path Page path * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. * @param string $post_type Optional. Post type. Default page. * @return mixed Null when complete. */ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { global $wpdb; $page_path = rawurlencode(urldecode($page_path)); $page_path = str_replace('%2F', '/', $page_path); $page_path = str_replace('%20', ' ', $page_path); $parts = explode( '/', trim( $page_path, '/' ) ); $parts = array_map( 'esc_sql', $parts ); $parts = array_map( 'sanitize_title_for_query', $parts ); $in_string = "'". implode( "','", $parts ) . "'"; $post_type_sql = $post_type; $wpdb->escape_by_ref( $post_type_sql ); $pages = $wpdb->get_results( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name IN ($in_string) AND (post_type = '$post_type_sql' OR post_type = 'attachment')", OBJECT_K ); $revparts = array_reverse( $parts ); $foundid = 0; foreach ( (array) $pages as $page ) { if ( $page->post_name == $revparts[0] ) { $count = 0; $p = $page; while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) { $count++; $parent = $pages[ $p->post_parent ]; if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) break; $p = $parent; } if ( $p->post_parent == 0 && $count+1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) { $foundid = $page->ID; break; } } } if ( $foundid ) return get_page( $foundid, $output ); return null; } /** * Retrieve a page given its title. * * @since 2.1.0 * @uses $wpdb * * @param string $page_title Page title * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. * @param string $post_type Optional. Post type. Default page. * @return mixed */ function get_page_by_title($page_title, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $page_title, $post_type ) ); if ( $page ) return get_page($page, $output); return null; } /** * Retrieve child pages from list of pages matching page ID. * * Matches against the pages parameter against the page ID. Also matches all * children for the same to retrieve all children of a page. Does not make any * SQL queries to get the children. * * @since 1.5.1 * * @param int $page_id Page ID. * @param array $pages List of pages' objects. * @return array */ function &get_page_children($page_id, $pages) { $page_list = array(); foreach ( (array) $pages as $page ) { if ( $page->post_parent == $page_id ) { $page_list[] = $page; if ( $children = get_page_children($page->ID, $pages) ) $page_list = array_merge($page_list, $children); } } return $page_list; } /** * Order the pages with children under parents in a flat list. * * It uses auxiliary structure to hold parent-children relationships and * runs in O(N) complexity * * @since 2.0.0 * * @param array $pages Posts array. * @param int $page_id Parent page ID. * @return array A list arranged by hierarchy. Children immediately follow their parents. */ function &get_page_hierarchy( &$pages, $page_id = 0 ) { if ( empty( $pages ) ) { $result = array(); return $result; } $children = array(); foreach ( (array) $pages as $p ) { $parent_id = intval( $p->post_parent ); $children[ $parent_id ][] = $p; } $result = array(); _page_traverse_name( $page_id, $children, $result ); return $result; } /** * function to traverse and return all the nested children post names of a root page. * $children contains parent-children relations * * @since 2.9.0 */ function _page_traverse_name( $page_id, &$children, &$result ){ if ( isset( $children[ $page_id ] ) ){ foreach( (array)$children[ $page_id ] as $child ) { $result[ $child->ID ] = $child->post_name; _page_traverse_name( $child->ID, $children, $result ); } } } /** * Builds URI for a page. * * Sub pages will be in the "directory" under the parent page post name. * * @since 1.5.0 * * @param mixed $page Page object or page ID. * @return string Page URI. */ function get_page_uri($page) { if ( ! is_object($page) ) $page = get_page($page); $uri = $page->post_name; // A page cannot be it's own parent. if ( $page->post_parent == $page->ID ) return $uri; while ($page->post_parent != 0) { $page = get_page($page->post_parent); $uri = $page->post_name . "/" . $uri; } return $uri; } /** * Retrieve a list of pages. * * The defaults that can be overridden are the following: 'child_of', * 'sort_order', 'sort_column', 'post_title', 'hierarchical', 'exclude', * 'include', 'meta_key', 'meta_value','authors', 'number', and 'offset'. * * @since 1.5.0 * @uses $wpdb * * @param mixed $args Optional. Array or string of options that overrides defaults. * @return array List of pages matching defaults or $args */ function &get_pages($args = '') { global $wpdb; $defaults = array( 'child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', ); $r = wp_parse_args( $args, $defaults ); extract( $r, EXTR_SKIP ); $number = (int) $number; $offset = (int) $offset; // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) ); if ( !in_array( $post_type, $hierarchical_post_types ) ) return false; // Make sure we have a valid post status if ( !is_array( $post_status ) ) $post_status = explode( ',', $post_status ); if ( array_diff( $post_status, get_post_stati() ) ) return false; $cache = array(); $key = md5( serialize( compact(array_keys($defaults)) ) ); if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) { if ( is_array($cache) && isset( $cache[ $key ] ) ) { $pages = apply_filters('get_pages', $cache[ $key ], $r ); return $pages; } } if ( !is_array($cache) ) $cache = array(); $inclusions = ''; if ( !empty($include) ) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = wp_parse_id_list( $include ); if ( ! empty( $incpages ) ) { foreach ( $incpages as $incpage ) { if (empty($inclusions)) $inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage); else $inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage); } } } if (!empty($inclusions)) $inclusions .= ')'; $exclusions = ''; if ( !empty($exclude) ) { $expages = wp_parse_id_list( $exclude ); if ( ! empty( $expages ) ) { foreach ( $expages as $expage ) { if (empty($exclusions)) $exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage); else $exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage); } } } if (!empty($exclusions)) $exclusions .= ')'; $author_query = ''; if (!empty($authors)) { $post_authors = preg_split('/[\s,]+/',$authors); if ( ! empty( $post_authors ) ) { foreach ( $post_authors as $post_author ) { //Do we have an author id or an author login? if ( 0 == intval($post_author) ) { $post_author = get_user_by('login', $post_author); if ( empty($post_author) ) continue; if ( empty($post_author->ID) ) continue; $post_author = $post_author->ID; } if ( '' == $author_query ) $autho