/** * Gets a list of recent comments formatted for display in a widget. * * The array of returned comments contains custom object instances with the * following properties that can be used by the widget: * * author_name - the display name of the comment's author * content - the content of the comment * meta - a string describing the comment's meta, constructed from * the meta formatting string passed to this method * permalink - the permalink URL for the comment * post_title - the name of the post on which the comment was made * * @param int $max_comments the maximum number of comments to return * @param int $max_comments_per_blog the most comments allowed per blog * @param string $meta_format the formatting string for the comment meta * @return array an array of formatted comments * * @since 0.2 */ public function get_comments_for_widget($max_comments, $max_comments_per_blog, $meta_format) { // Use cached values if possible $cached = $this->get_site_cache('widget'); if ($cached !== null) { return $cached; } $comments = array(); $raw_comments = $this->limit_sitewide_resources($this->get_sitewide_comments(), $max_comments, $max_comments_per_blog); $student_ids = ClassBlogs_Students::get_student_user_ids(); foreach ($raw_comments as $comment) { // Ignore the comment if it's not by a student if (!in_array($comment->user_id, $student_ids)) { continue; } // Create a string for the comment metadata $meta = ""; if ($meta_format) { $blog = sprintf('<a href="%s">%s</a>', ClassBlogs_NXTClass::get_blogaddress_by_id($comment->cb_sw_blog_id), ClassBlogs_NXTClass::get_blog_option($comment->cb_sw_blog_id, 'blogname')); $meta = ClassBlogs_Utils::format_user_string($meta_format, array('blog' => $blog, 'date' => mysql2date(get_option('date_format'), $comment->comment_date), 'time' => mysql2date(get_option('time_format'), $comment->comment_date)), 'cb-sitewide-comment'); } // Build the permalink to the comment using the post URL and an anchor $permalink = sprintf('%s#comment-%d', ClassBlogs_NXTClass::get_blog_permalink($comment->cb_sw_blog_id, $comment->comment_post_ID), $comment->comment_ID); $comments[] = (object) array('author_name' => $comment->comment_author, 'content' => $comment->comment_content, 'meta' => $meta, 'permalink' => $permalink, 'post_title' => $comment->post_title); } $this->set_site_cache('widget', $comments); return $comments; }
/** * Formats the blog display name based upon the formatting string. * * @param string $format the formatting string for the display name * @param int $user_id the ID of the student who owns the blog * @param int $blog_id the ID of the blog * @return string the formatted blog display name * * @access private * @since 0.2 */ private function _format_blog_display_name($format, $user_id, $blog_id) { $blog_title = ClassBlogs_NXTClass::get_blog_option($blog_id, 'blogname'); $first_name = get_user_meta($user_id, 'first_name', true); $last_name = get_user_meta($user_id, 'last_name', true); $blog_name = ClassBlogs_Utils::format_user_string($format, array('blog' => $blog_title, 'firstname' => $first_name, 'lastname' => $last_name, 'nickname' => get_user_meta($user_id, 'nickname', true)), 'cb-student-blog'); // If the blog name is the same as that of the main blog, use the // student's full name instead $main_blog_title = ClassBlogs_NXTClass::get_blog_option(ClassBlogs_Settings::get_root_blog_id(), 'blogname'); if ($blog_title === $main_blog_title) { $blog_name = $first_name . " " . $last_name; } return $blog_name; }
/** * Returns a random image from one of the blogs on the site. * * The returned image object, if not null, will have the following properties: * * blog_id - the ID of the blog on which the image was posted * title - the image's title * url - the absolute URL to the image * * If the image is associated with a particular post, it will also have * the following properties on it: * * post_id - the ID of the post that uses the image * user_id - the ID of the user who created a post using the image * * @return mixed the random image object, or null if none can be found * * @since 0.1 */ public function get_random_image() { global $blog_id, $nxtdb; $current_blog_id = $blog_id; $image = null; $urls = array(); // Search through every blog for a usable image. If an image is found, build // the link to it and add a possible caption. $blogs = ClassBlogs_Utils::get_all_blog_ids(); shuffle($blogs); foreach ($blogs as $blog) { ClassBlogs_NXTClass::switch_to_blog($blog); $images = $nxtdb->get_results("\n\t\t\t\tSELECT ID, post_title, GUID FROM {$nxtdb->posts}\n\t\t\t\tWHERE post_mime_type LIKE 'image/%%'\n\t\t\t\tAND post_content <> guid"); if ($images) { $image = $images[array_rand($images)]; $urls[] = $image->GUID; $info = nxt_get_attachment_image_src($image->ID); if (!empty($info)) { $image = array('blog_id' => $blog, 'title' => $image->post_title, 'url' => $info[0]); $urls[] = $info[0]; } break; } } ClassBlogs_Utils::restore_blog($current_blog_id); // If we have a valid image, try to find the first post on which it was // used and add its ID to the image data if ($image) { $info = array(); $post_id = null; $user_id = null; foreach ($urls as $url) { $post = $this->_find_first_post_to_use_image($image['blog_id'], $url); if (!empty($post)) { break; } } if (!empty($post)) { $post_id = $post->ID; $user_id = $post->post_author; } $image['post_id'] = $post_id; $image['user_id'] = $user_id; $image = (object) $image; } return $image; }
/** * Registers hooks and sets default options for the plugin. * * @access private * @since 0.3 */ public function _register_hooks() { // If we're not running multisite, this plugin has no purpose, so we // should abort if (!ClassBlogs_Utils::is_multisite()) { return; } // Update the default links options to be a single link pointing back // to the main class blog ClassBlogs_NXTClass::switch_to_blog(ClassBlogs_Settings::get_root_blog_id()); $this->default_options['links'] = array(array('url' => site_url(), 'title' => __('Return to Course Blog', 'classblogs'))); ClassBlogs_NXTClass::restore_current_blog(); // If there are any links defined and we're not in the admin side, // inject the professor's links into a widget in the first widgetized // area of all student blogs in the network $links = $this->get_option('links'); if (!is_admin() && !empty($links)) { add_action('init', array($this, '_register_widget')); add_filter('sidebars_widgets', array($this, '_add_widget')); } }
/** * Returns a list of information about each student blog. * * The blog information will be returned as an array, with keys of user IDs. * Each key's values will be an object with the following attributes: * * blog_id - the possible ID of the blog * url - the URL of the blog * * If running in multisite mode, `blog_id` will be the ID of the user's * blog. If running in single-site mode, however, it will be null, as only * one blog exists, and the blog URL is of the author archive page. * * @return array information on all student blogs * * @since 0.5 */ public static function get_student_blogs() { $blogs = array(); // Cycle through every student foreach (self::get_student_user_ids() as $student_id) { // Add the first non-root blog on which the student is an admin if // running in multisite mode, or use their author archive URL if // running in single-site mode $blog_info = array(); if (ClassBlogs_Utils::is_multisite()) { foreach (ClassBlogs_Utils::get_non_root_blog_ids() as $blog_id) { $admins = get_users("blog_id={$blog_id}&include={$student_id}&role=administrator"); if (count($admins) == 1) { $blog_info = array('blog_id' => $blog_id, 'url' => ClassBlogs_NXTClass::get_blogaddress_by_id($blog_id)); break; } } } else { $blog_info = array('blog_id' => null, 'url' => get_author_posts_url($student_id)); } if (!empty($blog_info)) { $blogs[$student_id] = (object) $blog_info; } } return $blogs; }
/** * Gets a list of recent posts formatted for display in a widget. * * The array of returned posts contains custom object instances with the * following properties that can be used by the widget: * * content - the content of the post * meta - a string describing the post's meta, constructed from * the meta formatting string passed to this method * permalink - the permalink URL for the post * title - the title of the post * * @param int $max_posts the maximum number of posts to return * @param int $max_posts_per_blog the most posts allowed per blog * @param string $meta_format the formatting string for the post meta * @return array an array of formatted posts * * @since 0.2 */ public function get_posts_for_widget($max_posts, $max_posts_per_blog, $meta_format) { // Use cache values if possible $cached = $this->get_site_cache('widget'); if ($cached !== null) { return $cached; } $posts = array(); $raw_posts = $this->limit_sitewide_resources($this->get_sitewide_posts(), $max_posts, $max_posts_per_blog); $student_ids = ClassBlogs_Students::get_student_user_ids(); foreach ($raw_posts as $post) { // Ignore the post if it's not by a student if (!in_array($post->post_author, $student_ids)) { continue; } // Create a string for the post metadata $meta = ""; if ($meta_format) { $user_data = get_userdata($post->post_author); $blog = sprintf('<a href="%s" class="cb-sitewide-post-blog">%s</a>', ClassBlogs_NXTClass::get_blogaddress_by_id($post->cb_sw_blog_id), ClassBlogs_NXTClass::get_blog_option($post->cb_sw_blog_id, 'blogname')); $meta = ClassBlogs_Utils::format_user_string($meta_format, array('author' => $user_data->display_name, 'blog' => $blog, 'date' => mysql2date(get_option('date_format'), $post->post_date), 'time' => mysql2date(get_option('time_format'), $post->post_date)), 'cb-sitewide-post'); } $posts[] = (object) array('content' => $post->post_content, 'meta' => $meta, 'permalink' => ClassBlogs_NXTClass::get_blog_permalink($post->cb_sw_blog_id, $post->ID), 'title' => $post->post_title); } $this->set_site_cache('widget', $posts); return $posts; }
/** * Applies the student's chosen pseudonym. * * This updates the student's user and blog information, then attempts to * update any references to the old URL, such as those used by media embedded * into posts on the blog whose URL is being changed. * * The inputs for this function will have already been validated by another * method, so it can be assumed that they are valid. * * @param int $user_id the student's user ID * @param int $blog_id the ID of the student's primary blog * @param string $new_username the student's new username * * @access private * @since 0.1 */ private function _apply_pseudonym($user_id, $blog_id, $new_username) { global $nxtdb; // Update the student's username $nxtdb->update($nxtdb->users, array('user_login' => $new_username), array('ID' => $user_id), array('%s'), array('%d')); // Deal with the implications of the updated username in multisite if (ClassBlogs_Utils::is_multisite()) { ClassBlogs_NXTClass::switch_to_blog($blog_id); $old_url = trailingslashit(home_url()); // Update the blog URL to reflect their new username $site = get_current_site(); $new_path = trailingslashit($site->path . $new_username); $new_url = 'http://' . $site->domain . $new_path; update_option('siteurl', $new_url); update_option('home', $new_url); update_blog_details($blog_id, array('path' => $new_path)); delete_option('rewrite_rules'); // Replace any occurrences of the old URL in the blog's posts $referring_posts = $nxtdb->get_results("\n\t\t\t\tSELECT ID, post_content FROM {$nxtdb->posts}\n\t\t\t\tWHERE post_content LIKE '%%" . like_escape($old_url) . "%%' "); foreach ($referring_posts as $post) { $nxtdb->update($nxtdb->posts, array('post_content' => str_replace($old_url, $new_url, $post->post_content)), array('ID' => $post->ID), array('%s'), array('%d')); } ClassBlogs_NXTClass::restore_current_blog(); } // Flag that the user has changed their username $changed = $this->get_option('changed_users'); $changed[$new_username] = true; $this->update_option('changed_users', $changed); }
/** * Restores the root blog after the loop has ended. * * This needs to be called to prevent the blog from thinking it is on the * blog on which the last sitewide post displayed was made, which will result * in display and URL-resolution issues. * * @since 0.3 */ public function reset_blog_on_loop_end() { global $nxt_query, $nxt_rewrite; ClassBlogs_NXTClass::restore_current_blog(); if (isset($this->root_blog_posts)) { $nxt_query->posts = $this->root_blog_posts; } if (isset($this->_rewrite)) { $nxt_rewrite = $this->_rewrite; } }
/** * Restores an arbitrary blog. * * This functions identically to `restore_current_blog`, but with the option * of passing a blog ID to restore to. This switches to that blog, then * clears the switched stack and resets the switched state flag to false. * * @param int $blog_id the ID of the blog to restore to * * @since 0.2 */ public static function restore_blog($blog_id) { global $switched_stack, $switched; ClassBlogs_NXTClass::switch_to_blog($blog_id); $switched_stack = array(); $switched = false; }
/** * Returns markup for the local videos page. * * @return string markup for the local playlist page * * @access private * @since 0.1 */ public function _render_playlist_page() { $markup = ""; foreach ($this->get_playlist_videos() as $index => $video) { // Add the video with a title $markup .= '<div class="cb-youtube-local-playlist-page-video post hentry">'; $markup .= '<h2 class="cb-youtube-local-playlist-page-title"><a href="' . esc_url($video->link) . '" title="' . __('View on YouTube', 'classblogs') . '">' . esc_html($video->title) . '</a></h2>'; $markup .= '<div class="cb-youtube-local-playlist-page-video-thumbnail-container">'; $markup .= sprintf('<a href="%1$s"><img src="%2$s" title="%3$s" alt="%3$s" data-youtube-id="%4$s" class="cb-youtube-local-playlist-page-video-thumbnail" /></a>', esc_url($video->link), esc_url($this->_get_large_thumbnail_url($video->youtube_id)), esc_attr($video->title), esc_attr($video->youtube_id)); $markup .= '</div>'; // Add metadata for the video $markup .= sprintf('<p class="cb-youtube-local-playlist-page-meta">%s</p>', sprintf(__('Added to the playlist on %s', 'classblogs'), sprintf('<time datetime="%s" class="cb-youtube-local-playlist-page-date">%s</time>', date('c', strtotime($video->date_added)), esc_html(date_i18n(get_option('date_format'), strtotime($video->date_added)))))); if (!empty($video->used_by)) { $markup .= '<p class="cb-youtube-local-playlist-page-usage">' . __('Embedded in', 'classblogs') . ' '; $links = array(); foreach ($video->used_by as $usage) { $link = '<a class="cb-youtube-local-playlist-page-usage-post" '; ClassBlogs_NXTClass::switch_to_blog($usage->blog_id); $link .= sprintf(' href="%s">%s</a>', esc_url(get_permalink($usage->post_id)), get_post($usage->post_id)->post_title); ClassBlogs_NXTClass::restore_current_blog(); $links[] = $link; } $markup .= implode(', ', $links) . '</p>'; } $markup .= '</div>'; } return $markup; }
/** * Returns the URL for the tag-list page. * * @return string the URL for the tag-list page * * @access private * @since 0.2 */ private function _get_tag_page_url() { ClassBlogs_NXTClass::switch_to_blog(ClassBlogs_Settings::get_root_blog_id()); $url = get_permalink($this->get_option('tag_page_id')); ClassBlogs_NXTClass::restore_current_blog(); return $url; }
/** * Toggles the active status of the class blogs suite. * * @param bool $activate whether to activate or deactivate the plugin suite * * @since 0.4 */ public static function _set_activation($activate) { $method = $activate ? 'activate' : 'deactivate'; ClassBlogs_NXTClass::switch_to_blog(ClassBlogs_Settings::get_root_blog_id()); foreach (self::get_all_plugins() as $plugin) { if (is_callable(array($plugin->plugin, $method))) { call_user_func(array($plugin->plugin, $method)); } } ClassBlogs_NXTClass::restore_current_blog(); }
/** * Aggregates all sitewide posts, comments and tags into separate tables. * * @access private * @since 0.2 */ private function _sync_tables() { global $nxtdb; // Drop all data before proceeding $this->_clear_tables(); $this->clear_site_cache(); // Export the post and comment data for each blog to our tables, which // will also update the tag-usage data foreach ($this->_get_usable_blog_ids() as $blog_id) { ClassBlogs_NXTClass::switch_to_blog($blog_id); foreach ($nxtdb->get_results("SELECT ID FROM {$nxtdb->posts}") as $post) { $this->_track_single_post($post->ID); } foreach ($nxtdb->get_results("SELECT comment_ID FROM {$nxtdb->comments}") as $comment) { $this->_track_single_comment($comment->comment_ID); } ClassBlogs_NXTClass::restore_current_blog(); } }