Community Support Forums — WordPress® ( Users Helping Users ) — 2011-10-12T02:06:49-05:00 http://www.primothemes.com/forums/feed.php?f=4&t=1633 2011-10-12T02:06:49-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=46655#p46655 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
smitchell360 wrote:
Indeed. I plan to clean everything up (and will post the plugin) once I get my entire flow working. I have this odd infinite loop after getting a successful payment notification from the PayPal sandbox account.


smitchell, did you ever finalize this? Would be awesome for me.

Thanks,

Kenny

Statistics: Posted by kennymcnett — October 12th, 2011, 2:06 am


]]>
2011-01-19T17:49:31-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5812#p5812 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>

Statistics: Posted by Cristián Lávaque — January 19th, 2011, 5:49 pm


]]>
2011-01-18T19:11:44-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5759#p5759 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]> ... but very good point.

Statistics: Posted by smitchell360 — January 18th, 2011, 7:11 pm


]]>
2011-01-18T19:10:58-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5758#p5758 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]> Statistics: Posted by smitchell360 — January 18th, 2011, 7:10 pm


]]>
2011-01-18T19:09:56-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5757#p5757 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]> Statistics: Posted by smitchell360 — January 18th, 2011, 7:09 pm


]]>
2011-01-18T15:02:35-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5745#p5745 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Code:
<?php
function capability_dated
($capability, $beg_time, $end_time)
{
    echo base64_encode($capability . ',' . $capability . '_beg' . date('Ymd', strtotime($beg_time)) .  'end' . date('Ymd', strtotime($end_time)));
}
?>


And then used like

Code:
<input type="hidden" name="item_number" value="1:<?php capability_dated('take_grc_professional_exam', 'now', '+1 week'); ?>" />

Statistics: Posted by Cristián Lávaque — January 18th, 2011, 3:02 pm


]]>
2011-01-18T13:16:41-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5735#p5735 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
That works, but since it's not obfuscated, you could have someone edit the times in the form and submit one which gives him a longer range, right? They could probably even find all the custom capabilities you used in other buttons and add them all to a single purchase. :?

You could probably pass them as a variable that's unreadable or looks like something else, but gets turned back into the capabilities after the registration, but before saving it in the database. Probably using base64_encode and base64_decode...

Code:
<?php
$capability 
= 'take_grc_professional_exam';
$beg_time = 'now';
$end_time = '+1 week';

$capability = base64_encode($capability . ',' . $capability . '_beg' . date('Ymd', strtotime($beg_time)) .  'end' . date('Ymd', strtotime($end_time)));

echo '<input type="hidden" name="item_number" value="1:' , $capability , '" />';
?>


Now, someone with PHP knowledge may try base64-decoding that string, but that'd be a small number of people, if any. If you want to make it harder to break, you could add a salt.

Statistics: Posted by Cristián Lávaque — January 18th, 2011, 1:16 pm


]]>
2011-01-18T12:33:07-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5732#p5732 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Doesn't that fix the time ranges for you, though, since to change them you'd have to edit the code or the member's account after creation?

Statistics: Posted by Cristián Lávaque — January 18th, 2011, 12:33 pm


]]>
2011-01-18T11:21:11-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5730#p5730 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Code:
$beg_date = strtotime ("now");
$end_date = strtotime ("+1 week");

$beg_date_string = date ( "Ymd", $beg_date );
$end_date_string = date ( "Ymd", $end_date );

$custom_capabilities_string = "take_grc_professional_exam,take_grc_professional_exam_beg" . $beg_date_string . "_end" . $end_date_string;


Then add this string to the PayPal form (I'm putting the actual form code on the page instead of the S2 shortcode)

Code:
<input type="hidden" name="item_number" value="1:<?php echo $custom_capabilities_string; ?>" />

Statistics: Posted by smitchell360 — January 18th, 2011, 11:21 am


]]>
2011-01-15T15:27:38-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5631#p5631 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]> Statistics: Posted by smitchell360 — January 15th, 2011, 3:27 pm


]]>
2011-01-15T13:47:28-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5628#p5628 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
smitchell360 wrote:
strtotime did not convert 20110101.


That's odd. I tried this

Code:
<?php echo strtotime('20110101'); ?>


and it outputs 1293861600.

smitchell360 wrote:
The main reason that I add the "beg" and "end" is that I want the information stored to be a bit more readable.

The custom capabilities cannot contain "-". They use "_" or alphanumeric.


Got it. Then my regex I think would be

Code:
'~_beg(\d{8})_end(\d{8})$~'


Using the prefixes, you don't even need the underscore between the dates, e.g. capabilityname_beg20110112end20110211.


I wanted to ask you something: the capability with the dates is added to each member, right? How does the script determine the beg/end dates of the capability? You must tell s2Member somewhere that the capability starts after n days and ends after n days, right? Where does this happen?

smitchell360 wrote:
To make this even more robust, we should probably add functions that return the correct PayPal button string based on:

- custom_capability
- start_date
- end_date

I'll work on that today. Unless you have some time...


I'll let you do it. I'm actually not that good writing new code, am better working with existing one.


Back to what I ask above, what'd happen if you add a start_date and end_date to the button and the person who visits the registration page with that button leaves that browser window/tab open for a couple of days before purchasing, then the dates would be wrong.

I think it should be start_time and end_time in days. That could be saved that way and the dates calculated when needed, or calculate the dates right after the order is complete and stored as dates.

Maybe capabilities with time triggers could have the times in days for begins and ends as part of the name, e.g. capabilityname_beg30end365. Then the calculated dates could be added to that right after purchase, e.g. capabilityname_beg30end365_beg20110214end20120213. It'd be easy to tell them apart.

Statistics: Posted by Cristián Lávaque — January 15th, 2011, 1:47 pm


]]>
2011-01-15T12:26:53-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5625#p5625 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
- custom_capability
- start_date
- end_date

I'll work on that today. Unless you have some time...

Statistics: Posted by smitchell360 — January 15th, 2011, 12:26 pm


]]>
2011-01-15T12:25:22-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5624#p5624 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
The main reason that I add the "beg" and "end" is that I want the information stored to be a bit more readable.

The custom capabilities cannot contain "-". They use "_" or alphanumeric.

strtotime did not convert 20110101. It requires it to be formatted a bit more. As such, I need to do some formatting ... and adding the "beg" and "end" will probably help another developer down the road.

Statistics: Posted by smitchell360 — January 15th, 2011, 12:25 pm


]]>
2011-01-14T22:04:00-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5594#p5594 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Code:
<?php

foreach 
($user->allcaps as $single_capability => $single_capability_value){

    $cap_to_process = $single_capability;
    //error_log("capability to process: " . print_r($cap_to_process, TRUE), 0);

    $end_date = null;
    $start_date = null;
    $capability = null;

    // parse the capability

    // get and trim off end date
    if ( preg_match($end_date_regex, $cap_to_process, $end_date_string_array) ) {

        //error_log("getting end_date: " . $end_date_string_array[0] . " from: " . print_r($cap_to_process, TRUE), 0);

        $end_date = grccertify_string_to_date( $end_date_string_array[0] );
        //error_log("end_date: " . print_r($end_date, TRUE), 0);

        //error_log("trimming end_date from: " . print_r($cap_to_process, TRUE), 0);
        $cap_to_process = str_replace ("_" . $end_date_string_array[0], "", $cap_to_process);
        //error_log("end_date trimmed and capability string is now: " . print_r($cap_to_process, TRUE), 0);
    }

    // get and trim off start date
    if ( preg_match($start_date_regex, $cap_to_process, $start_date_string_array) ) {

        //error_log("getting start_date: " . $start_date_string_array[0] . " from: " . print_r($cap_to_process, TRUE), 0);
        $start_date = grccertify_string_to_date( $start_date_string_array[0] );
        //error_log("start_date: " . print_r($start_date, TRUE), 0);

        //error_log("trimming start_date from: " . print_r($cap_to_process, TRUE), 0);
        $cap_to_process = str_replace ("_" . $start_date_string_array[0] , "", $cap_to_process);
        //error_log("start_date trimmed and capability string is now: " . print_r($cap_to_process, TRUE), 0);
    }

    // you are left with just the capability
    $capability = $cap_to_process;
 


like this

Code:
<?php

foreach ($user->allcaps as $capability => $v){

    
// Parse the capability.
    
if (preg_match('~_(\d{8}?)-(\d{8}?)$~'$capability$matches)){
        
$end_date = empty($matches[1]) ? null strtotime($matches[1]);
        
$start_date = empty($matches[2]) ? null strtotime($matches[2]);
        
$capability str_replace($matches[0] , ''$capability);
    }
 


I used the date format without the prefixes for the regex, and didn't add the error log stuff cause I'm not sure how to do it. I didn't test it at all, so forgive me if I messed it up somewhere. :roll:

Statistics: Posted by Cristián Lávaque — January 14th, 2011, 10:04 pm


]]>
2011-01-14T20:34:47-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5592#p5592 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
http://mx.php.net/manual/en/datetime.formats.date.php

Statistics: Posted by Cristián Lávaque — January 14th, 2011, 8:34 pm


]]>
2011-01-14T20:15:02-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5591#p5591 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Code:
[code=php]Lorem <?php echo 'Ipsum'; ?>[/code]


I think it's great that you started working on the code to add this functionality and are sharing it with us. Thanks! :)

I'll give the code a closer look later, but first a couple comments on what you said in the opening post.

I think that you could dispense with the "beg" and "end" prefixes, just having the dates would be enough since the position relative to the hyphen would indicate which is which, like this:

..._yyyymmdd-yyyymmdd
..._yyyymmdd-
..._-yyyymmdd


The regex would be simple (although you can also explode the string first with the underscore and then the hyphen).

Code:
   $start_date_regex = "~_(\d{8})-~";
   $end_date_regex = "~-(\d{8})$~";


How are these dates calculated? Do you enter them by hand or are they calculated by the plugin adding a certain number of days to the date the ccap was given to the member?

Statistics: Posted by Cristián Lávaque — January 14th, 2011, 8:15 pm


]]>
2011-01-14T18:12:19-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5587#p5587 <![CDATA[Re: "Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Here is the code (no idea how to get syntax highlighting turned on for this). It is REALLY rough but should be a good start for many of you. Please keep this thread going with comments so that we can shore up this functionality in all of our sites.

Code:

function grccertify_check_for_expired_capabilities($siteuser = NULL)
{
   date_default_timezone_set("America/Phoenix");
   $start_date_regex = "/beg[0-9]+/i";
   $end_date_regex = "/end[0-9]+/i";
   $allusers = NULL;
   
   if ($siteuser == NULL) {
   
      // check all users
      $allusers = get_users_of_blog();
      //error_log("all users of the blog: " . print_r($allusers, TRUE), 0);
            
      if ($allusers) {
      
         foreach ($allusers as $singleuser) {
            
            error_log("processing user: " . $singleuser->ID, 0);
            $user = new WP_User( $singleuser->ID );
            //error_log("all user info: " . print_r($user, TRUE), 0);
            //error_log(" -- allcaps: " . print_r($user->allcaps, TRUE), 0);
            
            // check the list for any timed capabilities in the form:
            // capability_name_begyyymmdd_endyyymmdd
            if ($user->allcaps) {
            
               foreach ($user->allcaps as $single_capability => $single_capability_value){
                  
                  $cap_to_process = $single_capability;
                  //error_log("capability to process: " . print_r($cap_to_process, TRUE), 0);
                  
                  $end_date = null;
                  $start_date = null;
                  $capability = null;
                  
                  // parse the capability
                                 
                  // get and trim off end date
                  if ( preg_match($end_date_regex, $cap_to_process, $end_date_string_array) ) {
                  
                     //error_log("getting end_date: " . $end_date_string_array[0] . " from: " . print_r($cap_to_process, TRUE), 0);
                     
                     $end_date = grccertify_string_to_date( $end_date_string_array[0] );
                     //error_log("end_date: " . print_r($end_date, TRUE), 0);
                     
                     //error_log("trimming end_date from: " . print_r($cap_to_process, TRUE), 0);
                     $cap_to_process = str_replace ("_" . $end_date_string_array[0], "", $cap_to_process);
                     //error_log("end_date trimmed and capability string is now: " . print_r($cap_to_process, TRUE), 0);
                  }
                  
                  // get and trim off start date
                  if ( preg_match($start_date_regex, $cap_to_process, $start_date_string_array) ) {
                  
                     //error_log("getting start_date: " . $start_date_string_array[0] . " from: " . print_r($cap_to_process, TRUE), 0);
                     $start_date = grccertify_string_to_date( $start_date_string_array[0] );
                     //error_log("start_date: " . print_r($start_date, TRUE), 0);
                     
                     //error_log("trimming start_date from: " . print_r($cap_to_process, TRUE), 0);
                     $cap_to_process = str_replace ("_" . $start_date_string_array[0] , "", $cap_to_process);
                     //error_log("start_date trimmed and capability string is now: " . print_r($cap_to_process, TRUE), 0);
                  }   

                  // you are left with just the capability
                  $capability = $cap_to_process;
                  
                  if ( $start_date || $end_date ) {
                  
                     //error_log("capability to add or remove is: " . print_r($capability, TRUE), 0);
                     //error_log("start_date is: " . $start_date, 0);
                     //error_log("end_date is: " . $end_date, 0);
                     //error_log("now is: " . strtotime ("now"), 0);
                     
               
                     // ensure that the capability_name is removed if the start-end range is not met
                     if ( strtotime ("now") > $end_date )
                     {
                        error_log("AFTER END DATE. Removing capability: " . print_r($capability, TRUE) . " from user ID: " . print_r($user->ID, TRUE), 0);
                        $user->remove_cap ($capability);         
                     }
                     
                     if ( strtotime ("now") < $start_date )
                     {
                        error_log("BEFORE START DATE. Removing capability: " . print_r($capability, TRUE) . " from user ID: " . print_r($user->ID, TRUE), 0);
                        $user->remove_cap ($capability);         
                     }                     
                     
                     // ensure that the capability_name is present if the start-end range is met
                     if ( (strtotime ("now") >= $start_date) && ($end_date == null) )
                     {
                        error_log("MET START DATE and NO END DATE. Adding capability: " . print_r($capability, TRUE) . " to user ID: " . print_r($user->ID, TRUE), 0);
                        $user->add_cap ($capability);
                     }
                     if ( (strtotime ("now") >= $start_date) && (strtotime ("now") <= $end_date) )
                     {
                        error_log("BETWEEN START DATE AND END DATE. Adding capability: " . print_r($capability, TRUE) . " to user ID: " . print_r($user->ID, TRUE), 0);
                        $user->add_cap ($capability);
                     }   
                     if ( (strtotime ("now") <= $end_date) && ($start_date == null) )
                     {
                        error_log("NO START DATE AND BEFORE END DATE. Adding capability: " . print_r($capability, TRUE) . " to user ID: " . print_r($user->ID, TRUE), 0);
                        $user->add_cap ($capability);
                     }                        
                  
                  }
                  else {
                     // this is not a timed capability, do nothing
                     error_log("capability is not timed: " . print_r($capability, TRUE), 0);
                  }
               }
            }
            else {
               error_log("no capabilities found for user:" . print_r($user->ID, TRUE), 0);
            }
         }
      }
   }
   else {
   
      // TODO: just check a single user
      // TODO: make subfunction below
   }   
}


function grccertify_string_to_date ( $date_as_string ) {

   //error_log("converting string: " . print_r($date_as_string, TRUE), 0);
   $year = substr($date_as_string, 3, 4);
   $month = substr($date_as_string, 7, 2);
   $day = substr($date_as_string, 9, 2);
   
   //create a date
   $date_to_return = strtotime( $year . "-" . $month . "-" . $day );
   //error_log("date to return: " . print_r($date_to_return, TRUE), 0);
   
   return $date_to_return;
}

Statistics: Posted by smitchell360 — January 14th, 2011, 6:12 pm


]]>
2011-01-14T18:08:18-05:00 http://www.primothemes.com/forums/viewtopic.php?t=1633&p=5585#p5585 <![CDATA["Timed" Custom Capabilities (Jason Please Help Finalize)]]>
Given a custom capability of: custom_timed_cap

When you initially provision the capability, always create TWO entries for the custom capability:
- custom_timed_cap
- custom_timed_cap_beg20110101_end20110201

this means that the capability should begin on 2011-Jan-01 and end on 2001-Feb-01

What my code does is, every night (or every hour or every 5 minutes) loops through your users, grabs all capabilities, looks for "timed" capabilities and adds/removes the capability as indicated.

What is important (to me) is that the "custom_timed_cap_beg20110101_end20110201" is NEVER removed. This way, I have a record of every custom capability that was provisioned.

I only use "custom_timed_cap" to determine if someone can access content.

Make sense?

Hopefully Jason will chime in on this.

Statistics: Posted by smitchell360 — January 14th, 2011, 6:08 pm


]]>