, Ruben Garcia * @since 1.0.0 */ // Exit if accessed directly if( !defined( 'ABSPATH' ) ) exit; /** * Add requirements meta boxes * * @since 1.0.5 * * @return void */ function gamipress_add_requirements_ui_meta_box() { // Points Awards add_meta_box( 'gamipress-requirements-ui-points-award', __( 'Automatic Points Awards', 'gamipress' ), 'gamipress_requirements_ui_meta_box', 'points-type', 'advanced', 'default', array( 'requirement_type' => 'points-award' ) ); // Points Deductions add_meta_box( 'gamipress-requirements-ui-points-deduct', __( 'Automatic Points Deductions', 'gamipress' ), 'gamipress_requirements_ui_meta_box', 'points-type', 'advanced', 'default', array( 'requirement_type' => 'points-deduct' ) ); // Steps foreach ( gamipress_get_achievement_types_slugs() as $achievement_type ) { add_meta_box( 'gamipress-requirements-ui', __( 'Required Steps', 'gamipress' ), 'gamipress_requirements_ui_meta_box', $achievement_type, 'advanced', 'default', array( 'requirement_type' => 'step' ) ); } // Rank Requirements foreach ( gamipress_get_rank_types_slugs() as $rank_type ) { add_meta_box( 'gamipress-requirements-ui', __( 'Rank Requirements', 'gamipress' ), 'gamipress_requirements_ui_meta_box', $rank_type, 'advanced', 'default', array( 'requirement_type' => 'rank-requirement' ) ); } } add_action( 'add_meta_boxes', 'gamipress_add_requirements_ui_meta_box' ); /** * Renders the HTML for meta box, refreshes whenever a new requirement is added * * @since 1.0.5 * @updated 1.3.7 Added $metabox * * @param WP_Post $post The current post object. * @param array $metabox With metabox id, title, callback, and args elements. * * @return void */ function gamipress_requirements_ui_meta_box( $post = null, $metabox = array() ) { // Define the requirement type to use $requirement_type = gamipress_requirements_ui_get_requirement_type( $post, $metabox ); // If is lowest priority rank then show a notice and prevent to show requirements UI if( $requirement_type === 'rank-requirement' ) { if( ( $post->post_status === 'auto-draft' && gamipress_get_rank_priority( $post->ID ) === 1 ) || ( $post->post_status !== 'auto-draft' && gamipress_is_lowest_priority_rank( $post->ID ) ) ) { echo '

' . __( 'The rank with the lowest priority is set as default rank for all users so this rank should be created without requirements.', 'gamipress' ) . '
' . __( 'You will be able to set requirements on next ranks. After save this rank, if it is not configured as the lowest priority you will be able to edit the requirements again.', 'gamipress' ) . '

'; return; } } // Setup the requirement object based on the requirement type $requirement_types = gamipress_get_requirement_types(); $requirement_type_object = $requirement_types[$requirement_type]; // Get assigned requirements $assigned_requirements = gamipress_get_assigned_requirements( $post->ID, $requirement_type, 'any' ); if( ! $assigned_requirements ) { $assigned_requirements = array(); } // Sort the requirements by their order uasort( $assigned_requirements, 'gamipress_compare_requirements_order' ); switch( $requirement_type ) { case 'points-award': echo '

' . __( 'Define the automatic ways a user could retrieve an amount of this points type. Use the "Label" field to optionally customize the titles of each one.', 'gamipress' ) . '

'; break; case 'points-deduct': echo '

' . __( 'Define the automatic ways a user could lose an amount of this points type. Use the "Label" field to optionally customize the titles of each one.', 'gamipress' ) . '

'; break; case 'step': echo '

' . __( 'Define the required "steps" for this achievement to be considered complete. Use the "Label" field to optionally customize the titles of each step.', 'gamipress' ) . '

'; break; case 'rank-requirement': echo '

' . __( 'Define the required requirements for this rank to be considered that user is ranked on it. Use the "Label" field to optionally customize the titles of each requirement.', 'gamipress' ) . '
' . __( 'Important! User will not earn this requirements until be ranked on the previous rank.', 'gamipress' ) . '

'; break; } // Sequential input if( in_array( $requirement_type, array( 'step', 'rank-requirement' ) ) ) : ?> ID, '_gamipress_sequential_nonce' ); ?>
ID, '_gamipress_sequential' ) ); ?> value="on">
'; foreach ( $assigned_requirements as $requirement ) { gamipress_requirement_ui_html( $requirement->ID, $post->ID ); } echo ''; // Render the add and save buttons ?>
ID; } // Grab post's requirements return get_posts( array( 'post_type' => $requirement_type, 'post_parent' => $post_id, 'post_status' => $post_status, 'orderby' => 'menu_order', 'order' => 'ASC', 'posts_per_page' => -1, 'suppress_filters' => false, ) ); } /** * Helper function for generating the HTML output for configuring a given requirement * * @since 1.0.5 * * @param integer $requirement_id The given requirement's ID * @param integer $post_id The given requirement's parent $post ID * * @return string The concatenated HTML input for the requirement */ function gamipress_requirement_ui_html( $requirement_id = 0, $post_id = 0 ) { // Grab our requirement's requirements and measurement $requirements = gamipress_get_requirement_object( $requirement_id ); $requirement_type = gamipress_get_post_type( $requirement_id ); $status = gamipress_get_post_status( $requirement_id ); $count = ! empty( $requirements['count'] ) ? $requirements['count'] : 1; $limit = ! empty( $requirements['limit'] ) ? $requirements['limit'] : 1; $limit_type = ! empty( $requirements['limit_type'] ) ? $requirements['limit_type'] : 'unlimited'; // Setup the requirement object based on the requirement type $requirement_types = gamipress_get_requirement_types(); $requirement_type_object = $requirement_types[$requirement_type]; ?>
  • />
    array( 'label' => __( 'Duplicate', 'gamipress' ), 'icon' => 'dashicons-admin-page', ), 'delete' => array( 'label' => __( 'Delete', 'gamipress' ), 'icon' => 'dashicons-trash', ) ); /** * Available filter to add custom requirement actions * * @since 1.4.6 * * @param array $requirement_actions */ $requirement_actions = apply_filters( 'gamipress_requirement_ui_requirement_actions', $requirement_actions ); foreach( $requirement_actions as $requirement_action => $requirement_action_args ) : ?>
    true ), 'objects' ); ?> __( 'Unlimited', 'gamipress' ), 'minutely' => __( 'Per minute', 'gamipress' ), 'hourly' => __( 'Per hour', 'gamipress' ), 'daily' => __( 'Per day', 'gamipress' ), 'weekly' => __( 'Per week', 'gamipress' ), 'monthly' => __( 'Per month', 'gamipress' ), 'yearly' => __( 'Per year', 'gamipress' ), ); /** * Filter available to override limit intervals available * * @since 1.9.0 * * @param array $limit_intervals Default limit intervals (unlimited, hourly, daily, weekly, monthly and yearly) * @param int $requirement_id The requirement ID * @param int $post_id The post ID where requirements are displayed * * @return array */ $limit_intervals = apply_filters( 'gamipress_requirement_limit_intervals', $limit_intervals, $requirement_id, $post_id ); ?>
  • post_type === 'points-type' ) { // Requirement type passed through the add_meta_box() $requirement_type = $metabox['args']['requirement_type']; } else if( gamipress_is_achievement( $post ) ) { $requirement_type = 'step'; } else if( gamipress_is_rank( $post ) ) { $requirement_type = 'rank-requirement'; } else if( isset( $metabox['args'] ) && isset( $metabox['args']['requirement_type'] ) ) { $requirement_type = $metabox['args']['requirement_type']; } return apply_filters( 'gamipress_requirements_ui_get_requirement_type', $requirement_type, $post ); } /** * Get all the requirements of a given points award * * @since 1.0.0 * * @param integer $point_award_id The given requirement's post ID * * @return array|bool An array of all the requirement requirements if it has any, false if not */ function gamipress_get_points_award_requirements( $point_award_id = 0 ) { $requirements = gamipress_get_requirement_object( $point_award_id ); return apply_filters( 'gamipress_get_points_award_requirements', $requirements, $point_award_id ); } /** * Get all the requirements of a given points deduct * * @since 1.3.7 * * @param integer $point_deduct_id The given requirement's post ID * * @return array|bool An array of all the requirement requirements if it has any, false if not */ function gamipress_get_points_deduct_requirements( $point_deduct_id = 0 ) { $requirements = gamipress_get_requirement_object( $point_deduct_id ); return apply_filters( 'gamipress_get_points_deduct_requirements', $requirements, $point_deduct_id ); } /** * Get all the requirements of a given step * * @since 1.0.0 * * @param integer $step_id The given requirement's post ID * * @return array|bool An array of all the requirement requirements if it has any, false if not */ function gamipress_get_step_requirements( $step_id = 0 ) { $requirements = gamipress_get_requirement_object( $step_id ); return apply_filters( 'gamipress_get_step_requirements', $requirements, $step_id ); } /** * Get all the requirements of a given rank requirement * * @since 1.3.1 * * @param integer $rank_requirement_id The given requirement's post ID * * @return array|bool An array of all the requirement requirements if it has any, false if not */ function gamipress_get_rank_requirement_requirements( $rank_requirement_id = 0 ) { $requirements = gamipress_get_requirement_object( $rank_requirement_id ); return apply_filters( 'gamipress_get_rank_requirement_requirements', $requirements, $rank_requirement_id ); } /** * AJAX Handler for adding a new requirement * * @since 1.0.0 */ function gamipress_add_requirement_ajax_handler() { // Security check, forces to die if not security passed check_ajax_referer( 'gamipress_admin', 'nonce' ); // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $post = get_post( $post_id ); if( ! $post ) wp_send_json_error( __( 'Invalid post.', 'gamipress' ) ); $requirement_type = gamipress_requirements_ui_get_requirement_type( $post, array( 'args' => array( 'requirement_type' => ( isset( $_POST['requirement_type'] ) ? sanitize_text_field( $_POST['requirement_type'] ) : '' ) ) ) ); // Create a new requirement post and grab it's ID $requirement_id = wp_insert_post( array( 'post_type' => $requirement_type, 'post_status' => 'publish', 'post_parent' => $post->ID, 'menu_order' => 0, ) ); // Output the edit requirement html to insert into the requirements meta box gamipress_requirement_ui_html( $requirement_id, $post->ID ); die; } add_action( 'wp_ajax_gamipress_add_requirement', 'gamipress_add_requirement_ajax_handler' ); /** * AJAX Handler for duplicate a requirement * * @since 1.0.0 */ function gamipress_duplicate_requirement_ajax_handler() { // Security check, forces to die if not security passed check_ajax_referer( 'gamipress_admin', 'nonce' ); // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $requirement_id = isset( $_POST['requirement_id'] ) ? absint( $_POST['requirement_id'] ) : 0; $post = get_post( $post_id ); if( ! $post ) wp_send_json_error( __( 'Invalid post.', 'gamipress' ) ); $requirement = gamipress_get_requirement_object( $requirement_id ); // Create a new requirement post and grab it's ID $clone_requirement_id = wp_insert_post( array( 'post_title' => gamipress_get_post_field( 'post_title', $requirement['ID'] ), 'post_type' => gamipress_get_post_field( 'post_type', $requirement['ID'] ), 'post_status' => 'publish', 'post_parent' => $post->ID, 'menu_order' => absint( $post->menu_order ) + 1, ) ); // Set the cloned ID to let gamipress_update_requirement() clone the data $requirement['ID'] = $clone_requirement_id; gamipress_update_requirement( $requirement ); // Reset the trigger cache gamipress_delete_trigger_cache( $requirement['trigger_type'] ); // Output the edit requirement html to insert into the requirements meta box gamipress_requirement_ui_html( $clone_requirement_id, $post->ID ); die; } add_action( 'wp_ajax_gamipress_duplicate_requirement', 'gamipress_duplicate_requirement_ajax_handler' ); /** * AJAX Handler for deleting a requirement * * @since 1.0.0 */ function gamipress_delete_requirement_ajax_handler() { // Security check, forces to die if not security passed check_ajax_referer( 'gamipress_admin', 'nonce' ); // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); $requirement_id = isset( $_POST['requirement_id'] ) ? absint( $_POST['requirement_id'] ) : 0; // Reset the trigger cache $trigger = gamipress_get_post_meta( $requirement_id, '_gamipress_trigger_type' ); gamipress_delete_trigger_cache( $trigger ); /** * Action to delete custom requirement * * @since 1.0.0 * * @param int $requirement_id */ do_action( 'gamipress_delete_requirement', $requirement_id ); // Delete the requirement post wp_delete_post( $requirement_id ); die; } add_action( 'wp_ajax_gamipress_delete_requirement', 'gamipress_delete_requirement_ajax_handler' ); /** * AJAX Handler for saving all requirements * * @since 1.0.5 */ function gamipress_update_requirements_ajax_handler() { // Security check, forces to die if not security passed check_ajax_referer( 'gamipress_admin', 'nonce' ); // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) { wp_send_json_error( __( 'You are not allowed to perform this action.', 'gamipress' ) ); } $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $requirements_limit = 20; $order = absint( $_POST['loop'] ) * $requirements_limit; // Save sequential steps (now placed on requirements UI) if( isset( $_POST['_gamipress_sequential'] ) && ! empty( $_POST['_gamipress_sequential'] ) ) { gamipress_update_post_meta( $post_id, '_gamipress_sequential', 'on' ); } else { gamipress_delete_post_meta( $post_id, '_gamipress_sequential', 'on' ); } // Only continue if we have any requirements if ( isset( $_POST['requirements'] ) && is_array( $_POST['requirements'] ) ) { // Setup an array for storing all our requirement titles // This let's us dynamically update the Label field when requirements are saved $new_titles = array(); $triggers = array(); // Loop through each of the created requirements foreach ( $_POST['requirements'] as $requirement ) { $requirement_updated = gamipress_update_requirement( $requirement, $order ); // Grab the requirement ID $requirement_id = $requirement['requirement_id']; // Add the title to our AJAX return $new_titles[$requirement_id] = stripslashes( $requirement_updated['title'] ); // Add the trigger to the triggers array if not added yet if( ! in_array( $requirement['trigger_type'], $triggers ) ) { $triggers[] = $requirement['trigger_type']; } // Update order $order++; } // Loop all saved triggers to reset their caches foreach( $triggers as $trigger ) { // Reset the trigger cache gamipress_delete_trigger_cache( $trigger ); } // Send back all our requirement titles echo json_encode( $new_titles ); } // We're done here. die; } add_action( 'wp_ajax_gamipress_update_requirements', 'gamipress_update_requirements_ajax_handler' ); /** * Save a requirement * * @since 1.4.6 * * @param array $requirement * @param int $order * * @return array The updated requirement object */ function gamipress_update_requirement( $requirement, $order = 0 ) { // Check user capabilities if( ! current_user_can( gamipress_get_manager_capability() ) ) { if( defined( 'DOING_AJAX' ) ) { wp_send_json_error( __('You are not allowed to perform this action.', 'gamipress') ); } else { return $requirement; } } // Grab all of the relevant values of that requirement $requirement_id = isset( $requirement['ID'] ) ? absint( $requirement['ID'] ) : absint( $requirement['requirement_id'] ); $requirement_type = gamipress_get_post_type( $requirement_id ); $count = ( ! empty( $requirement['count'] ) ) ? absint( $requirement['count'] ) : 1; $points_condition = ( ! empty( $requirement['points_condition'] ) ) ? sanitize_text_field( $requirement['points_condition'] ) : 'greater_or_equal'; $points_required = ( ! empty( $requirement['points_required'] ) ) ? absint( $requirement['points_required'] ) : 1; $points_type_required = ( ! empty( $requirement['points_type_required'] ) ) ? sanitize_text_field( $requirement['points_type_required'] ) : ''; $rank_type_required = ( ! empty( $requirement['rank_type_required'] ) ) ? sanitize_text_field( $requirement['rank_type_required'] ) : ''; $rank_required = ( ! empty( $requirement['rank_required'] ) ) ? absint( $requirement['rank_required'] ) : 0; $post_type_required = ( ! empty( $requirement['post_type_required'] ) ) ? sanitize_text_field( $requirement['post_type_required'] ) : ''; $user_role_required = ( ! empty( $requirement['user_role_required'] ) ) ? sanitize_text_field( $requirement['user_role_required'] ) : ''; $meta_key_required = ( ! empty( $requirement['meta_key_required'] ) ) ? sanitize_text_field( $requirement['meta_key_required'] ) : ''; $meta_value_required = ( ! empty( $requirement['meta_value_required'] ) ) ? sanitize_text_field( $requirement['meta_value_required'] ) : ''; $limit = ( ! empty( $requirement['limit'] ) ) ? absint( $requirement['limit'] ) : 1; $limit_type = ( ! empty( $requirement['limit_type'] ) ) ? sanitize_text_field( $requirement['limit_type'] ) : 'unlimited'; $optional = ( isset( $requirement['optional'] ) ) ? (bool) $requirement['optional'] : false; $url = ( ! empty( $requirement['url'] ) ) ? sanitize_url( $requirement['url'] ) : ''; $trigger_type = sanitize_text_field( $requirement['trigger_type'] ); $achievement_type = sanitize_text_field( $requirement['achievement_type'] ); // Connect the achievement with the requirement if( in_array( $trigger_type, array( 'specific-achievement', 'revoke-specific-achievement' ) ) ) { $achievement_post_id = absint( $requirement['achievement_post'] ); // Update achievement post to check it on rules engine update_post_meta( $requirement_id, '_gamipress_achievement_post', $achievement_post_id ); } // Specific activity trigger type if( in_array( $trigger_type, array_keys( gamipress_get_specific_activity_triggers() ) ) ) { $achievement_post_id = absint( $requirement['achievement_post'] ); $achievement_post_site_id = ( empty( $requirement['achievement_post_site_id'] ) ? get_current_blog_id() : absint( $requirement['achievement_post_site_id'] ) ); // Update achievement post to check it on rules engine update_post_meta( $requirement_id, '_gamipress_achievement_post', $achievement_post_id ); update_post_meta( $requirement_id, '_gamipress_achievement_post_site_id', $achievement_post_site_id ); } // Update our relevant meta update_post_meta( $requirement_id, '_gamipress_points_condition', $points_condition ); update_post_meta( $requirement_id, '_gamipress_points_required', $points_required ); update_post_meta( $requirement_id, '_gamipress_points_type_required', $points_type_required ); update_post_meta( $requirement_id, '_gamipress_rank_type_required', $rank_type_required ); update_post_meta( $requirement_id, '_gamipress_rank_required', $rank_required ); update_post_meta( $requirement_id, '_gamipress_post_type_required', $post_type_required ); update_post_meta( $requirement_id, '_gamipress_user_role_required', $user_role_required ); update_post_meta( $requirement_id, '_gamipress_meta_key_required', $meta_key_required ); update_post_meta( $requirement_id, '_gamipress_meta_value_required', $meta_value_required ); update_post_meta( $requirement_id, '_gamipress_count', $count ); update_post_meta( $requirement_id, '_gamipress_limit', $limit ); update_post_meta( $requirement_id, '_gamipress_limit_type', $limit_type ); update_post_meta( $requirement_id, '_gamipress_trigger_type', $trigger_type ); update_post_meta( $requirement_id, '_gamipress_achievement_type', $achievement_type ); update_post_meta( $requirement_id, '_gamipress_optional', ( $optional ? '1' : '0' ) ); update_post_meta( $requirement_id, '_gamipress_url', $url ); // Specific points award data if( $requirement_type === 'points-award' || $requirement_type === 'points-deduct' ) { $points = ( ! empty( $requirement['points'] ) ) ? absint( $requirement['points'] ) : 1; $points_type = ( ! empty( $requirement['points_type'] ) ) ? sanitize_text_field( $requirement['points_type'] ) : ''; $maximum_earnings = ( ! $requirement['maximum_earnings'] !== "" ) ? absint( $requirement['maximum_earnings'] ) : 1; update_post_meta( $requirement_id, '_gamipress_points', $points ); update_post_meta( $requirement_id, '_gamipress_points_type', $points_type ); update_post_meta( $requirement_id, '_gamipress_maximum_earnings', $maximum_earnings ); } // If a new meta key is in use, delete cache and rebuild it if( $meta_key_required !== '' ) { gamipress_delete_cache( 'gamipress_meta_keys_in_use' ); gamipress_get_meta_keys_in_use(); } /** * Action to store custom requirement data when saved * * @since 1.0.0 * * @param int $requirement_id * @param array $requirement */ do_action( 'gamipress_update_requirement', $requirement_id, $requirement ); if( defined( 'DOING_AJAX' ) ) { /** * Action to store custom requirement data when saved through ajax * * @since 1.0.0 * * @param int $requirement_id * @param array $requirement */ do_action( 'gamipress_ajax_update_requirement', $requirement_id, $requirement ); } // Setup a new title if no set $post_title = ! empty( $requirement['title'] ) ? sanitize_text_field( $requirement['title'] ) : gamipress_build_requirement_title( $requirement_id, $requirement ); /** * Post title filter * * @since 1.0.0 * * @param int $post_title The post title * @param int $requirement_id The requirement ID * @param array $requirement The requirement */ $post_title = apply_filters( 'gamipress_requirement_post_title', $post_title, $requirement_id, $requirement ); // Update our original post with the new title wp_update_post( array( 'ID' => $requirement_id, 'post_title' => $post_title, 'post_status' => isset( $requirement['status'] ) ? sanitize_text_field( $requirement['status'] ) : gamipress_get_post_status( $requirement_id ), 'menu_order' => absint( $order ) ) ); return gamipress_get_requirement_object( $requirement_id ); } /** * Save custom fields * * @since 1.4.6 * * @param int $post_id */ function gamipress_on_save_requirements_post_parent( $post_id ) { $post_type = gamipress_get_post_type( $post_id ); $allowed_post_types = array_merge( gamipress_get_achievement_types_slugs(), gamipress_get_rank_types_slugs() ); // Bail if not is an allowed type if( ! in_array( $post_type, $allowed_post_types ) ) { return; } if ( ! isset( $_POST['_gamipress_sequential_nonce'] ) || ! wp_verify_nonce( $_POST['_gamipress_sequential_nonce'], '_gamipress_sequential_' . $post_id ) ) { return; } // Save sequential steps (now placed on requirements UI) if( isset( $_REQUEST['_gamipress_sequential'] ) ) { gamipress_update_post_meta( $post_id, '_gamipress_sequential', 'on' ); } else { gamipress_delete_post_meta( $post_id, '_gamipress_sequential', 'on' ); } } add_action( 'save_post', 'gamipress_on_save_requirements_post_parent' ); /** * Generate a requirement title based on his configuration * * @since 1.0.5 * * @param $requirement_id integer The requirement ID * @param $requirement array The requirement array object (Optional) * * @return string */ function gamipress_build_requirement_title( $requirement_id, $requirement = array() ) { if( empty( $requirement ) ) { $requirement = gamipress_get_requirement_object( $requirement_id ); } $requirement_type = gamipress_get_post_type( $requirement_id ); $points_condition = ( ! empty( $requirement['points_condition'] ) ) ? $requirement['points_condition'] : 'greater_or_equal'; $points_required = ( ! empty( $requirement['points_required'] ) ) ? absint( $requirement['points_required'] ) : 1; $points_type_required = ( ! empty( $requirement['points_type_required'] ) ) ? $requirement['points_type_required'] : ''; $rank_type_required = ( ! empty( $requirement['rank_type_required'] ) ) ? $requirement['rank_type_required'] : ''; $rank_required = ( ! empty( $requirement['rank_required'] ) ) ? absint( $requirement['rank_required'] ) : 0; $post_type_required = ( ! empty( $requirement['post_type_required'] ) ) ? $requirement['post_type_required'] : ''; $post_types = get_post_types( array(), 'objects' ); $post_type_label = ( isset( $post_types[$post_type_required] ) ? strtolower( $post_types[$post_type_required]->labels->singular_name ) : __( 'post', 'gamipress' ) ); $user_role_required = ( ! empty( $requirement['user_role_required'] ) ) ? $requirement['user_role_required'] : ''; $roles = gamipress_get_editable_roles(); $count = ( ! empty( $requirement['count'] ) ) ? absint( $requirement['count'] ) : 1; $limit = ( ! empty( $requirement['limit'] ) ) ? absint( $requirement['limit'] ) : 1; $limit_type = ( ! empty( $requirement['limit_type'] ) ) ? $requirement['limit_type'] : 'unlimited'; $trigger_type = $requirement['trigger_type']; $achievement_type = $requirement['achievement_type']; $meta_key_required = ( isset( $requirement['meta_key_required'] ) ) ? $requirement['meta_key_required'] : ''; $meta_value_required = ( isset( $requirement['meta_value_required'] ) ) ? $requirement['meta_value_required'] : ''; // Flip between our requirement types and make an appropriate connection switch ( $trigger_type ) { // Points triggers case 'earn-points': $title = sprintf( __( 'Earn %s', 'gamipress' ), gamipress_format_points( $points_required, $points_type_required, false ) ); break; case 'points-balance': $points_conditions = gamipress_number_condition_options(); $title = sprintf( __( 'Reach a balance %s %s', 'gamipress' ), $points_conditions[$points_condition], gamipress_format_points( $points_required, $points_type_required, false ) ); break; case 'gamipress_expend_points': $title = sprintf( __( 'Expend %s', 'gamipress' ), gamipress_format_points( $points_required, $points_type_required, false ) ); break; // Rank triggers case 'earn-rank': $rank = gamipress_get_post( $rank_required ); $title = sprintf( __( 'Reach %s %s', 'gamipress' ), ( $rank ? gamipress_get_rank_type_singular( $rank->post_type, true ) : '' ), ( $rank ? $rank->post_title : '' ) ); break; case 'revoke-rank': $rank = gamipress_get_post( $rank_required ); $title = sprintf( __( 'Get %s %s revoked', 'gamipress' ), ( $rank ? gamipress_get_rank_type_singular( $rank->post_type, true ) : '' ), ( $rank ? $rank->post_title : '' ) ); break; // Achievement triggers case 'specific-achievement': $title = sprintf( __( 'Unlock "%s"', 'gamipress' ), gamipress_get_specific_activity_trigger_post_title( $requirement['achievement_post'], $trigger_type, $requirement['achievement_post_site_id'] ) ); break; case 'any-achievement': $title = sprintf( __( 'Unlock any %s', 'gamipress' ), $achievement_type ); break; case 'all-achievements': $title = sprintf( __( 'Unlock all %s', 'gamipress' ), $achievement_type ); break; case 'revoke-specific-achievement': $title = sprintf( __( 'Get "%s" revoked', 'gamipress' ), gamipress_get_specific_activity_trigger_post_title( $requirement['achievement_post'], $trigger_type, $requirement['achievement_post_site_id'] ) ); break; case 'revoke-any-achievement': $title = sprintf( __( 'Get any %s revoked', 'gamipress' ), $achievement_type ); break; // Post type triggers case 'gamipress_new_comment_post_type': $title = sprintf( __( 'Comment on a %s', 'gamipress' ), $post_type_label ); break; case 'gamipress_user_post_comment_post_type': $title = sprintf( __( 'Get a comment on a %s', 'gamipress' ), $post_type_label ); break; case 'gamipress_spam_comment_post_type': $title = sprintf( __( 'Get a comment on a %s marked as spam', 'gamipress' ), $post_type_label ); break; case 'gamipress_publish_post_type': $title = sprintf( __( 'Publish a new %s', 'gamipress' ), $post_type_label ); break; case 'gamipress_delete_post_type': $title = sprintf( __( 'Delete a %s', 'gamipress' ), $post_type_label ); break; case 'gamipress_post_type_visit': $title = sprintf( __( 'Daily visit a %s', 'gamipress' ), $post_type_label ); break; case 'gamipress_user_post_type_visit': $title = sprintf( __( 'Get visits on a %s', 'gamipress' ), $post_type_label ); break; // Role triggers case 'gamipress_add_specific_role': $title = sprintf( __( 'Get added to %s role', 'gamipress' ), translate_user_role( $roles[$user_role_required]['name'] ) ); break; case 'gamipress_set_specific_role': $title = sprintf( __( 'Get assigned to %s role', 'gamipress' ), translate_user_role( $roles[$user_role_required]['name'] ) ); break; case 'gamipress_remove_specific_role': $title = sprintf( __( 'Get removed from %s role', 'gamipress' ), translate_user_role( $roles[$user_role_required]['name'] ) ); break; // Metas case 'gamipress_update_post_meta_any_value': $title = sprintf( __( 'Update post meta %s', 'gamipress' ), $meta_key_required ); break; case 'gamipress_update_user_meta_any_value': $title = sprintf( __( 'Update user meta %s', 'gamipress' ), $meta_key_required ); break; case 'gamipress_update_post_meta_specific_value': $title = sprintf( __( 'Update post meta %s with %s', 'gamipress' ), $meta_key_required, $meta_value_required ); break; case 'gamipress_update_user_meta_specific_value': $title = sprintf( __( 'Update user meta %s with %s', 'gamipress' ), $meta_key_required, $meta_value_required ); break; // Default default: $title = gamipress_get_activity_trigger_label( $trigger_type ); break; } // Specific activity trigger type if( in_array( $trigger_type, array_keys( gamipress_get_specific_activity_triggers() ) ) ) { $achievement_post_id = absint( $requirement['achievement_post'] ); $achievement_post_site_id = absint( $requirement['achievement_post_site_id'] ); if( $achievement_post_id ) { // Filtered title $title = sprintf( gamipress_get_specific_activity_trigger_label( $trigger_type ), gamipress_get_specific_activity_trigger_post_title( $achievement_post_id, $trigger_type, $achievement_post_site_id ) ); } } // Filter to completely override activity trigger label $title = apply_filters( 'gamipress_activity_trigger_label', $title, $requirement_id, $requirement ); // Prepend "%d %s for" with the points to title if( $requirement_type === 'points-award' || $requirement_type === 'points-deduct' ) { $points = ( ! empty( $requirement['points'] ) ) ? absint( $requirement['points'] ) : 1; $points_type = ( ! empty( $requirement['points_type'] ) ) ? $requirement['points_type'] : ''; // This var is correctly set but not used to generate the title //$maximum_earnings = ( ! empty( $requirement['maximum_earnings'] ) ) ? absint( $requirement['maximum_earnings'] ) : 1; if ( $points > 0 ) { $points_title = ''; if( $requirement_type === 'points-award' ) { $points_title = sprintf( __( '%s for', 'gamipress' ), gamipress_format_points( $points, $points_type, false ) ); // 1 Points for } else if( $requirement_type === 'points-deduct' ) { $points_title = sprintf( __( '-%s for', 'gamipress' ), gamipress_format_points( $points, $points_type, false ) ); // -1 Points for } // Prepend the points title to the title $title = sprintf( __( '%1$s %2$s', 'gamipress' ), $points_title, lcfirst( $title ) ); } } // Check if trigger is excluded from activity limits if( ! in_array( $trigger_type, gamipress_get_activity_triggers_excluded_from_activity_limit() ) ) { // Add "%d time(s)" to title $title = sprintf( __( '%1$s %2$s', 'gamipress' ), $title, sprintf( _n( '%d time', '%d times', $count, 'gamipress' ), $count ) ); } // Add "(limited to %d per %s)" to title if is limited if( $limit_type !== 'unlimited' ) { $limit_type_label = ''; switch( $limit_type ) { case 'minutely': $limit_type_label = __( 'minute', 'gamipress' ); break; case 'hourly': $limit_type_label = __( 'hour', 'gamipress' ); break; case 'daily': $limit_type_label = __( 'day', 'gamipress' ); break; case 'weekly': $limit_type_label = __( 'week', 'gamipress' ); break; case 'monthly': $limit_type_label = __( 'month', 'gamipress' ); break; case 'yearly': $limit_type_label = __( 'year', 'gamipress' ); break; } $title = sprintf( __( '%1$s %2$s', 'gamipress' ), $title, sprintf( __( '(limited to %d per %s)', 'gamipress' ), $limit, $limit_type_label ) ); } $optional = ( isset( $requirement['optional'] ) ) ? (bool) $requirement['optional'] : false; if( $optional ) { $title = sprintf( __( '%1$s %2$s', 'gamipress' ), $title, __( '(Optional)', 'gamipress' ) ); } // Available hook for custom Activity Triggers return apply_filters( 'gamipress_requirement_title', $title, $requirement_id, $requirement ); } /** * Get the sort order for a given requirement * * @since 1.0.5 * @updated 1.5.1 * * @param int $requirement_id The given requirement's post ID * * @return int The requirement's sort order */ function gamipress_get_requirement_menu_order( $requirement_id = 0 ) { // If not properly upgrade to required version fallback to compatibility function if( ! is_gamipress_upgraded_to( '1.5.1' ) ) return gamipress_get_requirement_menu_order_old( $requirement_id ); return gamipress_get_post_field( 'menu_order', $requirement_id ); } /** * Helper function for comparing our requirement sort order (used in uasort() in gamipress_create_points_awards_meta_box()) * * @since 1.0.5 * @updated 1.5.1 * * @param WP_Post $requirement_x The given requirement * @param WP_Post $requirement_y The requirement we're comparing against * * @return int 0 if the order matches, -1 if it's lower, 1 if it's higher */ function gamipress_compare_requirements_order( $requirement_x, $requirement_y ) { // If not properly upgrade to required version fallback to compatibility function if( ! is_gamipress_upgraded_to( '1.5.1' ) && property_exists( $requirement_x, 'order' ) ) return gamipress_compare_requirements_order_old( $requirement_x, $requirement_y ); if ( $requirement_x->menu_order == $requirement_y->menu_order ) return 0; return ( $requirement_x->menu_order < $requirement_y->menu_order ) ? -1 : 1; }