• Skip to primary navigation
  • Skip to main content
  • Skip to footer
  • Store
  • Support
  • Theme Documentation
  • My Account
  • Cart

9seeds

Building Custom WordPress Solutions | Plugin Development

 
  • Custom Development
  • Themes
  • Plugins
  • About
  • Contact
  • Blog

Case Study

Case Study: Gamifying PeepSo for a Growing Member Community

Posted on March 13, 2019

While requests for community websites and gamification are fairly common, building a fully integrated custom game within communities is much less so — and we love an interesting project. That’s why, when Intergalactic Postal Service approached 9seeds to create a game within their online community sidebar on a tight timeline, we excitedly responded, “game on”.

IPS is building a cool themed community, and wanted to debut the new social-integrated game at an upcoming comic book convention to their loyal members. Since the delivery deadline was two weeks away, we needed to find the most efficient combination of technology to accomplish the task.

Luckily, IPS was using PeepSo, an easily extensible member community plugin for WordPress that we often recommend. While it has a smaller user base than BuddyPress, it’s a more tightly integrated package and more full featured out of the box. This was going to be the first time we added gamification to PeepSo though.

The game build

The build for this social-enabled game was fairly straightforward from a standalone standpoint, the interesting part was integrating it seamlessly into the PeepSo community.

General requirements

  • The game is turn-based.
  • Activities must happen asynchronously.
  • The game must work within the PeepSo sidebar as a widget.
  • Players are notified about activities within the game via the PeepSo notification system.

Gameplay

  • A player initiates an action and other players are able to interact with the player based on that action.
  • A master dispatcher announces each interaction to the PeepSo activity stream.
  • Non-player characters occasionally interact with real players when site activity is down.
  • Master dispatch user is able to actively interact with the live chat plugin to let a player know directly when something happened to them (as well as who was responsible) to allow for swift counter-action.

Building the integration

PeepSo has a slick, JavaScript-heavy user interface. In order to seamlessly integrate with the technology and UX of the site, the game would also need to load and run using the same JavaScript framework and interactivity. That meant adding custom JavaScript using standard WordPress methods; and Ajax calls to the backend for the widget.

Within the PeepSo profile area, there’s a PeepSo-specific widget area that only PeepSo widgets work within, and it deviates a bit from how widgets normally work within WordPress. PeepSo support was great at providing code examples to help implement the widget, and in turn the game into a PeepSo widget.

Once the widget shell was added, game was coded, and notifications integration was planned out, it was time to start hooking into the site’s social features.

Hooking into PeepSo

To get the system messages into the community timeline, we used a helper function to interact with PeepSo:

public static function peepso( $owner, $user, $msg ) {
 $activity = PeepSoActivity::get_instance();
 $result = $activity->add_post( $owner, $user, $msg );
}

Next we built the private chat between Game Master and user:

$model = new PeepSoMessagesModel();
$msg_id = $model->create_new_conversation($gm, $msg, '', array($pm,$userid));

The final step before client testing was to add a public audit log (or leaderboard with stats) to encourage deeper engagement. We made quick work of adding a new tab in the PeepSo user profile area along with companion visibility and permissions options in the PeepSo administration console.

Game On

And just like that, it was time to test the game mechanics, display, UX, and messaging hooks.

What we had originally thought might be an extremely involved project was made easier by some excellent integration framework and support from the PeepSo team.

Have an interesting PeepSo integration project you’d love to get started on? Get in touch and let us know how we can help!

Continue Reading

Todd Huish

    More by Todd Huish
    Adjusting Code Increases MemberPress Value

    Using MemberPress to Get that Magazine Feeling

    Posted on November 6, 2017

    Our customers come up with the best ways to use software sometimes. I recently had to have my eyes opened to the fact that just because we are in a digital age doesn’t mean we have to abandon all the old tools available to us.

    Let’s say you want to do a magazine style site where monthly content is given to subscribers. A standard way of implementing this with membership software is to charge for a monthly subscription which gives you access to everything, Then if you cancel, you lose access to the site. In one respect this model gives people the incentive to remain a customer but in another sense, it’s not exactly fair.

    • If a customer paid for a subscription and received 3 “issues” why wouldn’t they retain access to that over time?
    • Another thing to think about is that if you are expecting your customers to pay monthly, you have to keep the prices low enough such that they don’t notice it on the bill. This is how Time gets away with it at just $2.50/mo. That’s low enough to just pay forever without worrying about it and having access to (quick google search) 93 years worth of back-issues.
    • If you want to charge a higher subscription rate you have to offer a little more and one of those things can be the fact that they get to retain access to issues they were subscribed.

    So… how to implement this? Without code there really isn’t a way to accomplish this. The reality is it completely breaks the concept of a membership site to allow people access to premium content after they are no longer a member.

    MemberPress developers to the rescue.

    MemberPress recently implemented a rule which allows for this exact scenario. At its simplest form it states, “Even though you have access to this resource, I’m going to deny you anyway.” The way we correct this is to simply not protect the magazine issues and instead write a little snippet of code which asks, “This issue was published on March 9th, does the user attempting to access this issue have a transaction for March 9th?”

    With the chunk of code below we check and make sure they have a transaction covering the time period they’re trying to access. If they do, we allow them to see what they’ve already purchased.

    We love taking awesome products like MemberPress and tweaking them to provide the exact functionality our clients desire. If you have a WordPress or MemberPress customization project, please get in touch:

    Get in Touch with 9seeds

    add_filter('mepr-last-chance-to-block-content', 'deny_selective_access_9s');
    function deny_selective_access_9s($deny,$current_post,$uri) {
        //short circuit if it's not even a magazine issue post type
        if($current_post->post_type != 'magazine-issue')
            return $deny;
    
        //if there isn't even a user block access. We don't want to do a lot of 
        //work looking up transactions if they aren't even logged in
        $user = new MeprUser(get_current_user_ID());
        if(!$user->ID)
            return true;
    
        //add a custom where to get transactions by user by date
        add_filter('mepr_transaction_get_complete_by_user_id_custom_where', 'deny_selective_access_where_9s');
        
        $num = get_all_complete_by_user_id( $user->ID,
            '', //order by
            '', //limit 
            true, //count only
            true, //include expired
            false, //include confirmations
            true //include custom where
        )
        
        //do not leave this filter lying around to confuse other parts of the memberpress software
        remove_filter('mepr_transaction_get_complete_by_user_id_custom_where', 'deny_selective_access_where_9s');
    
        if(!$num)
            $deny = true;
    
        return $deny;
    }
    function deny_selective_access_where_9s($where,$user_id){
        global $post,$wpdb;
          $where .= $wpdb->prepare(
            'AND %s > t.created_at  AND %s < t.expires_at ', $post->post_date,
            $post->post_date
          );
        return $where
    }
    
    Continue Reading

    Todd Huish

      More by Todd Huish

      Using Memberpress to Convert Free Users to Paid

      Posted on January 10, 2017

      MemberPress is a great WordPress membership plugin that lets you create rules to protect your content and sell subscriptions to access that content. Making customized exceptions to those rules though has long been a bit challenging even for WordPress developers.
      Thanks to filters added in the latest version of MemberPress however it’s now much easier to customize MemberPress rules! We did that for a client recently.

      Having a Successful Membership Site

      A client came to us with an existing site that had a lot of content generated over time and building a sizable list of registered users. They wanted to augment their free subscription model with selling memberships to access some of that same content.

      MemberPress was built for this kind of scenario!  They installed the plugin and had already set up the following tags and MemberPress rules:

      1. Made a whole library of premium posts
      2. Tagged posts appropriately: Beginner, Intermediate, and Advanced
      3. Created 3 paid membership levels in MemberPress (Beginner for $5/mo, Intermediate for $7/mo, and Advanced for $10/mo)
      4. Set up 3 MemberPress rules to:
        • Protect all content tagged Beginner and allow Advanced, Intermediate, and Beginner memberships to access it
        • Protect all content tagged Intermediate and allow Advanced, and Intermediate memberships to access it
        • Protect all content tagged Advanced and allow Advanced memberships to access it

      With the exception of creating the content, it’s a very straightforward setup, each membership level can access all the content for their subscription level and below.

      Converting Existing Users to Paid Users

      It’s easy to direct traffic to your sales page and to get first-time site visitors to signup for something free, but what about getting all the existing free registered users to sign up for a paid membership?

      It’s also becoming common practice to build semi-permeable content gateways where a visitor can access a little content for free with or without registering but then getting locked out from viewing more content until they subscribe.

      There’s no way in MemberPress at the moment to allow limited access to some things if they don’t have a MemberPress membership of some sort though. MemberPress recently added a new hook in their WordPress plugin, however that helps with this exact scenario.

      What this hook allows is for a site owner to do is send an email to all their currently registered users and say “Hey, we have all this new premium content, you should buy it but as a long time registered user we’re going to give you unrestricted access to a premium lesson so you can try it out”.

      By setting this up in code and allowing an existing user to get access it works out better because there’s no friction to the customer. You lose a certain percentage of people for every click you make them do to get a thing so by handling it this way it just appears to work magically as far as the customer is concerned. Another way to solve this would be to make a new membership and only allow existing members to sign up for it.

      We discussed this with the client but they wanted to offer their existing base access to any single lesson they wanted. By creating a membership and then putting in a rule it would either overly give these users access to the entire library or you would have to pick a single lesson to showcase as the “free” premium one.

      Custom Code for MemberPress

      All of the non-code ideas were a compromise and so we went with the original plan and put in the following snippet for them.

      add_filter('mepr-pre-run-rule-content', 'allow_premium_access_9s' ,10,3);
      function allow_premium_access_9s( $protect, $current_post, $uri ) {
          $user = new MeprUser(get_current_user_ID());
          $prd = get_page_by_title('Premium Membership', OBJECT, MeprProduct::$cpt);
          //make sure we have a user and the premium membership lookup succeeded
          if($prd->ID && $user->ID) {
              //if the user isn't already a premium member
              if(!$user->is_already_subscribed_to($prd->ID)) {
                  $promo_access = get_user_meta($user->ID,'promo_access',true);
                  if(!$promo_access) {
                      //if the user does not already have promo access to a lesson
                      //allow them in to this one
                      update_user_meta($user->ID,'promo_access',array('lesson'=>$current_post->ID,'expiration'=>strtotime("+1 month")));
                      $protect = false;
                  } elseif($promo_access['lesson'] == $current_post->ID && $promo_access['expiration'] > time()) {
                      //The user has previously chosen this to be their promo lesson and
                      //their special access is not expired
                      $protect = false;
                  }
              }
          }
          return $protect;
      }
      

      The thing about this rule is that it allows for some sneaky special things anytime you are running a promotion. Another good example is allowing access to a protected post if there’s a special code on the URL. Put that URL code right into your Facebook ad’s target URL and have someone get to see premium content for 1 click. Then when they go off the page you let the unauthorized message do its job and upsell them to membership status.

      With the new MemberPress customizations, you can now selectively grant access to protected parts of your site without making complicated interlocking sets of rules for promotional items which sometimes live and die within days.

      Continue Reading

      Todd Huish

        More by Todd Huish

        Extending The Functionality of MemberPress

        Posted on July 7, 2015

         

         

        memberpress_mod

        There are a number of well established commercial WordPress plugins that provide an almost perfect solution out of the box for our customers. These plugins are big part of what makes WordPress a great and affordable solution for so many websites. Often however, a business needs something “just a little custom”. Where a full custom solution might be tens of thousands of dollars in development, a $100 plugin and a few hours of custom development can deliver a similar highly tailored solution. This recently completed project extending MemberPress is a great example.

        Unique Client Needs

        A client using MemberPress came to us wanting to offer their members the ability to purchase a gift membership for someone else as well as a way to set up and manage a very customized 40 day email drip program.

        Taking Something Good And Making It Better

        We love working with the MemberPress plugin. It’s robust and can meet the needs of many membership sites. However, each business is unique in the services it delivers to it’s customers and sometimes delivering those services requires extending the functionality provided by a plugin.

        Implementing the gift memberships was more challenging than it sounds. The existing coupon functionality in MemberPress assumes that a site administrator would simply create a coupon code for use by many users. We started with this and extended it such that users could purchase a 100% coupon and that coupon could be sent to someone as a gift. The final tweak was to make it so these coupon codes were one-time use only.

        The 40 day drip program took people through a series of daily questions about each day’s lesson. MemberPress tracks progress through the drip program but doesn’t allow users to go back and repeat the program. We created a plugin that allowed users to reset the program to day 1 and wiped out all of their previous answers so they could start the process anew.

        Both add-ons work independently of one another giving the site owner flexibility in which add-on functionality is active at any given time.

        Customized Solutions

        There are countless amazing plugins out there that do a massive range of things for a specific need. When you need something a little different the most affordable solution may be to extend one of those existing plugins to fit your particular need. Contact us. We’ll create the perfect plugin add-on for you!

        Continue Reading

        elena

          More by elena

          Footer

          Get in Touch

          • New Project Inquiry
          • Product Support and General Inquiry
          • Store Purchase Terms and Conditions
          • Store FAQ
          • Cookie Policy
          • Privacy Policy

          Our Services

          • Custom WP Development
          • Theme Store
          • Plugin Store

          WordPress Plugins for Sale

          • Time Tracker
          • Authorize.net SIM Gateway

          WordPress Plugins for Free

          • Simple Calendar
          • WP Chargify
          • Facebook
          • Twitter
          • LinkedIn
          • WordPress
          • GitHub

          Copyright 2025 | 9seeds, LLC

          Like nearly all websites this one uses cookies too. Like most users we think consent banners like these are a dumb solution, but it's what we've got until new laws are passed. We use cookies on our website for remembering your preferences, for example if you're logged in or what is in your cart. We also use 3rd party cookies for analytics so we know what pages on the site are most popular. By clicking “Accept”, you consent to the use of ALL the cookies.
          Do not sell my personal information.
          Cookie SettingsAccept
          Manage consent

          Privacy Overview

          This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience and may even preclude you being able to login to the website.
          Necessary
          Always Enabled
          Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
          CookieDurationDescription
          __stripe_mid1 yearThis cookie is set by Stripe payment gateway. This cookie is used to enable payment on the website without storing any patment information on a server.
          __stripe_sid30 minutesThis cookie is set by Stripe payment gateway. This cookie is used to enable payment on the website without storing any patment information on a server.
          cookielawinfo-checkbox-advertisement1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Advertisement" category .
          cookielawinfo-checkbox-analytics1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Analytics" category .
          cookielawinfo-checkbox-necessary1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to record the user consent for the cookies in the "Necessary" category .
          cookielawinfo-checkbox-others1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to store the user consent for cookies in the category "Others".
          cookielawinfo-checkbox-performance1 yearSet by the GDPR Cookie Consent plugin, this cookie is used to store the user consent for cookies in the category "Performance".
          Functional
          Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
          Performance
          Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
          Analytics
          Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
          CookieDurationDescription
          _ga2 yearsThe _ga cookie, installed by Google Analytics, calculates visitor, session and campaign data and also keeps track of site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognize unique visitors.
          _gid1 dayInstalled by Google Analytics, _gid cookie stores information on how visitors use a website, while also creating an analytics report of the website's performance. Some of the data that are collected include the number of visitors, their source, and the pages they visit anonymously.
          CONSENT2 yearsYouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data.
          Advertisement
          Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
          CookieDurationDescription
          VISITOR_INFO1_LIVE5 months 27 daysA cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
          YSCsessionYSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
          yt-remote-connected-devicesneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
          yt-remote-device-idneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
          Others
          Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
          CookieDurationDescription
          cookielawinfo-checkbox-functional1 yearThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
          SAVE & ACCEPT
          Powered by CookieYes Logo