/** * Prevent switching to Twenty Thirteen on old versions of WordPress. Switches * to the previously activated theme or the default theme. * * @since Twenty Thirteen 1.0 * * @param string $theme_name The theme name. * @param WP_Theme $theme The theme object. * @return void */ function twentythirteen_switch_theme($theme_name, $theme) { if ('twentythirteen' != $theme->get_template()) { switch_theme($theme->get_template(), $theme->get_stylesheet()); } elseif ('twentythirteen' != WP_DEFAULT_THEME) { switch_theme(WP_DEFAULT_THEME); } unset($_GET['activated']); add_action('admin_notices', 'twentythirteen_upgrade_notice'); }
function prepare_items() { $themes = wp_get_themes(array('allowed' => true)); if (!empty($_REQUEST['s'])) { $this->search_terms = array_unique(array_filter(array_map('trim', explode(',', strtolower(wp_unslash($_REQUEST['s'])))))); } if (!empty($_REQUEST['features'])) { $this->features = $_REQUEST['features']; } if ($this->search_terms || $this->features) { foreach ($themes as $key => $theme) { if (!$this->search_theme($theme)) { unset($themes[$key]); } } } unset($themes[get_option('stylesheet')]); WP_Theme::sort_by_name($themes); $per_page = 36; $page = $this->get_pagenum(); $start = ($page - 1) * $per_page; $this->items = array_slice($themes, $start, $per_page, true); $this->set_pagination_args(array('total_items' => count($themes), 'per_page' => $per_page, 'infinite_scroll' => true)); }
/** * @deprecated 3.4.0 * @see WP_Theme::get_allowed_on_site() */ function wpmu_get_blog_allowedthemes($blog_id = 0) { _deprecated_function(__FUNCTION__, '3.4', 'WP_Theme::get_allowed_on_site()'); return array_map('intval', WP_Theme::get_allowed_on_site($blog_id)); }
/** * @param WP_Theme $theme * @return bool */ public function search_theme($theme) { // Search the features foreach ($this->features as $word) { if (!in_array($word, $theme->get('Tags'))) { return false; } } // Match all phrases foreach ($this->search_terms as $word) { if (in_array($word, $theme->get('Tags'))) { continue; } foreach (array('Name', 'Description', 'Author', 'AuthorURI') as $header) { // Don't mark up; Do translate. if (false !== stripos(strip_tags($theme->display($header, false, true)), $word)) { continue 2; } } if (false !== stripos($theme->get_stylesheet(), $word)) { continue; } if (false !== stripos($theme->get_template(), $word)) { continue; } return false; } return true; }
/** * Returns the version of the the current theme. * * @return string * The version of the current theme. * * @ingroup helperfunc */ function get_theme_version() { if (class_exists('WP_Theme')) { $theme = new WP_Theme(get_theme_name(), get_theme_root()); return $theme->get('Version'); } else { $theme_data = get_theme_data(get_template_directory() . '/style.css'); return $theme_data['Version']; } }
public static function resolveLanguagesPath(\WP_Theme $theme) { // as taken from wp-includes/class-wp-theme.php:1114 $path = $theme->get_stylesheet_directory(); if ($domainpath = $theme->get('DomainPath')) { $path .= $domainpath; } else { $path .= '/languages'; } return $path; }
protected function get_theme_info_html(WP_Theme $theme) { $name = $theme->display('Name'); $version = $theme->display('Version'); $description = $theme->display('Description'); $desc_title = esc_attr($theme->get('Description')); $author = $theme->display('Author'); $screenshot = $theme->get_screenshot(); $thumbnail_style = $screenshot !== false ? sprintf('style="background-image:url(%s);"', $screenshot) : ''; $theme_url = network_admin_url(add_query_arg('theme', $theme->get_stylesheet(), 'themes.php')); $version_label = __('Version:', 'wtaiu'); $author_label = __('By', 'wtaiu'); $output = <<<OUTPUT <div class="theme-info" title="{$desc_title}"> <a href="{$theme_url}" class="theme-screenshot" {$thumbnail_style}></a> <div class="theme-info-wrap"> <h3 class="theme-info-header" title="{$name}"> <a href="{$theme_url}" class="theme-name">{$name}</a> </h3> <p class="theme-version">{$version_label} {$version}</p> <p class="theme-author">{$author_label} {$author}</p> </div> </div> OUTPUT; return $output; }
protected function outputThemeInfo($theme) { $theme_path = wordpress_path('wp-content/themes/') . $theme; // check if (!file_exists($theme_path)) { throw new \InvalidArgumentException("Theme '{$theme}' is not found."); } $theme_object = new \WP_Theme($theme, dirname($theme_path)); // // MEMO: template_dir と同じ // $this->line("<info>[path]</info> '{$theme_path}'"); $properties_wordpress = ['name', 'title', 'version', 'parent_theme', 'template_dir', 'stylesheet_dir', 'template', 'stylesheet', 'screenshot', 'description', 'author', 'tags', 'theme_root', 'theme_root_uri']; foreach ($properties_wordpress as $property) { $value = $theme_object->{$property}; if (is_array($value)) { $value = '[' . implode(', ', $value) . ']'; } $this->line("<info>[{$property}]</info> {$value}"); } $properties_extra = ['php_namespace' => 'PHP Namespace']; foreach ($properties_extra as $property => $field) { $value = $theme_object->get($field); if (is_array($value)) { $value = '[' . implode(', ', $value) . ']'; } $this->line("<info>[{$property}]</info> {$value}"); } }
/** * Returns field from theme data if cookie is set to valid theme. * * @param string $field_name * @param mixed $default * * @deprecated :2.0 * * @return mixed */ public static function get_theme_field($field_name, $default = false) { if (!empty(self::$theme)) { return self::$theme->get($field_name); } return $default; }
/** * Get the switched theme object. * * @return WP_Theme|bool * @since 0.1 */ public function get_switched_theme() { if (!is_null($this->switched_theme)) { return $this->switched_theme; } $cts = Conditional_Themes_Manager::get_all(); if (is_array($cts) && !empty($cts)) { foreach ($cts as $ct) { if (!is_null($this->original_theme)) { if ($ct->theme === $this->original_theme->get_stylesheet()) { continue; } } if (!empty($ct->condition) && is_callable($ct->condition)) { $ct->condition = call_user_func($ct->condition); $ct->condition = (bool) $ct->condition; } if (is_bool($ct->condition) && $ct->condition) { $theme = wp_get_theme($ct->theme); if ($theme->exists() && $theme->is_allowed()) { $this->switched_theme = $theme; break; } } } } if (empty($this->switched_theme)) { $this->switched_theme = FALSE; } return $this->switched_theme; }
function prepare_items() { global $status, $totals, $page, $orderby, $order, $s; wp_reset_vars(array('orderby', 'order', 's')); $themes = array('all' => apply_filters('all_themes', wp_get_themes()), 'search' => array(), 'enabled' => array(), 'disabled' => array(), 'upgrade' => array(), 'broken' => $this->is_site_themes ? array() : wp_get_themes(array('errors' => true))); if ($this->is_site_themes) { $themes_per_page = $this->get_items_per_page('site_themes_network_per_page'); $allowed_where = 'site'; } else { $themes_per_page = $this->get_items_per_page('themes_network_per_page'); $allowed_where = 'network'; } $maybe_update = current_user_can('update_themes') && !$this->is_site_themes && ($current = get_site_transient('update_themes')); foreach ((array) $themes['all'] as $key => $theme) { if ($this->is_site_themes && $theme->is_allowed('network')) { unset($themes['all'][$key]); continue; } if ($maybe_update && isset($current->response[$key])) { $themes['all'][$key]->update = true; $themes['upgrade'][$key] = $themes['all'][$key]; } $filter = $theme->is_allowed($allowed_where, $this->site_id) ? 'enabled' : 'disabled'; $themes[$filter][$key] = $themes['all'][$key]; } if ($s) { $status = 'search'; $themes['search'] = array_filter(array_merge($themes['all'], $themes['broken']), array(&$this, '_search_callback')); } $totals = array(); foreach ($themes as $type => $list) { $totals[$type] = count($list); } if (empty($themes[$status]) && !in_array($status, array('all', 'search'))) { $status = 'all'; } $this->items = $themes[$status]; WP_Theme::sort_by_name($this->items); $this->has_items = !empty($themes['all']); $total_this_page = $totals[$status]; if ($orderby) { $orderby = ucfirst($orderby); $order = strtoupper($order); if ($orderby == 'Name') { if ('ASC' == $order) { $this->items = array_reverse($this->items); } } else { uasort($this->items, array(&$this, '_order_callback')); } } $start = ($page - 1) * $themes_per_page; if ($total_this_page > $themes_per_page) { $this->items = array_slice($this->items, $start, $themes_per_page, true); } $this->set_pagination_args(array('total_items' => $total_this_page, 'per_page' => $themes_per_page)); }
/** * 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) { // XTEC ************ AFEGIT - Hide reactor at the theme selector // 2014.08.29 @sarjona if ($theme == 'reactor') { break; } //************ FI 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; }
/** * Test the `site_allowed_themes` filter, which filters allowed themes for a site and provides `$blog_id`. */ public function test_wp_theme_get_allowed_with_site_allowed_themes_filter() { $blog_id = 1; $this->default_allowed = WP_Theme::get_allowed($blog_id); add_filter('site_allowed_themes', array($this, 'filter_site_allowed_themes'), 10, 2); $allowed = WP_Theme::get_allowed($blog_id); remove_filter('site_allowed_themes', array($this, 'filter_site_allowed_themes'), 10); $expected = $this->default_allowed + array('site-allowed-theme' => true); $this->assertEquals($expected, $allowed); }
/** * Check for a plugin update. * * @since 1.0 * * @param object $transient * * @return object */ public function check_for_update($transient) { if (empty($transient->checked) || empty($this->key)) { return $transient; } try { $info = $this->get_latest_version($this->key); } catch (Exception $e) { return $transient; } if (!is_wp_error($info) && version_compare($info->version, $this->version, '>')) { $info->upgrade_notice = 'upgrade'; $stylesheet = $this->theme->get_stylesheet(); $transient->response[$stylesheet] = array('new_version' => $info->version, 'package' => $info->package, 'slug' => $stylesheet, 'theme' => $stylesheet, 'url' => add_query_arg('ID', $this->product_id, $this->generate_endpoint_url('changelog'))); if (!empty($info->upgrade_notice)) { $transient->response[$stylesheet]['upgrade_notice'] = $info->upgrade_notice; } } return $transient; }
/** * Do a several Clean Up * * @brief Clean Up */ public function _init() { /* Text Domain */ if ($this->setup->autoload_text_domain) { load_theme_textdomain($this->theme->get('TextDomain'), trailingslashit(TEMPLATEPATH) . $this->theme->get('DomainPath')); } /* Clean up wp_head */ if ($this->setup->cleanup_wp_head) { remove_action('wp_head', 'feed_links_extra', 3); // Category Feeds remove_action('wp_head', 'feed_links', 2); // Post and Comment Feeds remove_action('wp_head', 'rsd_link'); // EditURI link remove_action('wp_head', 'wlwmanifest_link'); // Windows Live Writer remove_action('wp_head', 'index_rel_link'); // index link remove_action('wp_head', 'parent_post_rel_link', 10, 0); // previous link remove_action('wp_head', 'start_post_rel_link', 10, 0); // start link remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); // Links for Adjacent Posts remove_action('wp_head', 'wp_generator'); // WP vers } }
function tc_get_theme_data($theme_file) { if (!class_exists('WP_Theme')) { return get_theme_data($theme_file); } $theme = new WP_Theme(basename(dirname($theme_file)), dirname(dirname($theme_file))); $theme_data = array('Name' => $theme->get('Name'), 'URI' => $theme->display('ThemeURI', true, false), 'Description' => $theme->display('Description', true, false), 'Author' => $theme->display('Author', true, false), 'AuthorURI' => $theme->display('AuthorURI', true, false), 'Version' => $theme->get('Version'), 'Template' => $theme->get('Template'), 'Status' => $theme->get('Status'), 'Tags' => $theme->get('Tags'), 'Title' => $theme->get('Name'), 'AuthorName' => $theme->display('Author', false, false), 'License' => $theme->display('License', false, false), 'License URI' => $theme->display('License URI', false, false), 'Template Version' => $theme->display('Template Version', false, false)); return $theme_data; }
/** * Populate network settings. * * @since 3.0.0 * * @global wpdb $wpdb * @global object $current_site * @global int $wp_db_version * @global WP_Rewrite $wp_rewrite * * @param int $network_id ID of network to populate. * @return bool|WP_Error True on success, or WP_Error on warning (with the install otherwise successful, * so the error code must be checked) or failure. */ function populate_network($network_id = 1, $domain = '', $email = '', $site_name = '', $path = '/', $subdomain_install = false) { global $wpdb, $current_site, $wp_db_version, $wp_rewrite; $errors = new WP_Error(); if ('' == $domain) { $errors->add('empty_domain', __('You must provide a domain name.')); } if ('' == $site_name) { $errors->add('empty_sitename', __('You must provide a name for your network of sites.')); } // Check for network collision. if ($network_id == $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->site} WHERE id = %d", $network_id))) { $errors->add('siteid_exists', __('The network already exists.')); } if (!is_email($email)) { $errors->add('invalid_email', __('You must provide a valid email address.')); } if ($errors->get_error_code()) { return $errors; } // If a user with the provided email does not exist, default to the current user as the new network admin. $site_user = get_user_by('email', $email); if (false === $site_user) { $site_user = wp_get_current_user(); } // Set up site tables. $template = get_option('template'); $stylesheet = get_option('stylesheet'); $allowed_themes = array($stylesheet => true); if ($template != $stylesheet) { $allowed_themes[$template] = true; } if (WP_DEFAULT_THEME != $stylesheet && WP_DEFAULT_THEME != $template) { $allowed_themes[WP_DEFAULT_THEME] = true; } // If WP_DEFAULT_THEME doesn't exist, also whitelist the latest core default theme. if (!wp_get_theme(WP_DEFAULT_THEME)->exists()) { if ($core_default = WP_Theme::get_core_default_theme()) { $allowed_themes[$core_default->get_stylesheet()] = true; } } if (1 == $network_id) { $wpdb->insert($wpdb->site, array('domain' => $domain, 'path' => $path)); $network_id = $wpdb->insert_id; } else { $wpdb->insert($wpdb->site, array('domain' => $domain, 'path' => $path, 'id' => $network_id)); } wp_cache_delete('networks_have_paths', 'site-options'); if (!is_multisite()) { $site_admins = array($site_user->user_login); $users = get_users(array('fields' => array('ID', 'user_login'))); if ($users) { foreach ($users as $user) { if (is_super_admin($user->ID) && !in_array($user->user_login, $site_admins)) { $site_admins[] = $user->user_login; } } } } else { $site_admins = get_site_option('site_admins'); } /* translators: Do not translate USERNAME, SITE_NAME, BLOG_URL, PASSWORD: those are placeholders. */ $welcome_email = __('Howdy USERNAME, Your new SITE_NAME site has been successfully set up at: BLOG_URL You can log in to the administrator account with the following information: Username: USERNAME Password: PASSWORD Log in here: BLOG_URLwp-login.php We hope you enjoy your new site. Thanks! --The Team @ SITE_NAME'); $misc_exts = array('jpg', 'jpeg', 'png', 'gif', 'mov', 'avi', 'mpg', '3gp', '3g2', 'midi', 'mid', 'pdf', 'doc', 'ppt', 'odt', 'pptx', 'docx', 'pps', 'ppsx', 'xls', 'xlsx', 'key'); $audio_exts = wp_get_audio_extensions(); $video_exts = wp_get_video_extensions(); $upload_filetypes = array_unique(array_merge($misc_exts, $audio_exts, $video_exts)); $sitemeta = array('site_name' => $site_name, 'admin_email' => $email, 'admin_user_id' => $site_user->ID, 'registration' => 'none', 'upload_filetypes' => implode(' ', $upload_filetypes), 'blog_upload_space' => 100, 'fileupload_maxk' => 1500, 'site_admins' => $site_admins, 'allowedthemes' => $allowed_themes, 'illegal_names' => array('www', 'web', 'root', 'admin', 'main', 'invite', 'administrator', 'files'), 'wpmu_upgrade_site' => $wp_db_version, 'welcome_email' => $welcome_email, 'first_post' => __('Welcome to %s. This is your first post. Edit or delete it, then start blogging!'), 'siteurl' => get_option('siteurl') . '/', 'add_new_users' => '0', 'upload_space_check_disabled' => is_multisite() ? get_site_option('upload_space_check_disabled') : '1', 'subdomain_install' => intval($subdomain_install), 'global_terms_enabled' => global_terms_enabled() ? '1' : '0', 'ms_files_rewriting' => is_multisite() ? get_site_option('ms_files_rewriting') : '0', 'initial_db_version' => get_option('initial_db_version'), 'active_sitewide_plugins' => array(), 'WPLANG' => get_locale()); if (!$subdomain_install) { $sitemeta['illegal_names'][] = 'blog'; } /** * Filter meta for a network on creation. * * @since 3.7.0 * * @param array $sitemeta Associative array of network meta keys and values to be inserted. * @param int $network_id ID of network to populate. */ $sitemeta = apply_filters('populate_network_meta', $sitemeta, $network_id); $insert = ''; foreach ($sitemeta as $meta_key => $meta_value) { if (is_array($meta_value)) { $meta_value = serialize($meta_value); } if (!empty($insert)) { $insert .= ', '; } $insert .= $wpdb->prepare("( %d, %s, %s)", $network_id, $meta_key, $meta_value); } $wpdb->query("INSERT INTO {$wpdb->sitemeta} ( site_id, meta_key, meta_value ) VALUES " . $insert); /* * When upgrading from single to multisite, assume the current site will * become the main site of the network. When using populate_network() * to create another network in an existing multisite environment, skip * these steps since the main site of the new network has not yet been * created. */ if (!is_multisite()) { $current_site = new stdClass(); $current_site->domain = $domain; $current_site->path = $path; $current_site->site_name = ucfirst($domain); $wpdb->insert($wpdb->blogs, array('site_id' => $network_id, 'blog_id' => 1, 'domain' => $domain, 'path' => $path, 'registered' => current_time('mysql'))); $current_site->blog_id = $blog_id = $wpdb->insert_id; update_user_meta($site_user->ID, 'source_domain', $domain); update_user_meta($site_user->ID, 'primary_blog', $blog_id); if ($subdomain_install) { $wp_rewrite->set_permalink_structure('/%year%/%monthnum%/%day%/%postname%/'); } else { $wp_rewrite->set_permalink_structure('/blog/%year%/%monthnum%/%day%/%postname%/'); } flush_rewrite_rules(); if (!$subdomain_install) { return true; } $vhost_ok = false; $errstr = ''; $hostname = substr(md5(time()), 0, 6) . '.' . $domain; // Very random hostname! $page = wp_remote_get('http://' . $hostname, array('timeout' => 5, 'httpversion' => '1.1')); if (is_wp_error($page)) { $errstr = $page->get_error_message(); } elseif (200 == wp_remote_retrieve_response_code($page)) { $vhost_ok = true; } if (!$vhost_ok) { $msg = '<p><strong>' . __('Warning! Wildcard DNS may not be configured correctly!') . '</strong></p>'; $msg .= '<p>' . sprintf(__('The installer attempted to contact a random hostname (%s) on your domain.'), '<code>' . $hostname . '</code>'); if (!empty($errstr)) { /* translators: %s: error message */ $msg .= ' ' . sprintf(__('This resulted in an error message: %s'), '<code>' . $errstr . '</code>'); } $msg .= '</p>'; $msg .= '<p>' . sprintf(__('To use a subdomain configuration, you must have a wildcard entry in your DNS. This usually means adding a %s hostname record pointing at your web server in your DNS configuration tool.'), '<code>*</code>') . '</p>'; $msg .= '<p>' . __('You can still use your site but any subdomain you create may not be accessible. If you know your DNS is correct, ignore this message.') . '</p>'; return new WP_Error('no_wildcard_dns', $msg); } } return true; }
/** * Prepare themes for JavaScript. * * @since 3.8.0 * * @param array $themes Optional. Array of WP_Theme objects to prepare. * Defaults to all allowed themes. * * @return array An associative array of theme data, sorted by name. */ function wp_prepare_themes_for_js($themes = null) { $current_theme = get_stylesheet(); /** * Filter theme data before it is prepared for JavaScript. * * Passing a non-empty array will result in wp_prepare_themes_for_js() returning * early with that value instead. * * @since 4.2.0 * * @param array $prepared_themes An associative array of theme data. Default empty array. * @param null|array $themes An array of WP_Theme objects to prepare, if any. * @param string $current_theme The current theme slug. */ $prepared_themes = (array) apply_filters('pre_prepare_themes_for_js', array(), $themes, $current_theme); if (!empty($prepared_themes)) { return $prepared_themes; } // Make sure the current theme is listed first. $prepared_themes[$current_theme] = array(); if (null === $themes) { $themes = wp_get_themes(array('allowed' => true)); if (!isset($themes[$current_theme])) { $themes[$current_theme] = wp_get_theme(); } } $updates = array(); if (current_user_can('update_themes')) { $updates_transient = get_site_transient('update_themes'); if (isset($updates_transient->response)) { $updates = $updates_transient->response; } } WP_Theme::sort_by_name($themes); $parents = array(); /** @type WP_Theme $theme */ foreach ($themes as $theme) { $slug = $theme->get_stylesheet(); $encoded_slug = urlencode($slug); $parent = false; if ($theme->parent()) { $parent = $theme->parent()->display('Name'); $parents[$slug] = $theme->parent()->get_stylesheet(); } $prepared_themes[$slug] = array('id' => $slug, 'name' => $theme->display('Name'), 'screenshot' => array($theme->get_screenshot()), 'description' => $theme->display('Description'), 'author' => $theme->display('Author', false, true), 'authorAndUri' => $theme->display('Author'), 'version' => $theme->display('Version'), 'tags' => $theme->display('Tags'), 'parent' => $parent, 'active' => $slug === $current_theme, 'hasUpdate' => isset($updates[$slug]), 'update' => get_theme_update_available($theme), 'actions' => array('activate' => current_user_can('switch_themes') ? wp_nonce_url(admin_url('themes.php?action=activate&stylesheet=' . $encoded_slug), 'switch-theme_' . $slug) : null, 'customize' => current_user_can('edit_theme_options') && current_user_can('customize') ? wp_customize_url($slug) : null, 'preview' => add_query_arg(array('preview' => 1, 'template' => urlencode($theme->get_template()), 'stylesheet' => urlencode($slug), 'preview_iframe' => true, 'TB_iframe' => true), home_url('/')), 'delete' => current_user_can('delete_themes') ? wp_nonce_url(admin_url('themes.php?action=delete&stylesheet=' . $encoded_slug), 'delete-theme_' . $slug) : null)); } // Remove 'delete' action if theme has an active child if (!empty($parents) && array_key_exists($current_theme, $parents)) { unset($prepared_themes[$parents[$current_theme]]['actions']['delete']); } /** * Filter the themes prepared for JavaScript, for themes.php. * * Could be useful for changing the order, which is by name by default. * * @since 3.8.0 * * @param array $prepared_themes Array of themes. */ $prepared_themes = apply_filters('wp_prepare_themes_for_js', $prepared_themes); $prepared_themes = array_values($prepared_themes); return array_filter($prepared_themes); }
/** * Constructor for WP_Theme. * * @global array $wp_theme_directories * * @param string $theme_dir Directory of the theme within the theme_root. * @param string $theme_root Theme root. * @param WP_Error|void $_child If this theme is a parent theme, the child may be passed for validation purposes. */ public function __construct($theme_dir, $theme_root, $_child = null) { global $wp_theme_directories; // Initialize caching on first run. if (!isset(self::$persistently_cache)) { /** This action is documented in wp-includes/theme.php */ self::$persistently_cache = apply_filters('wp_cache_themes_persistently', false, 'WP_Theme'); if (self::$persistently_cache) { wp_cache_add_global_groups('themes'); if (is_int(self::$persistently_cache)) { self::$cache_expiration = self::$persistently_cache; } } else { wp_cache_add_non_persistent_groups('themes'); } } $this->theme_root = $theme_root; $this->stylesheet = $theme_dir; // Correct a situation where the theme is 'some-directory/some-theme' but 'some-directory' was passed in as part of the theme root instead. if (!in_array($theme_root, (array) $wp_theme_directories) && in_array(dirname($theme_root), (array) $wp_theme_directories)) { $this->stylesheet = basename($this->theme_root) . '/' . $this->stylesheet; $this->theme_root = dirname($theme_root); } $this->cache_hash = md5($this->theme_root . '/' . $this->stylesheet); $theme_file = $this->stylesheet . '/style.css'; $cache = $this->cache_get('theme'); if (is_array($cache)) { foreach (array('errors', 'headers', 'template') as $key) { if (isset($cache[$key])) { $this->{$key} = $cache[$key]; } } if ($this->errors) { return; } if (isset($cache['theme_root_template'])) { $theme_root_template = $cache['theme_root_template']; } } elseif (!file_exists($this->theme_root . '/' . $theme_file)) { $this->headers['Name'] = $this->stylesheet; if (!file_exists($this->theme_root . '/' . $this->stylesheet)) { $this->errors = new WP_Error('theme_not_found', sprintf(__('The theme directory "%s" does not exist.'), esc_html($this->stylesheet))); } else { $this->errors = new WP_Error('theme_no_stylesheet', __('Stylesheet is missing.')); } $this->template = $this->stylesheet; $this->cache_add('theme', array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template)); if (!file_exists($this->theme_root)) { // Don't cache this one. $this->errors->add('theme_root_missing', __('ERROR: The themes directory is either empty or doesn’t exist. Please check your installation.')); } return; } elseif (!is_readable($this->theme_root . '/' . $theme_file)) { $this->headers['Name'] = $this->stylesheet; $this->errors = new WP_Error('theme_stylesheet_not_readable', __('Stylesheet is not readable.')); $this->template = $this->stylesheet; $this->cache_add('theme', array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template)); return; } else { $this->headers = get_file_data($this->theme_root . '/' . $theme_file, self::$file_headers, 'theme'); // Default themes always trump their pretenders. // Properly identify default themes that are inside a directory within wp-content/themes. if ($default_theme_slug = array_search($this->headers['Name'], self::$default_themes)) { if (basename($this->stylesheet) != $default_theme_slug) { $this->headers['Name'] .= '/' . $this->stylesheet; } } } // (If template is set from cache [and there are no errors], we know it's good.) if (!$this->template && !($this->template = $this->headers['Template'])) { $this->template = $this->stylesheet; if (!file_exists($this->theme_root . '/' . $this->stylesheet . '/index.php')) { $this->errors = new WP_Error('theme_no_index', __('Template is missing.')); $this->cache_add('theme', array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template)); return; } } // If we got our data from cache, we can assume that 'template' is pointing to the right place. if (!is_array($cache) && $this->template != $this->stylesheet && !file_exists($this->theme_root . '/' . $this->template . '/index.php')) { // If we're in a directory of themes inside /themes, look for the parent nearby. // wp-content/themes/directory-of-themes/* $parent_dir = dirname($this->stylesheet); if ('.' != $parent_dir && file_exists($this->theme_root . '/' . $parent_dir . '/' . $this->template . '/index.php')) { $this->template = $parent_dir . '/' . $this->template; } elseif (($directories = search_theme_directories()) && isset($directories[$this->template])) { // Look for the template in the search_theme_directories() results, in case it is in another theme root. // We don't look into directories of themes, just the theme root. $theme_root_template = $directories[$this->template]['theme_root']; } else { // Parent theme is missing. $this->errors = new WP_Error('theme_no_parent', sprintf(__('The parent theme is missing. Please install the "%s" parent theme.'), esc_html($this->template))); $this->cache_add('theme', array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template)); $this->parent = new WP_Theme($this->template, $this->theme_root, $this); return; } } // Set the parent, if we're a child theme. if ($this->template != $this->stylesheet) { // If we are a parent, then there is a problem. Only two generations allowed! Cancel things out. if ($_child instanceof WP_Theme && $_child->template == $this->stylesheet) { $_child->parent = null; $_child->errors = new WP_Error('theme_parent_invalid', sprintf(__('The "%s" theme is not a valid parent theme.'), esc_html($_child->template))); $_child->cache_add('theme', array('headers' => $_child->headers, 'errors' => $_child->errors, 'stylesheet' => $_child->stylesheet, 'template' => $_child->template)); // The two themes actually reference each other with the Template header. if ($_child->stylesheet == $this->template) { $this->errors = new WP_Error('theme_parent_invalid', sprintf(__('The "%s" theme is not a valid parent theme.'), esc_html($this->template))); $this->cache_add('theme', array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template)); } return; } // Set the parent. Pass the current instance so we can do the crazy checks above and assess errors. $this->parent = new WP_Theme($this->template, isset($theme_root_template) ? $theme_root_template : $this->theme_root, $this); } // We're good. If we didn't retrieve from cache, set it. if (!is_array($cache)) { $cache = array('headers' => $this->headers, 'errors' => $this->errors, 'stylesheet' => $this->stylesheet, 'template' => $this->template); // If the parent theme is in another root, we'll want to cache this. Avoids an entire branch of filesystem calls above. if (isset($theme_root_template)) { $cache['theme_root_template'] = $theme_root_template; } $this->cache_add('theme', $cache); } }
/** * @global string $status * @global int $page * @global string $s * @global array $totals * @param WP_Theme $theme */ public function single_row($theme) { $status = 'all'; $stylesheet = $theme->get_stylesheet(); remove_action("after_theme_row_{$stylesheet}", 'wp_theme_update_row', 10, 2); $theme_key = urlencode($stylesheet); /** * Filter the action links that show up under each theme row. * * @since 5.0.0 * * @param array Array of action links * @param WP_Theme $theme WP_Theme object * @param string $status Status of the theme. */ $actions = apply_filters('mpsum_theme_action_links', array(), $theme, 'all'); $checkbox_id = "checkbox_" . md5($theme->get('Name')); $checkbox = "<input type='checkbox' name='checked[]' value='" . esc_attr($stylesheet) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select', 'stops-core-theme-and-plugin-updates') . " " . $theme->display('Name') . "</label>"; $id = sanitize_html_class($theme->get_stylesheet()); $class = 'active'; $theme_options = MPSUM_Updates_Manager::get_options('themes'); if (false !== ($key = array_search($stylesheet, $theme_options))) { $class = 'inactive'; } echo "<tr id='{$id}' class='{$class}'>"; list($columns, $hidden) = $this->get_column_info(); foreach ($columns as $column_name => $column_display_name) { $style = ''; if (in_array($column_name, $hidden)) { $style = ' style="display:none;"'; } switch ($column_name) { case 'cb': echo "<th scope='row' class='check-column'>{$checkbox}</th>"; break; case 'name': echo "<td class='theme-title'{$style}><strong>" . $theme->display('Name') . "</strong>"; echo $this->row_actions($actions, true); echo "</td>"; break; case 'description': echo "<td class='column-description desc'{$style}>"; if ($theme->errors()) { $pre = $status == 'broken' ? __('Broken Theme:', 'stops-core-theme-and-plugin-updates') . ' ' : ''; echo '<p><strong class="attention">' . $pre . $theme->errors()->get_error_message() . '</strong></p>'; } echo "<div class='theme-description'><p>" . $theme->display('Description') . "</p></div>\n\t\t\t\t\t\t<div class='second theme-version-author-uri'>"; $theme_meta = array(); if ($theme->get('Version')) { $theme_meta[] = sprintf(__('Version %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Version')); } $theme_meta[] = sprintf(__('By %s', 'stops-core-theme-and-plugin-updates'), $theme->display('Author')); if ($theme->get('ThemeURI')) { $theme_meta[] = '<a href="' . $theme->display('ThemeURI') . '" title="' . esc_attr__('Visit theme homepage', 'stops-core-theme-and-plugin-updates') . '">' . __('Visit Theme Site', 'stops-core-theme-and-plugin-updates') . '</a>'; } /** * Filter the array of row meta for each theme in the Multisite themes * list table. * * @since 3.1.0 * * @param array $theme_meta An array of the theme's metadata, * including the version, author, and * theme URI. * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme WP_Theme object. * @param string $status Status of the theme. */ $theme_meta = apply_filters('theme_row_meta', $theme_meta, $stylesheet, $theme, $status); echo implode(' | ', $theme_meta); echo "</div></td>"; break; default: echo "<td class='{$column_name} column-{$column_name}'{$style}>"; /** * Fires inside each custom column of the Multisite themes list table. * * @since 3.1.0 * * @param string $column_name Name of the column. * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme Current WP_Theme object. */ do_action('manage_themes_custom_column', $column_name, $stylesheet, $theme); echo "</td>"; } } echo "</tr>"; if ($this->is_site_themes) { remove_action("after_theme_row_{$stylesheet}", 'wp_theme_update_row'); } /** * Fires after each row in the Multisite themes list table. * * @since 3.1.0 * * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme Current WP_Theme object. * @param string $status Status of the theme. */ do_action('after_theme_row', $stylesheet, $theme, $status); /** * Fires after each specific row in the Multisite themes list table. * * The dynamic portion of the hook name, `$stylesheet`, refers to the * directory name of the theme, most often synonymous with the template * name of the theme. * * @since 3.5.0 * * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme Current WP_Theme object. * @param string $status Status of the theme. */ do_action("after_theme_row_{$stylesheet}", $stylesheet, $theme, $status); }
/** * Disable multiple themes on a network. * * @ticket 30594 */ function test_network_disable_multiple_themes() { if (!is_multisite()) { $this->markTestSkipped('This test requires multisite'); } $current_allowed_themes = get_site_option('allowedthemes'); $allowed_themes = array('existing-4' => true, 'existing-5' => true, 'existing-6' => true); update_site_option('allowedthemes', $allowed_themes); $disable_themes = array('existing-4', 'existing-5'); WP_Theme::network_disable_theme($disable_themes); $new_allowed_themes = get_site_option('allowedthemes'); update_site_option('allowedthemes', $current_allowed_themes); // reset previous value. unset($allowed_themes['existing-4']); unset($allowed_themes['existing-5']); $this->assertEqualSetsWithIndex($allowed_themes, $new_allowed_themes); }
/** * Checks that current theme files 'index.php' and 'style.css' exists. * * Does not initially check the default theme, which is the fallback and should always exist. * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. * Will switch theme to the fallback theme if current theme does not validate. * * You can use the 'validate_current_theme' filter to return false to * disable this functionality. * * @since 1.5.0 * @see WP_DEFAULT_THEME * * @return bool */ function validate_current_theme() { /** * Filter whether to validate the current theme. * * @since 2.7.0 * * @param bool $validate Whether to validate the current theme. Default true. */ if (wp_installing() || !apply_filters('validate_current_theme', true)) { return true; } if (!file_exists(get_template_directory() . '/index.php')) { // Invalid. } elseif (!file_exists(get_template_directory() . '/style.css')) { // Invalid. } elseif (is_child_theme() && !file_exists(get_stylesheet_directory() . '/style.css')) { // Invalid. } else { // Valid. return true; } $default = wp_get_theme(WP_DEFAULT_THEME); if ($default->exists()) { switch_theme(WP_DEFAULT_THEME); return false; } /** * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, * switch to the latest core default theme that's installed. * If it turns out that this latest core default theme is our current * theme, then there's nothing we can do about that, so we have to bail, * rather than going into an infinite loop. (This is why there are * checks against WP_DEFAULT_THEME above, also.) We also can't do anything * if it turns out there is no default theme installed. (That's `false`.) */ $default = WP_Theme::get_core_default_theme(); if (false === $default || get_stylesheet() == $default->get_stylesheet()) { return true; } switch_theme($default->get_stylesheet()); return false; }
/** * * @param string $theme_key * @param WP_Theme $theme * @return false|void */ function wp_theme_update_row($theme_key, $theme) { $current = get_site_transient('update_themes'); if (!isset($current->response[$theme_key])) { return false; } $r = $current->response[$theme_key]; $theme_name = $theme['Name']; $details_url = add_query_arg(array('TB_iframe' => 'true', 'width' => 1024, 'height' => 800), $current->response[$theme_key]['url']); $wp_list_table = _get_list_table('WP_MS_Themes_List_Table'); $active = $theme->is_allowed('network') ? ' active' : ''; echo '<tr class="plugin-update-tr' . $active . '" id="' . esc_attr($theme->get_stylesheet() . '-update') . '" data-slug="' . esc_attr($theme->get_stylesheet()) . '"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">'; if (!current_user_can('update_themes')) { /* translators: 1: theme name, 2: details URL, 3: accessibility text, 4: version number */ printf(__('There is a new version of %1$s available. <a href="%2$s" class="thickbox open-plugin-details-modal" aria-label="%3$s">View version %4$s details</a>.'), $theme_name, esc_url($details_url), esc_attr(sprintf(__('View %1$s version %2$s details'), $theme_name, $r['new_version'])), $r['new_version']); } elseif (empty($r['package'])) { /* translators: 1: theme name, 2: details URL, 3: accessibility text, 4: version number */ printf(__('There is a new version of %1$s available. <a href="%2$s" class="thickbox open-plugin-details-modal" aria-label="%3$s">View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>'), $theme_name, esc_url($details_url), esc_attr(sprintf(__('View %1$s version %2$s details'), $theme_name, $r['new_version'])), $r['new_version']); } else { /* translators: 1: theme name, 2: details URL, 3: accessibility text, 4: version number, 5: update URL, 6: accessibility text */ printf(__('There is a new version of %1$s available. <a href="%2$s" class="thickbox open-plugin-details-modal" aria-label="%3$s">View version %4$s details</a> or <a href="%5$s" class="update-link" aria-label="%6$s">update now</a>.'), $theme_name, esc_url($details_url), esc_attr(sprintf(__('View %1$s version %2$s details'), $theme_name, $r['new_version'])), $r['new_version'], wp_nonce_url(self_admin_url('update.php?action=upgrade-theme&theme=') . $theme_key, 'upgrade-theme_' . $theme_key), esc_attr(sprintf(__('Update %s now'), $theme_name))); } /** * Fires at the end of the update message container in each * row of the themes list table. * * The dynamic portion of the hook name, `$theme_key`, refers to * the theme slug as found in the WordPress.org themes repository. * * @since 3.1.0 * * @param WP_Theme $theme The WP_Theme object. * @param array $r { * An array of metadata about the available theme update. * * @type string $new_version New theme version. * @type string $url Theme URL. * @type string $package Theme update package URL. * } */ do_action("in_theme_update_message-{$theme_key}", $theme, $r); echo '</div></td></tr>'; }
/** * @global string $status * @global array $totals * * @param WP_Theme $theme */ public function single_row($theme) { global $status, $totals; if ($this->is_site_themes) { $allowed = $theme->is_allowed('site', $this->site_id); } else { $allowed = $theme->is_allowed('network'); } $stylesheet = $theme->get_stylesheet(); $class = !$allowed ? 'inactive' : 'active'; $id = sanitize_html_class($theme->get_stylesheet()); if (!empty($totals['upgrade']) && !empty($theme->update)) { $class .= ' update'; } echo "<tr id='{$id}' class='{$class}'>"; $this->single_row_columns($theme); echo "</tr>"; if ($this->is_site_themes) { remove_action("after_theme_row_{$stylesheet}", 'wp_theme_update_row'); } /** * Fires after each row in the Multisite themes list table. * * @since 3.1.0 * * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme Current WP_Theme object. * @param string $status Status of the theme. */ do_action('after_theme_row', $stylesheet, $theme, $status); /** * Fires after each specific row in the Multisite themes list table. * * The dynamic portion of the hook name, `$stylesheet`, refers to the * directory name of the theme, most often synonymous with the template * name of the theme. * * @since 3.5.0 * * @param string $stylesheet Directory name of the theme. * @param WP_Theme $theme Current WP_Theme object. * @param string $status Status of the theme. */ do_action("after_theme_row_{$stylesheet}", $stylesheet, $theme, $status); }
/** * Runs the actual child theme creation functionality * * @global WP_Filesystem_Base $wp_filesystem * * @param string $new_theme * @param WP_Theme $template * * @throws Exception If the global filesystem object isn't available */ public static function procreate($new_theme, WP_Theme $template) { /** @var WP_Filesystem_Base $wp_filesystem */ global $wp_filesystem; if (!$wp_filesystem instanceof WP_Filesystem_Base) { if (!WP_Filesystem()) { throw new Exception(esc_html__('Could not access the filesystem!', 'child-themify')); } } $oldStylesheet = $template->get_stylesheet(); $templateDirectory = untrailingslashit($template->get_stylesheet_directory()); $oldName = $template->name; $new_theme_directory = trailingslashit(get_theme_root()) . sanitize_file_name(strtolower($new_theme)); $wp_filesystem->mkdir($new_theme_directory); $newStylesheet = trailingslashit($new_theme_directory) . 'style.css'; $wp_filesystem->touch($newStylesheet); $stylesheetContents = <<<EOF /* Theme Name: {$new_theme} Version: 1.0 Description: A child theme of {$oldName} Template: {$oldStylesheet} */ @import url("../{$oldStylesheet}/style.css"); EOF; $wp_filesystem->put_contents($newStylesheet, $stylesheetContents); if (file_exists("{$templateDirectory}/screenshot.png")) { $wp_filesystem->copy("{$templateDirectory}/screenshot.png", "{$new_theme_directory}/screenshot.png"); } add_settings_error('', 'child-themify', esc_html__('Your child theme was created successfully.', 'child-themify'), 'updated'); }
/** * Retrieve theme data from parsed theme file. * * @since 1.5.0 * @deprecated 3.4.0 * @deprecated Use wp_get_theme() * @see wp_get_theme() * * @param string $theme_file Theme file path. * @return array Theme data. */ function get_theme_data($theme_file) { _deprecated_function(__FUNCTION__, '3.4', 'wp_get_theme()'); $theme = new WP_Theme(basename(dirname($theme_file)), dirname(dirname($theme_file))); $theme_data = array('Name' => $theme->get('Name'), 'URI' => $theme->display('ThemeURI', true, false), 'Description' => $theme->display('Description', true, false), 'Author' => $theme->display('Author', true, false), 'AuthorURI' => $theme->display('AuthorURI', true, false), 'Version' => $theme->get('Version'), 'Template' => $theme->get('Template'), 'Status' => $theme->get('Status'), 'Tags' => $theme->get('Tags'), 'Title' => $theme->get('Name'), 'AuthorName' => $theme->get('Author')); foreach (apply_filters('extra_theme_headers', array()) as $extra_header) { if (!isset($theme_data[$extra_header])) { $theme_data[$extra_header] = $theme->get($extra_header); } } return $theme_data; }
$themes = isset($_POST['checked']) ? (array) $_POST['checked'] : array(); if (empty($themes)) { wp_safe_redirect(add_query_arg('error', 'none', $referer)); exit; } WP_Theme::network_enable_theme((array) $themes); wp_safe_redirect(add_query_arg('enabled', count($themes), $referer)); exit; case 'disable-selected': check_admin_referer('bulk-themes'); $themes = isset($_POST['checked']) ? (array) $_POST['checked'] : array(); if (empty($themes)) { wp_safe_redirect(add_query_arg('error', 'none', $referer)); exit; } WP_Theme::network_disable_theme((array) $themes); wp_safe_redirect(add_query_arg('disabled', count($themes), $referer)); exit; case 'update-selected': check_admin_referer('bulk-themes'); if (isset($_GET['themes'])) { $themes = explode(',', $_GET['themes']); } elseif (isset($_POST['checked'])) { $themes = (array) $_POST['checked']; } else { $themes = array(); } $title = __('Update Themes'); $parent_file = 'themes.php'; require_once ABSPATH . 'wp-admin/admin-header.php'; echo '<div class="wrap">';
/** * Prepare item for response * * @param WP_Theme $item * @param WP_REST_Request $request * * @return array */ public function prepare_item_for_response($item, $request) { return array('name' => $item->get('Name'), 'slug' => $item->slug, 'version' => $item->get('Version'), 'description' => $item->get('Description'), 'author' => $item->get('Author'), 'author_uri' => $item->get('AuthorURI'), 'text_domain' => $item->get('TextDomain'), 'domain_path' => $item->get('DomainPath'), 'tags' => $item->get('Tags')); }
/** * Returns the URL to the directory of a theme's "template" files. * * In the case of a child theme, this is the URL to the directory of the * parent theme's files. * * @since 3.4.0 * @access public * * @return string URL to the template directory. */ public function get_template_directory_uri() { if ($this->parent) { $theme_root_uri = $this->parent->get_theme_root_uri(); } else { $theme_root_uri = $this->get_theme_root_uri(); } return $theme_root . '/' . $this->template; }
/** * Theme switched * * @since 0.1.0 * * @param string $new_name * @param WP_Theme $new_theme */ public function switch_theme($new_name, WP_Theme $new_theme) { // Insert activity wp_insert_user_activity(array('object_type' => $this->object_type, 'object_subtype' => $new_theme->get_stylesheet(), 'object_name' => $new_name, 'object_id' => 0, 'action' => 'activate')); }