charset ) ) $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; // Upgrade $version = get_site_option( 'dpa_db_version' ); if ( $version !== false ) { switch ( $version ) { case '6': // version 1.0 + 1.1 $wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements_categories TO {$bp->achievements->table_categories}" ); $wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements_unlocked TO {$bp->achievements->table_unlocked}" ); $wpdb->query( "RENAME TABLE {$wpdb->base_prefix}dpa_achievements TO {$bp->achievements->table_achievements}" ); // TODO: add note in documentation if there are existing custom achievements, they'll need to change their DB records appropiately. $wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_achievements} ADD COLUMN is_default int(1) NOT NULL" ) ); $wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_achievements} ADD COLUMN is_special int(1) NOT NULL" ) ); $wpdb->query( $wpdb->prepare( "ALTER TABLE {$bp->achievements->table_categories} ADD COLUMN is_default int(1) NOT NULL" ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET is_default = 1, is_special = 0" ) ); $wpdb->query( $wpdb->prepare( "UPDATE {$bp->achievements->table_categories} SET is_default = 1" ) ); break; } update_site_option( 'dpa_db_version', DPA_DB_VERSION ); do_action( 'dpa_after_upgrade' ); return; } // Install $sql = array(); $sql[] = "CREATE TABLE {$bp->achievements->table_achievements} ( id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, category_id bigint(20) NOT NULL, short_name varchar(100) NOT NULL, nice_name varchar(100) NOT NULL, description longtext NOT NULL, points int(100) NOT NULL, active int(1) NOT NULL, is_default int(1) NOT NULL, is_special int(1) NOT NULL, KEY short_name (short_name) ) {$charset_collate};"; $sql[] = "CREATE TABLE {$bp->achievements->table_unlocked} ( id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, achievement_id bigint(20) NOT NULL, user_id bigint(20) NOT NULL, achieved_at DATETIME NOT NULL ) {$charset_collate};"; $sql[] = "CREATE TABLE {$bp->achievements->table_categories} ( id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, category varchar(100) NOT NULL, is_default int(1) NOT NULL ) {$charset_collate};"; $categories = array( __( 'Blog', 'dpa' ), __( 'Friends', 'dpa' ), __( 'Groups', 'dpa' ), __( 'Messaging', 'dpa'), __( 'Profile', 'dpa' ) ); foreach( $categories as $name ) { $sql[] = $wpdb->prepare( "INSERT INTO {$bp->achievements->table_categories} ( category, is_default ) VALUES ( %s, 1 );", $name ); } require_once( ABSPATH . 'wp-admin/upgrade-functions.php' ); dbDelta( $sql ); $sql = array(); $achievements = dpa_get_defaultachievements(); foreach ( $achievements as $achievement ) { $category_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->achievements->table_categories} WHERE category = %s", $achievement['category'] ) ); $sql[] = $wpdb->prepare( "INSERT INTO {$bp->achievements->table_achievements} ( category_id, short_name, nice_name, description, points, active, is_default, is_special ) VALUES ( %d, %s, %s, %s, %d, 1, 1, 0 );", $category_id, $achievement['short_name'], $achievement['name'], $achievement['description'], $achievement['points'] ); } dbDelta( $sql ); update_site_option( 'dpa_db_version', DPA_DB_VERSION ); do_action( 'dpa_after_install' ); } function dpa_setup_globals() { global $bp, $wpdb; /* For internal identification */ $bp->achievements->id = 'achievements'; $bp->achievements->slug = DPA_SLUG; $bp->achievements->slug_summary = DPA_SLUG_SUMMARY; $bp->achievements->table_achievements = $wpdb->base_prefix . 'dpa'; $bp->achievements->table_unlocked = $wpdb->base_prefix . 'dpa_unlocked'; $bp->achievements->table_categories = $wpdb->base_prefix . 'dpa_categories'; $bp->achievements->format_notification_function = 'dpa_format_notifications'; /* Register this in the active components array */ $bp->active_components[$bp->achievements->slug] = $bp->achievements->id; } add_action( 'plugins_loaded', 'dpa_setup_globals' ); add_action( 'admin_menu', 'dpa_setup_globals' ); function dpa_check_installed() { if ( !is_site_admin() ) return false; /* Need to check db tables exist, activate hook no-worky in mu-plugins folder. */ if ( get_site_option( 'dpa_db_version' ) < DPA_DB_VERSION ) dpa_install(); } add_action( 'admin_menu', 'dpa_check_installed' ); function dpa_load_textdomain() { $locale = apply_filters( 'buddypress_locale', get_locale() ); $mofile = WP_PLUGIN_DIR . "/achievements/dp-achievements/languages/achievements-$locale.mo"; if ( file_exists( $mofile ) ) load_textdomain( 'dpa', $mofile ); } add_action ( 'plugins_loaded', 'dpa_load_textdomain', 5 ); add_action( 'dpa_after_upgrade', 'dpa_recalculate_userpoints' ); add_action( 'dpa_after_install', 'dpa_recalculate_userpoints' ); function dpa_setup_nav() { global $bp, $wpdb; /* Add 'Achievements' to the main navigation */ bp_core_new_nav_item( array( 'name' => __( 'Achievements', 'dpa' ), 'slug' => $bp->achievements->slug, 'screen_function' => 'dpa_screen', 'default_subnav_slug' => $bp->achievements->slug_summary, 'item_css_id' => $bp->achievements->id ) ); $achievements_link = $bp->loggedin_user->domain . $bp->achievements->slug . '/'; /* Add the subnav items to the Achievements nav item */ bp_core_new_subnav_item( array( 'name' => apply_filters( 'dpa_filter_achievement_category', __( 'Summary', 'dpa' ) ), 'slug' => apply_filters( 'dpa_make_category_slug', $bp->achievements->slug_summary ), 'parent_url' => $achievements_link, 'parent_slug' => $bp->achievements->slug, 'screen_function' => 'dpa_screen' ) ); $categories = wp_cache_get( 'dpa_distinct_categories', 'dpa' ); if ( !$categories ) { $categories = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT category FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" ) ); wp_cache_set( 'dpa_distinct_categories', $categories, 'dpa' ); } foreach ( (array) $categories as $category_name ) { $slug = apply_filters( 'dpa_make_category_slug', $category_name ); bp_core_new_subnav_item( array( 'name' => apply_filters( 'dpa_filter_achievement_category', $category_name ), 'slug' => $slug, 'parent_url' => $achievements_link, 'parent_slug' => $bp->achievements->slug, 'screen_function' => 'dpa_screen', 'item_css_id' => "achievements-$slug" ) ); } if ( $bp->current_component == $bp->achievements->slug ) { if ( !bp_is_home() ) $bp->bp_options_avatar = bp_core_fetch_avatar( array( 'item_id' => $bp->displayed_user->id, 'type' => 'thumb' ) ); $bp->bp_options_title = __( 'Category', 'dpa' ); } do_action( 'dpa_setup_nav' ); } add_action( 'wp', 'dpa_setup_nav', 2 ); add_action( 'admin_menu', 'dpa_setup_nav', 2 ); /******************************************************************************** * Business Functions * * Business functions are where all the magic happens in BuddyPress. They will * handle the actual saving or manipulation of information. Usually they will * hand off to a database class for data access, then return * true or false on success or failure. */ /* TODO: DB table won't exist on first page load (via /wp-admin/). As this is called on *every* page load, can't to slow it down at all by checking URL or by SQL. Any kind of "IF EXISTS" SQL syntax? */ function dpa_load_achievements() { global $bp, $wpdb; $achievements = $wpdb->get_col( $wpdb->prepare( "SELECT short_name FROM {$bp->achievements->table_achievements} WHERE active = 1" ) ); $unique_achievements = array(); // Strips out anything after underscores (for ranked achievements). foreach ( (array) $achievements as $a ) { $short_name = "dpa_register_$a"; $i = strpos( $short_name, '_', strlen( 'dpa_register_' ) ); if ( $i !== false ) $short_name = substr( $short_name, 0, $i ); $unique_achievements[] = $short_name; } $unique_achievements = array_unique( $unique_achievements ); foreach ( (array) $unique_achievements as $achievement ) { if ( function_exists( $achievement ) ) { do_action( 'dpa_beforeload_' . $achievement ); call_user_func( $achievement ); do_action( 'dpa_beforeload_' . $achievement ); } } } add_action( 'plugins_loaded', 'dpa_load_achievements', 20 ); function dpa_update_userpoints( $user_id, $points=0 ) { $oldpoints = get_usermeta( $user_id, 'dpa_points' ); update_usermeta( $user_id, 'dpa_points', apply_filters( 'dpa_filter_usermeta_points', $oldpoints ) + $points ); } function dpa_update_achievement( $id, $action ) { global $bp, $wpdb; $sql = ''; if ( 'enable' == $action ) $sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET active = 1 WHERE id = %d LIMIT 1", $id ); elseif ( 'disable' == $action ) $sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET active = 0 WHERE id = %d LIMIT 1", $id ); elseif ( 'save' == $action ) { if ( isset( $_REQUEST['achievement_category'] ) && isset( $_REQUEST['achievement_description'] ) && isset( $_REQUEST['achievement_points'] ) && isset( $_REQUEST['achievement_name'] ) ) { $sql = $wpdb->prepare( "UPDATE {$bp->achievements->table_achievements} SET category_id = %d, description = %s, points = %d, nice_name = %s WHERE id = %d LIMIT 1", $_REQUEST['achievement_category'], $_REQUEST['achievement_description'], $_REQUEST['achievement_points'], $_REQUEST['achievement_name'], $id ); } } if ( empty( $sql ) || !$wpdb->query( $sql ) ) bp_core_add_message( __( 'There was an error updating the database; please try again.', 'dpa' ), 'error' ); else bp_core_add_message( __( 'Achievement details have been updated.', 'dpa' ) ); } function dpa_recalculate_userpoints() { global $bp, $wpdb; if ( !is_site_admin() ) return; define( 'DPA_CHECKING', 1 ); $original_userid = $bp->loggedin_user->id; $user_ids = BP_Core_User::get_active_users( null, 1 ); foreach ( $user_ids['users'] as $user ) { $achievements = $wpdb->get_col( $wpdb->prepare( "SELECT short_name FROM {$bp->achievements->table_achievements} WHERE active = 1 AND is_default = 1" ) ); $unique_achievements = array(); // Strips out anything after underscores (for ranked achievements). foreach ( (array) $achievements as $achievement ) { $short_name = "dpa_handle_$achievement"; $i = strpos( $short_name, '_', strlen( 'dpa_handle_' ) ); if ( $i !== false ) $short_name = substr( $short_name, 0, $i ); $unique_achievements[] = $short_name; } $unique_achievements = array_unique( $unique_achievements ); $bp->loggedin_user->id = $user->user_id; foreach ( (array) $unique_achievements as $achievement ) call_user_func( $achievement ); $sql = $wpdb->prepare( "SELECT SUM(points) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a WHERE u.achievement_id = a.id AND a.active = 1 AND u.user_id = %d", $user->user_id ); update_usermeta( $user->user_id, 'dpa_points', $wpdb->get_var( $sql ) ); } do_action( 'dpa_recalculate_userpoints', $original_userid ); $bp->loggedin_user->id = $original_userid; } function dpa_get_all_unlocked_achievements( $user_id, $limit=0, $category='' ) { global $wpdb, $bp; $sql = $wpdb->prepare( "SELECT a.id, achieved_at, category, description, active, is_special, nice_name, points, short_name FROM wp_dpa as a LEFT JOIN wp_dpa_unlocked as u ON a.id = u.achievement_id AND u.user_id = %d LEFT JOIN wp_dpa_categories as c ON a.category_id = c.id WHERE a.active = 1", $user_id ); if ( $category ) $sql .= $wpdb->prepare( " AND c.category = %s", $category ); $sql .= " ORDER BY achieved_at DESC"; if ( $limit ) $sql .= " LIMIT {$limit}"; return $wpdb->get_results( $sql ); } function dpa_get_recent_achievements( $user_id, $limit=0, $category='' ) { global $wpdb, $bp; $sql = $wpdb->prepare( "SELECT a.id, achieved_at, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c, {$bp->achievements->table_unlocked} as u WHERE a.active = 1 AND c.id = a.category_id AND u.achievement_id = a.id AND u.user_id = %d", $user_id ); if ( $category ) $sql .= $wpdb->prepare( " AND c.category = %s", $category ); $sql .= " ORDER BY achieved_at DESC"; if ( $limit ) $sql .= " LIMIT {$limit}"; return $wpdb->get_results( $sql ); } function dpa_get_all_disabled_achievements( $limit=0, $category='' ) { global $wpdb, $bp; $sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 0 AND c.id = a.category_id" ); if ( $category ) $sql .= $wpdb->prepare( " AND c.category = %s", $category ); if ( $limit ) $sql .= " LIMIT {$limit}"; return $wpdb->get_results( $sql ); } function dpa_get_all_enabled_achievements( $limit=0, $category='' ) { global $wpdb, $bp; $sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" ); if ( $category ) $sql .= $wpdb->prepare( " AND c.category = %s", $category ); if ( $limit ) $sql .= " LIMIT {$limit}"; return $wpdb->get_results( $sql ); } function dpa_get_all_achievements( $limit=0, $category='' ) { global $wpdb, $bp; $sql = $wpdb->prepare( "SELECT a.id, category, description, active, is_special, nice_name, points, short_name FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE c.id = a.category_id" ); if ( $category ) $sql .= $wpdb->prepare( " AND c.category = %s", $category ); if ( $limit ) $sql .= " LIMIT {$limit}"; return $wpdb->get_results( $sql ); } function dpa_get_all_categories( $user_id, $category='' ) { global $wpdb, $bp; if ( $category ) { $category_names = array( $category ); } else { $category_names = wp_cache_get( 'dpa_distinct_categories', 'dpa' ); if ( !$category_names ) { $category_names = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT category FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id" ) ); wp_cache_set( 'dpa_distinct_categories', $category_names, 'dpa' ); } } $categories = array(); foreach ( (array) $category_names as $category ) { $categories[$category] = new stdClass; $categories[$category]->name = $category; } foreach ( (array) $category_names as $category ) { $sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE u.user_id = %d AND a.active = 1 AND u.achievement_id = a.id AND c.id = a.category_id AND c.category = %s", $user_id, $category ); $categories[$category]->unlocked_count = (int) $wpdb->get_var( $sql ); $sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_achievements} as a, {$bp->achievements->table_categories} as c WHERE a.active = 1 AND c.id = a.category_id AND c.category = %s", $category ); $categories[$category]->total_count = (int) $wpdb->get_var( $sql ); $categories[$category]->percentage = ( $categories[$category]->unlocked_count / $categories[$category]->total_count ) * 100; } return array_values( $categories ); } function dpa_get_overall_category( $user_id ) { global $wpdb, $bp; $overall = array(); $overall[0] = new stdClass; $overall[0]->name = 'overall'; $sql = $wpdb->prepare( "SELECT COUNT(short_name) FROM {$bp->achievements->table_unlocked} as u, {$bp->achievements->table_achievements} as a WHERE u.user_id = %d AND a.active = 1 AND u.achievement_id = a.id", $user_id ); $overall[0]->unlocked_count = (int) $wpdb->get_var( $sql ); $sql = $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->achievements->table_achievements} WHERE active = 1" ); $overall[0]->total_count = (int) $wpdb->get_var( $sql ); $overall[0]->percentage = ( $overall[0]->unlocked_count / $overall[0]->total_count ) * 100; return $overall; } /******************************************************************************** * Screen Functions * * Screen functions are the controllers of BuddyPress. They will execute when their * specific URL is caught. They will first save or manipulate data using business * functions, then pass on the user to a template file. */ function dpa_screen_filter_template( $located_template, $template_name ) { if ( !empty( $located_template ) ) return $located_template; if ( $bp->current_component != $bp->achievements->slug ) return false; if ( false !== strpos( $template_name[0], 'achievements_theme_' ) ) { $prefix = strlen( 'achievements_theme_' ); $template_name = substr( $template_name[0], $prefix, strlen( $template_name[0] ) - $prefix ); $template_path = WP_PLUGIN_DIR . "/achievements/dp-achievements/theme/$template_name"; if ( file_exists( $template_path ) ) return $template_path; } return false; } add_filter( 'bp_located_template', 'dpa_screen_filter_template', 10, 2 ); function dpa_screen() { global $bp, $is_member_page; if ( $bp->current_component == $bp->achievements->slug && !$is_member_page ) { bp_core_redirect( site_url() ); return; } $page = bp_current_action(); if ( $page == $bp->achievements->slug_summary ) { do_action( 'dpa_screen_summary' ); bp_core_load_template( 'achievements_theme_summary' ); } else { do_action( 'dpa_screen_category', $page ); bp_core_load_template( 'achievements_theme_category' ); } } function dpa_screen_notification_settings() { global $current_user; ?>
id, 'notification_dpa_unlock_achievement' ) || 'yes' == get_usermeta( $current_user->id, 'notification_dpa_unlock_achievement' ) ) { ?>checked="checked" /> id, 'notification_dpa_unlock_achievement' ) == 'no' ) { ?>checked="checked" />
$user_id, 'content' => $content, 'item_id' => $item_id, 'component_name' => $bp->achievements->id, 'component_action' => $component_action, 'primary_link' => bp_core_get_userurl( $user_id ) ) ); } function dpa_format_activity( $user_id, $achievement_id, $component_action = false ) { global $bp, $wpdb; if ( !$component_action ) $component_action = 'new_achievement'; $user_link = bp_core_get_userlink( $user_id ); switch( $component_action ) { case 'new_achievement': $userdata = get_userdata( $user_id ); $sql = $wpdb->prepare( "SELECT nice_name FROM {$bp->achievements->table_achievements} WHERE id = %d LIMIT 1", $achievement_id ); $achievement_name = apply_filters( 'dpa_filter_achievement_nice_name', $wpdb->get_var( $sql ) ); $achievement_link = sprintf( '%s', bp_core_get_userurl( $user_id ) . $bp->achievements->slug, $achievement_name ); $stream_item = apply_filters( 'dpa_new_achievement_activity', sprintf( __( '%s unlocked achievement: %s', 'dpa' ), $user_link, $achievement_link ), $user_id, $achievement_id ); break; } return apply_filters( 'dpa_format_activity', $stream_item, $user_id, $achievement_id, $component_action ); } function dpa_register_activity_actions() { global $bp; if ( !function_exists( 'bp_activity_set_action' ) ) return false; bp_activity_set_action( $bp->achievements->id, 'new_achievement', __( 'Achievement unlocked', 'dpa' ) ); do_action( 'dpa_register_activity_actions' ); } add_action( 'plugins_loaded', 'dpa_register_activity_actions' ); function dpa_format_notifications( $action, $item_id, $secondary_item_id, $total_items ) { global $bp, $wpdb; switch ( $action ) { case 'new_achievement': if ( 1 == $total_items ) { $sql = $wpdb->prepare( "SELECT nice_name FROM {$bp->achievements->table_achievements} WHERE id = %d LIMIT 1", $item_id ); $achievement_name = apply_filters( 'dpa_filter_achievement_nice_name', $wpdb->get_var( $sql ) ); $user_url = bp_core_get_userurl( $secondary_item_id ); return apply_filters( 'dpa_new_achievement_notification', '' . sprintf( __( 'Achievement unlocked: %s', 'dpa' ), $achievement_name ) . '', $secondary_item_id, $item_id ); } else { $user_url = bp_core_get_userurl( $bp->loggedin_user->id ); return apply_filters( 'dpa_new_achievement_notification', '' . __( 'Achievements unlocked!', 'dpa' ) . '', $secondary_item_id, $item_id ); } break; } do_action( 'dpa_format_notifications', $action, $item_id, $secondary_item_id, $total_items ); return false; } function dpa_screen_remove_notifications() { global $bp; if ( bp_is_home() ) bp_core_delete_notifications_for_user_by_type( $bp->loggedin_user->id, $bp->achievements->slug, 'new_achievement' ); } add_action( 'dpa_screen_summary', 'dpa_screen_remove_notifications' ); ?>