• Resolved jasonkadlec

    (@jasonkadlec)


    I LOVE the ability require X out of X of Achievement Type as a way to unlock a badge.

    Here’s a little scenario I’m running up against though– appreciate your helping think of a better solution?

    Reward
    Badge
    Thing

    You must earn Things to get Badges, Many Badges will get your Reward… pretty standard.

    Here is where I’m getting in trouble:

    I want the following badges:

    Lesson 1, Lesson 2, Lesson 3 and so forth.

    So Lesson 1 will require Thing 1, Thing 2, Thing 3, Thing 4.

    Lesson 2 will require Thing 5, Thing 6, Thing 7, Thing 8.

    One solution is — in order to get the Lesson 1 Badge, you must complete Things 1-4.

    But what I want is, in order to get the Lesson 1 Badge, you must complete at least 3 of Things 1-4.

    So with the existing setup, I’d need to create the following Achievement Types:

    Lesson 1 Things

    Lesson 2 Things

    Lesson 3 Things ….

    So the issue with that is… this course has 22 lessons.

    Annnd it’s not the only course that would use Badge OS.

    Annnd “Things” are really all the same… it’s the taxonomy of Lesson 1, Lesson 2 etc that is different.

    I wish I could require 3 of 4 [ Achievement Type ] with this [Taxonomy].

    Otherwise… for every lesson of every course, I’ll have to create a new “Thing” achievement type?

    At what point will that create insane queries / slow down WordPress?

    Is there any issue with having 100 or even 200 Achievement types?

    Certainly it’s going to get unwieldy in the admin UI?

    https://www.ads-software.com/plugins/badgeos/

Viewing 9 replies - 1 through 9 (of 9 total)
  • Michael Beckwith

    (@tw2113)

    The BenchPresser

    It’s not a complete answer, but I think the filter at the end of the function highlighted at https://github.com/opencredit/badgeos/blob/master/includes/rules-engine.php#L42:L83 may be of interest to you.

    You can hook into the filter, and do some extra checks, and if the users doesn’t meet your needs above, you can have it return false until they do. As an example, the function right after it uses the filter in a similar way.

    Thread Starter jasonkadlec

    (@jasonkadlec)

    Interesting — can you confirm 1 thing and then let me know if you’d consider the 2nd:

    1st:

    I can create a new function – like the points — that says if the achievement type is required steps — then get the total number of steps, and if the user has at least total number -1, then achieve the award.

    This would mean that 3 out of 4 steps, 9 out of 10 steps etc would always get the badge… but I’d always be locked into Total – 1.

    2nd:

    Would you consider making it a feature so that when “required steps” is chosen, that we can also set in that screen the number of those specific steps would be required to earn the Achievement?

    OR

    Can you point me towards how I could add in such an additional field so it surfaces in the admin, but only when the user as selected Requires Steps – so it loads with the rest of that UI where they select the steps.

    And/or — I suppose I could use the Custom Fields / Types style plugin (or write into functions) to add a custom field to the created Achievement Post Type and then go looking for a value in that field instead of just the Total – 1 idea above…

    OK that’s what I’m going to do for now… but I think it would be a super useful feature to allow the require at least _____ steps to be available in BOTH the way it is now (require ____ number of steps of (select achievement type).

    AND also when setting a “Require Steps” — make it so that it either requires all the steps, or allows the end user to specify how may of those steps specified would be required to earn the achievement.

    Thanks for considering.

    Thanks for answering so fast!

    Thanks for answering with useful link straight to the thing I need.

    YO. You da man.

    Michael Beckwith

    (@tw2113)

    The BenchPresser

    My thoughts were that with that filter, you could check the completion of other achievements that you specify, before saying “yes, this user deserves this one”. It’d require your own querying of achievements, which are all post types. You’d want to check which achievements are being awarded so that you’re only doing this for ones that need the other achievements too. It’d be very specific to the current setup, and have no UI, so there would be some limitations, but it’d be possible. It’s also possible to create your own UI for this spot, for what it’s worth.

    For the 2nd part, we’d need to think about it, and see if we could do it without breaking anything. It probably wouldn’t be right away, but we’d make a GitHub issue for the enhancement.

    We use CMB at the moment for our metaboxes, but I have strong desire to get it updated to CMB2, which WebDevStudios maintains. What we use now is no longer maintained as well, so there’s more incentive. In case you need it: https://github.com/WebDevStudios/Custom-Metaboxes-and-Fields-for-WordPress/

    Thread Starter jasonkadlec

    (@jasonkadlec)

    I’m a bit confused as to how function badgeos_user_deserves_step works?

    It seems like that’s the thing I need to emulate/filter?

    I successfully got a custom field added to the Achievement so I can set my “step override.”

    Again – here is what I’m looking to do:

    I have an Achievement that is earned by completing steps:

    https://cl.ly/image/3F3E0H0Y1V2O

    I’ve created 3 such steps, of specific Achievement Type, and then selected the specific Achievement within that type:

    https://cl.ly/image/3e2z1b423u0n

    I now have a custom field added to the Achievement (the main one, that has the required steps):

    https://cl.ly/image/1y313y45291H

    Just to see if I could understand what does what… I tried this:

    function badgeos_user_deserves_step( $return = false, $user_id = 0, $step_id = 0 ) {
    
    	// Only override the $return data if we're working on a step
    	if ( 'step' == get_post_type( $step_id ) ) {
    
    		if (!empty(get_post_meta( $step_id, 'wpcf-how-many-steps', true ))) {
    			$minimum_activity_count = absint( get_post_meta( $step_id, 'wpcf-how-many-steps', true ) );
    			} else {
    				$minimum_activity_count = absint( get_post_meta( $step_id, '_badgeos_count', true ) );
    			}
    
    		// Grab the relevent activity for this step
    		$relevant_count = absint( badgeos_get_step_activity_count( $user_id, $step_id ) );
    
    		// If we meet or exceed the required number of checkins, they deserve the step
    		if ( $relevant_count >= $minimum_activity_count )
    			$return = true;
    		else
    			$return = false;
    	}
    
    	return $return;
    }
    add_filter( 'user_deserves_achievement', 'badgeos_user_deserves_step', 10, 3 );

    — meaning I directly edited rules-engine.php at line 401.

    Where wpcf-how-many-steps — is my custom field… I even just tried hard setting

    $minimum_activity_count = 2;

    Just to see if that is what is being checked… and it doesn’t appear to be the thing.

    So need your help a little bit more…

    It seems like if the Achievement is set to “require steps” — this is the only rule in the rules-engine.php that would seem to apply?

    It looks like this rule calls the function badgeos_get_step_activity_count at the bottom there… which is where we total up how many steps for that achievement have been awarded?

    Do these functions only pertain to steps that are the default WordPress kind of steps?

    Thanks for your help! I’d love to get this to work and then you could check it into a future update ha ha!

    Michael Beckwith

    (@tw2113)

    The BenchPresser

    First I’d recommend against editing the rules-engine.php file directly. You should be able to remove that filter highlighted above and re-add your own version.

    The only way I can really see this failing at the moment is if the user hasn’t completed the steps enough times yet, though I don’t know what you’re using to test it. To help, it may not be the worst idea to call the function directly with hardcoded values and check the return values.

    Not sure what you mean by “default WordPress kind of steps” to be honest, as steps are specific to BadgeOS in this case, and are their own private post type used to help tie everything together.

    Thread Starter jasonkadlec

    (@jasonkadlec)

    Of course – I’d not leave edits in rules-engine.php, I’m just trying to figure out what does what.

    By default WordPress, I meant things like leaving a comment, logging in vs. specific achievements.

    I wouldn’t need to check how many times a step is required… what I want is as simple as:

    Trigger = Achievement has been Awarded… OK so look and see if that Achievement was a required Step of some other Achievement.

    If it was, go see what other steps that Achievement has, and also see if there is a number set in that Achievement’s custom posts.

    So let’s say that I was just awarded the Achievement “Thing One.”

    Thing One is a required step of the Achievement “Lesson 1.” Lesson 1 also has steps Thing 2 and Thing 3, Thing 4 and has that custom field value set at 3.

    Now look at the User’s Achievements — look for Thing 2, Thing 3, Thing 4 in the achievements awarded so far, and count up how many were found.

    Compare the Count with the custom field value.

    If the count is equal to or greater than the value of the custom field, then Award the Achievement Lesson 1.

    … Thus overriding the default behavior which requires that the user must have ALL the steps Thing 1, Thing 2, Thing 3 and Thing 4 in order to earn the Lesson 1 badge.

    So it is just a matter of figuring out:

    How do I figure out if an Achievement is a required step of another Achievement?

    How do I figure out all the required steps of a given Achievement, and further more get the ID’s of the actual Achievements that are the steps.

    Sounds like Steps are a private post type serving as a linking table between Achievements.

    Anything I’m not understanding that would prevent what I’ve sketched out from working?

    Michael Beckwith

    (@tw2113)

    The BenchPresser

    Gotcha, things done related to WP core.

    BadgeOS does use posts-2-posts to help with tying everything together.

    the includes/achievement-functions.php file would be a good one to look through as well, as it may yield functions I’m forgetting about and could prove useful.

    For example, both of these may be good: badgeos_get_parent_of_achievement( $achievement_id ) and badgeos_get_children_of_achievement( $achievement_id )

    Hook into the approriate hook from above, for when “Thing 1” is triggered. Use that with badgeos_get_parent_of_achievement to fetch “Lesson 1”. Use the info from “Lesson 1” with badgeos_get_children_of_achievement as necessary, probably with relation to checking the user’s earned steps. Compare found results to the minimal required total.

    My long story short is that the data is there, just a matter of figuring out how to tie it all together, and I’m sure you’re aware of that too. I just haven’t had to do this type of customization work at all, so I’m trying to figure it out with you. (I’m not the original developer of the plugin, fwiw).

    Thread Starter jasonkadlec

    (@jasonkadlec)

    Michael:

    Thanks! It’s a huge time saver when someone who knows the plugin better can point the way to useful functions.

    With badgeos_get_children_of_achievement and badgeos_get_parent_of_achievement, I think I can turn the sketch into code and make it work.

    Michael Beckwith

    (@tw2113)

    The BenchPresser

    Shouldn’t be that outdated, but we have https://badgeos.org/api/ available if you don’t want to open the files themselves directly.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Achievement Categories / How to solve this req. ?’ is closed to new replies.