+/**
+ * Returns an array of WP_Theme objects based on the arguments.
+ *
+ * Despite advances over get_themes(), this function is quite expensive, and grows
+ * linearly with additional themes. Stick to wp_get_theme() if possible.
+ *
+ * @since 3.4.0
+ *
+ * @param array $args The search arguments. Optional.
+ * - errors mixed True to return themes with errors, false to return themes without errors, null
+ * to return all themes. Defaults to false.
+ * - allowed mixed (Multisite) True to return only allowed themes for a site. False to return only
+ * disallowed themes for a site. 'site' to return only site-allowed themes. 'network'
+ * to return only network-allowed themes. Null to return all themes. Defaults to null.
+ * - blog_id int (Multisite) The blog ID used to calculate which themes are allowed. Defaults to 0,
+ * synonymous for the current blog.
+ * @return Array of WP_Theme objects.
+ */
+function wp_get_themes( $args = array() ) {
+ global $wp_theme_directories;
+
+ $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0 );
+ $args = wp_parse_args( $args, $defaults );
+
+ $theme_directories = search_theme_directories();
+
+ if ( count( $wp_theme_directories ) > 1 ) {
+ // Make sure the current theme wins out, in case search_theme_directories() picks the wrong
+ // one in the case of a conflict. (Normally, last registered theme root wins.)
+ $current_theme = get_stylesheet();
+ if ( isset( $theme_directories[ $current_theme ] ) ) {
+ $root_of_current_theme = get_raw_theme_root( $current_theme );
+ if ( ! in_array( $root_of_current_theme, $wp_theme_directories ) )
+ $root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme;
+ $theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme;
+ }
+ }
+
+ if ( empty( $theme_directories ) )
+ return array();
+
+ if ( is_multisite() && null !== $args['allowed'] ) {
+ $allowed = $args['allowed'];
+ if ( 'network' === $allowed )
+ $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_network() );
+ elseif ( 'site' === $allowed )
+ $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_site( $args['blog_id'] ) );
+ elseif ( $allowed )
+ $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) );
+ else
+ $theme_directories = array_diff_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) );
+ }
+
+ $themes = array();
+ static $_themes = array();
+
+ foreach ( $theme_directories as $theme => $theme_root ) {
+ if ( isset( $_themes[ $theme_root['theme_root'] . '/' . $theme ] ) )
+ $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ];
+ else
+ $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] );
+ }
+
+ if ( null !== $args['errors'] ) {
+ foreach ( $themes as $theme => $wp_theme ) {
+ if ( $wp_theme->errors() != $args['errors'] )
+ unset( $themes[ $theme ] );
+ }
+ }
+
+ return $themes;
+}
+
+/**
+ * Gets a WP_Theme object for a theme.
+ *
+ * @since 3.4.0
+ *
+ * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme.
+ * @param string $theme_root Absolute path of the theme root to look in. Optional. If not specified, get_raw_theme_root()
+ * is used to calculate the theme root for the $stylesheet provided (or current theme).
+ * @return WP_Theme Theme object. Be sure to check the object's exists() method if you need to confirm the theme's existence.
+ */
+function wp_get_theme( $stylesheet = null, $theme_root = null ) {
+ global $wp_theme_directories;
+
+ if ( empty( $stylesheet ) )
+ $stylesheet = get_stylesheet();
+
+ if ( empty( $theme_root ) ) {
+ $theme_root = get_raw_theme_root( $stylesheet );
+ if ( false === $theme_root )
+ $theme_root = WP_CONTENT_DIR . '/themes';
+ elseif ( ! in_array( $theme_root, (array) $wp_theme_directories ) )
+ $theme_root = WP_CONTENT_DIR . $theme_root;
+ }
+
+ return new WP_Theme( $stylesheet, $theme_root );
+}
+
+/**
+ * Whether a child theme is in use.
+ *
+ * @since 3.0.0
+ *
+ * @return bool true if a child theme is in use, false otherwise.
+ **/
+function is_child_theme() {
+ return ( TEMPLATEPATH !== STYLESHEETPATH );
+}
+
+/**
+ * Retrieve name of the current stylesheet.
+ *
+ * The theme name that the administrator has currently set the front end theme
+ * as.
+ *
+ * For all extensive purposes, the template name and the stylesheet name are
+ * going to be the same for most cases.
+ *
+ * @since 1.5.0
+ * @uses apply_filters() Calls 'stylesheet' filter on stylesheet name.
+ *
+ * @return string Stylesheet name.
+ */