Wordpress - s2member plugin : membership to fixed date - wordpress

I'm integrating s2member as membership plugin to an existing wordpress site.
It is easy to generate the paypal button so the user is subscribing, for exemple, for one year of membership.
Our membership will effectively be valid for one year, but from a fixed date to another fixed date.
Basically, the membership must be valid from 1st of june (2011) to may 31 (2012). The user may have from may 15 to june 15 to subscribe, but we want the membership to end on may 31, whatever is the date the membership is purchased.
Is it possible?
Thanks ;)

Yes, it is possible. From the documentation:
s2Member uses its built-in Auto-EOT System. EOT = End Of Term. Whenever you generate a PayPal® Button with s2Member, you'll configure a length for the Subscription. Depending on the type of Subscription you choose ( recurring, non-recurring, lifetime, or fixed-term ); s2Member will either use PayPal's IPN/subscr_payment,subscr_cancel,subscr_eot notices, or it will set an Automatic EOT Time, which is processed automatically by s2Member via WP_Cron. For each Member, you can also override the EOT Time, by forcing a specific expiration date. To manually adjust the EOT Time for a specific Member, go to: WordPress® -> Users, and click the Edit link next the Member you want to work on.
That said, there is likely a date field in an s2Member table that you can override with a default value of May 31. Granted, additional constraints will need to be enforced programmatically to account for the rest of your membership logic. Example:
if ( date() >= $signupStartDate and date() <= $signupEndDate ) {
processForm();
} else {
die ( "You cannot sign up right now. Try again on " . $signupStartDate . "." );
}

Related

Change 'edit account' URL in Drupal

When going to edit account or edit profile in Drupal 7, the URL looks something like http://localhost/user/123/edit where 123 is the user id. Because of this, anyone can see how many users the site has, which I don't want. Is there a way that I can change it to something like http://localhost/user/edit or something without an ID?
I've tried setting up a menu entry in my module, that acts as the edit account/profile page, but had no success.
Also, I don't want to install a new module for this, I'd rather just write my code.
In theory, you could combine the Pathauto module (the widely-used module, used on over 250,000 D6 and D7 sites, which provides URL aliases for normal node and user paths, etc) with the Sub-pathauto module (a new D7 module, currently used on only a few hundred sites). The Sub-pathauto module is the only Drupal 7 module I'm aware of which will allow you to alias the user/uid part of a user/uid/edit -type path.
On the other hand, if your goal is simply to create the illusion that you might have more than a handful of users, when launching a new Drupal site, you could simply increment the UID index by adding (then deleting) a bunch of auto-generated users (with Devel generate), or since this is an auto-increment index, you could likely manually create a user entry in the database with an index of 1507 or something, and then any entry created by Drupal after that would start at 1508, even after you've removed the dummy entry from the table. (Caveat: I've never done this, but in theory it should work.)
Hope that helps. :-)
There is already a module that allows to do what you are trying to do, but as you want to avoid installing a module, you can create a module that contains the following code:
function mymodule_url_outbound_alter(&$path, &$options, $original_path) {
if (preg_match('|^user/([0-9]+)(/.*)?|', $path, $matches)) {
if ($user = user_load($matches[1])) {
$path = 'user/' . $user->name . $matches[2];
}
}
}
function mymodule_url_inbound_alter(&$path, $original_path, $path_language) {
if (preg_match('|^user/([^/]+)(/.*)?|', $path, $matches)) {
$uid = db_query("SELECT uid FROM {users} WHERE name = :name", array(':name' => $matches[1]))->fetchField();
if ($uid) {
$path = "user/$uid" . $matches[2];
}
}
}
This code works if usernames are unique, on your site. This is what normally happens on Drupal sites, where the username is forced to be unique; if a user tried to create an account using a username that already exist, he will get an error message.
The first hook rewrite paths such as "user/100" in "user/username," and the other hook make the inverse operation. This is necessary because Drupal expects user paths in the format "user/userid" and it would not be able to handle a user path containing the username (except when you are using a path alias).
As you are said you don't like that people can know how many users your site has, there is an easier way to avoid that. The fact people know that 123 is a valid user ID, though, doesn't mean they know how many users are registered in your site: You could have 1,000 users, 140,000 users. They just know that you could have 123 users, but if you have blocked users in your site, then some of the user IDs are not usable.
Create a user account that will never be used to log in, and create content on your site.
Editing the "users" database table increase the user ID of the account you created. Supposing that its user ID is 146, increase that number of 100.
Now, the next user that will register on your site will have a user ID equal to 247.
Increase the user ID of the dummy account you created incrementing the higher user ID.
In this way, if somebody notice that there is a user account with ID equal to 247, he will wrongly suppose you have 247 users.
What I did after all, was to create a hook_user_insert and to add 2 URL aliases in the urlalias table:
user/$user->uid/edit -> user/$user->name/edit
and
user/$user->uid/edit/profile -> user/$user->name/edit/profile
Hope this helps somebody.

add expiration date to a node in Drupal

i want to add an expiration date field to my custom content type in Drupal. it should specified by days (7-15-.... days after creating node) and after it reached the node should not display in site to visitors. but i need a renew option for it to allow creator renew it and activate it again.
is it too hard to impelmentation? how can i do it?
Have you already tried searching for modules?
Here's one that might do the trick http://drupal.org/project/auto_expire. There are others as well,but maybe you should check them out to see which one fits your needs (or can be altered easily if needed).
You can use Views to do that. Make a new View, specifically for a node or more nodes of that type, and put a filter on it with "Node:Updated". Then specify how many days you need.
You can create a View for the original poster and have him update the post, which will reset the counter.
A creative solution, but it should work.
Take a look at Node expire which sets up timers for nodes based on Rules. For a simpler approach, Scheduler can do it to. Both are linked from the Auto Expire module linked by wimvds, so there is some measure of duplication, though they do seem to have different approaches.
The following code may be of interest. It's a small snippet from a module i've had to create to auto expire adverts on an intranet site. The nodes simply unpublish after a number of days you specify in the code so could be hidden from your site and then the author of the content could simply just re -publish the nodes if they needed to.
/**
* Implementation of hook_cron().
*/
function auto_unpublish_pages_cron() {
//we only want to deal with all blog_post content type nodes
$c_type = 'blog_post';
//grab all nodes
$c_nodes = node_load_multiple(array(), array('type' => $c_type));
//setup time stamp for node expiry
$message_search_data = strtotime('- 7 days');
//now loop through nodes, & if they are old, expire them
foreach ($c_nodes as $m) {
$obj = entity_metadata_wrapper('node', $m);
//check when was last updated and if its still published
$last_update = $obj->changed->value();
$published = $obj->status->value();
//if it's still published & it's not recent, unpublish it
if (($message_search_date > $last_update) && $published<>0) {
$obj->status = 0;
$obj->save();
}
}
}

Drupal module to control user post frequency?

We've been having a new type of spam-bot this week at PortableApps.com which posts at a rate of about 10 comments a minute and doesn't seem to stop - at least the first hour or so (we've always stopped it within that time so far). We've had them about a dozen times in the last week - sometimes stopping it at 50 or 60, sometimes up to 250 or 300. We're working to stop it and other spam bots as much as possible, but at the moment it's still a real pest.
I was wondering whether in the mean time whether there's any sort of module to control the frequency a user can post at to e.g. 50 an hour or something like 10 in an hour for new users. That at least would mean that instead of having to clear up 300 comments 50 at a time in admin/content/comment we'd have a smaller number to clear. (A module to add a page to delete all content by a user and block them would also be helpful!)
I believe that there's a plugin to do this available for WordPress, but can't find any such thing for Drupal.
For your second question, i would have a look at the code of the User Delete module (click).
The module also disables the user account and unpublished all nodes/comments from a certain user. By extending the code, you could easily create another possibility to unpublish + delete all nodes/comments from a certain user and blocking the account.
After the unpublish code in the module, you should just put delete code (in sql if the module is selecting by a sql-query or by using the drupal delete functions).
Another option would be so make a view (using the view module) only to be viewed by administrators, where you choose a certain user using the filters and then lists his/her posts. Then in the node-contenttype.tpl.php you place a button that calls a function which deletes all nodes/comments and the user.
First problem (post frequency)
I've been thinking about the comment post limit. If I remember correctly Drupal stores comments in a seperate table and has comment specific functions.
I'd create a new module and using the comment_nodeapi function i would check in the operation 'insert' how much comments the current user has already made within a certain timeframe.
To check this I would write a custom sql query on the database which takes the count of alle comments made by uid where the post_date is larger then NOW-1hour. If that count is larger then 10 or 15 or whatever post frequency you want then you give a message back to the user. You can retrieve the user id and name by using the global $user variable.
(example: print $user->name;)
You have to check on your own for the sql query but here's some code when you have the amount:
<?php
function comment_nodeapi(&$node, $op, $arg = 0) {
switch ($op) {
case 'insert':
//PLACE HERE THE SQL TO GET THE COUNT
if($count > 15){
$repeat = FALSE;
$type = 'status'
drupal_set_message("You have reached the comment limit for this time.", $type, $repeat);
break;
}else{
db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->changed, $node->uid);
break;
}
}
}
?>
(this code has not been tested so no guarantees, but this should put you on the right track)
I would suggest something like Mollom (from the creator of Drupal). It scans the message for known spam pattern/keywords/... and if this scan fails, it displays a CAPTCHA to the user to make sure that it's a real human that wants to enter content that has the same properties like spam.
They offer a free service and some paid solutions. We are using it for some customers and it's worth the money. It also integrates very well in Drupal.
Comment Limit is probably what you need.
http://drupal.org/project/spam
http://drupal.org/project/antispam - with akismet support

I want to port my delicious bookmarks to my website

I started building a app that will automatically download my delicious bookmarks, and save to a database, so they I can view them on my own website in my favoured format.
I am forced to use oAuth, as I have a yahoo id to login to delicious. The problem is I am stuck at the point where oAuth requires a user to manually go and authenticate.
Is there a code/ guidelines available anywhere I can follow? All I want is a way to automatically save my bookmarks to my database.
Any help is appreciated. I can work on java, .net and php. Thanks.
Delicious Provides an API for this already:
https://api.del.icio.us/v1/posts/all?
Returns all posts. Please use sparingly. Call the update function to see if you need to fetch this at all.
Arguments
&tag={TAG}
(optional) Filter by this tag.
&start={#}
(optional) Start returning posts this many results into the set.
&results={#}
(optional) Return this many results.
&fromdt={CCYY-MM-DDThh:mm:ssZ}
(optional) Filter for posts on this date or later
&todt={CCYY-MM-DDThh:mm:ssZ}
(optional) Filter for posts on this date or earlier
&meta=yes
(optional) Include change detection signatures on each item in a 'meta' attribute. Clients wishing to maintain a synchronized local store of bookmarks should retain the value of this attribute - its value will change when any significant field of the bookmark changes.
Example
$ curl https://user:passwd#api.del.icio.us/v1/posts/all
<posts tag="" user="user">
<post href="http://www.weather.com/" description="weather.com"
hash="6cfedbe75f413c56b6ce79e6fa102aba" tag="weather reference"
time="2005-11-29T20:30:47Z" />
...
<post href="http://www.nytimes.com/"
description="The New York Times - Breaking News, World News & Multimedia"
extended="requires login" hash="ca1e6357399774951eed4628d69eb84b"
tag="news media" time="2005-11-29T20:30:05Z" />
</posts>
There are also public and private RSS feeds for bookmarks, so if you can read and parse XML you don't necessarily need to use the API.
Note however that if you registered with Delicious after December, and therefore use your Yahoo account, the above will not work and you'll need to use OAuth.
There are a number of full examples on the Delicious support site, see for example: http://support.delicious.com/forum/comments.php?DiscussionID=3698

How does one associate Google Analytics with a particular authenticated user?

What method would you use to associate tracking information in Google Analytics with a particular named user?
I want to be able to do custom reports, and ultimately drill down on usage by user.
EDIT
I was thinking that perhaps the EventTracking API would be able to help somehow.
Also, referring to this documentation.
You could add the user's username as a tracking/segmentation) variable...
pageTracker._setVar(username);
You can only use one _setVar per page, though...
http://www.google.com/support/analytics/bin/answer.py?answer=57045
http://groups.google.com/group/analytics-help-basics/browse_thread/thread/07e29dc610050971
Since Google Analytics isn't aware of users who are logged into your site you'd have to do that sort of tracking within your site's software itself. If there isn't some sort of plugin or extension out there already you'll probably have to write one yourself that keeps track of what your users do when their logged in.
I think you want Google Analytics - Custom Variables. You can set five variables per page, and there is support for variables you set persisting over session and cookie (aka "visitor") lifetime. Take note of the rules for overwriting previous values based upon slot and scope; the documentation explains this with some examples. You should probably include something in a click-wrapped privacy policy about tracking individual users this way; it's somewhat invasive, depending on the purpose of your website.
_gaq.push(['_setCustomVar',
1, // Slot number: [1-5], inclusive. Required.
'Username', // Custom variable name. Required.
username, // Custom variable value. Required.
2 // Scope:
// 1 = visitor/cookie-level, 2 = session-level, 3 = page-level.
// Optional, default=3.
]);
http://www.highlyrelevant.com/2011/03/25/how-to-add-edit-google-analytics-users-to-your-account/
This post was really helpful for me and my team. Not only does it show how to add users, but it also tells you how to edit existing users that aren't setup correctly.
Thanks!
Phil

Resources