I have a social networking site built on a PHP framework. I'm using a plugin to award members points when they update their profile. Right now, whenever a member clicks on 'Save' it triggers the profileupdate event, and that event triggers the points being awarded. But, even if the profile fields are all empty, the event is still triggered and they still get points… so, my clever users are gaming the system to get points without really updating their profile :\
I want to add a function that checks that the profile fields aren't empty -- or, ideally, checks that a significant amount of changes have been made to at least 1 of the profile fields, but I'm not sure how to do that.
I'm still pretty new to PHP (about 1 year experience), so if anyone could help both with explaining what the checking process should be and the specifics on the code to execute the checking function, I'd really appreciate it!
Here are the current events and functions:
When the owner of the page clicks on 'Save', this is the event in the core of the PHP framework that gets triggered to notify the user of the update:
$owner->save();
trigger_event('profileupdate', $owner->type, $owner);
system_message(echo("profile:saved"));
This is the function in the points plugin that checks to see if the plugin is configured to award points based on a profile update, and then calls the points_add function to add points to the user:
function points_profile($event, $type, $object) {
if ($points = get_plugin_setting('profileupdate')) {
if (function_exists('points_add')) {
points_add(get_logged_in_user_guid(), $points, $event, $type, $object->entity_guid);
}
}
return(true);
}
This is an example of how the individual profile fields are defined/labelled -- ie, "admin_defined_profile_1"
if (save_config("admin_defined_profile_$id", $label) &&
save_config("admin_defined_profile_type_$id", $type) &&
save_config('profile_custom_fields', $fieldlist))
look on rowcount() http://www.php.net/manual/en/pdostatement.rowcount.php
it will -on single UPDATE -return 1 if anything was actually changed and 0 if nothing was changed.
Related
I need to show something only to users with active subscriptions, im using the edd recurring payments plugin, I found this is their docs
$subscriber->has_active_subscription()
But im not sure how to make use of it to show something only to users with active subscriptions.
So i will be adding this code in my archive.php file and show extra php code for active users.
that code you found is part of the OOP class used by Easy Digital Downloads. Their docs are here: https://docs.easydigitaldownloads.com/article/1160-recurring-payments-developer-eddrecurringsubscriber
What you'd need to do is something like:
$my_user = get_current_user_id(); //grab current user
$subscriber = new EDD_Recurring_Subscriber( $my_user, true ); //pass user id to EDD class
//The EDD class will return its own user object, and on that you can do your check from the question:
if ($subscriber->has_active_subscription()) {
echo 'some special message for users with subscriptions';
} else {
//do something else
}
Watch out though, because that method will return true both if user has an active subscription and if he/she has a cancelled subscription (but false if subscription has expired). That may or may not be what you want.
I don't have EDD so haven't tested this but I hope it at least gets you started.
So I'm using the SwipeStripe module as an ecommerce shop, and having issues logging member details as customer details. I'll outline the process and what i've tried so far.
I am currently logged in as a member of my website.
I can view, and add products to my cart.
When I reach the checkout page, it asks me to register my details (become a member).
I have gone through the Customer.php, and OrderForm.php files. What I have discovered is:
Customer::currentUser() is not recognising me as a logged in user.
When I print Member::currentUser() it can see I am a logged in, registered member and I can print the details of that record.
Customer::currentUser() is as follows in the Customer.php file:
static function currentUser() {
$id = Member::currentUserID();
if($id) {
return DataObject::get_one("Customer", "\"Member\".\"ID\" = $id");
}
}
I was wondering if anyone could help me understand why Customer::currentUser() isn't recognising me as a logged in user?
Also, in the OrderForm.php, when I change the validation for the "register as a member" form fields (the function is called 'createFields') to Member::currentUserID() it recognises that I'm logged in and skips that section. It's only when it goes to save my order and customer details to the customer DB table, that it can't retrieve my email address.
I know this is an old post, but I've used this code/method all the way up to SS 3.4.
You will need to update Aram's code to work with SS 3.x.x
https://www.silverstripe.org/community/forums/e-commerce-modules/show/21390
-helenclarko
I would like to create a button that can be used to populate a table in my db with a single click.
I am just not sure what I need to do here to make this happen. Can I assign a method to be executed by a button? Or just have values picked up in my controller? Below is something like what I want to execute but through a button.
public function addInterest($interest)
{
$interest->UserId=Yii::app()->user->id;
$interest->ItemId=$this->ItemId;
return $interest->save();
}
**Additional details in response to Jaison Justus
With this implementation I am using controller and view from Model A (ItemId) where the button is to be displayed. Then there is Model B (UserId). Taking the info from Model A (ItemId) and Model B (UserId) I want to populate Model C ($interest) with that ItemId and UserId upon clicking a button. Looks like CJuiButton might provide a means to build it from being as then I can disable/hide the button after selected once. I am just not familiar with using buttons other than on a form where user input in collected, as links, or to provide pop up messages.
The code above currently sits in Model A model. With the code below in Model A controller everything works to populate Model C if I use a form and collect input. Since I do not require any input other then selecting the button from the user the form has nothing to put into it and therefore I know I can not use if(isset($_POST['Interest'])) as I have below.
public function actionView($id) {
$items=$this->loadModel($id);
$interest=$this->newInterest($items);
$this->render('view', array(
'model' => $items,
'interest' => $interest,
));
}
protected function newInterest($items)
{
$interest=new Interest;
if(isset($_POST['Interest']))
{
$interest->attributes=$_POST['interest'];
if($items->addInterest($interest))
$this->refresh();
}
return $interest;
}
In response to VarioN
Here is an attempt at using ajax. However this does not work and gives an Error 500 when ran. Is my controller action appropriate for what I am trying to do here?
Controller
public function actionAddInterest() {
$connection = yii::app()->db;
$sql1 = "INSERT INTO interest (UserId, ItemId)
VALUES(".Yii::app()->user->id.",".$this->ItemId.")";
$connection->createCommand($sql1)->execute();
}
View
<?php
echo CHtml::ajaxLink(
'Add Interest',
array('/item/addInterest'),
array('update'=>'#req_res')
);
?>
Looking at your question I see that you don't understand how MVC in Yii works.
Look at this 15 minutes screencast (Yii Tour - 3rd Stop - CRUD County) and after you will be able to create such button in any way you need (try use Gii and than customize it in your way - it's the easiest way).
Updated:
Seems that you need AJAX request. You can add CHtml::ajaxButton() in your view.
It will work this way:
User push the button, button do request (with JavaScript) to your
site without reloading the page and invisible for user.
Your controller action will serve this request: it can make some things (for ex., save data to db) and output data that your JavaScript possibly will display to user.
Than your JavaScript get answer and can make some changes on the page
(for example, hide button or show text got from request).
You can look at simple example with ajax here
If you needn't to submit form info with your button you can user ajaxLink. Example for it is here
There are a lot of examples with ajax and yii in the internet and at yii forum. Try to find them it may be very helpful.
Ask questions if you would have any.
Second update:
First, try to do your sql query simplier:
"INSERT INTO interest (UserId, ItemId) VALUES (1, 2)"
Than enable logging of mysql queries to log: at config/main.php add "trace" to "levels"
'components'=>array(
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CFileLogRoute',
'levels'=>'error, warning, trace',
),
Now you can try to press an AJAX link and look at the protected/runtime/log.txt and determine the problem.
Additional info to AJAX requests
All that outputs your ajax scripts can be viewed by browser's features:
At Chrome: press F12, go to Network, press an ajax-link and look at request response.
At Firefox with addon "Firebug".
With this you can determine whether a request is done or not.
I implement the example from facebook credits, and create an test app, added the callback.php in the Callback Url, place my keys correctly. but I get this error:
Sorry, but we're having trouble processing your payment. You have not been charged for this transaction. Please try again.
I am trying to create a few buttons with different monetary values. Like:
Click to get 100 credits
Click to get 1000 credits
If I use this generic code, I get the payment window just fine, but I can't see my products there, I can only choose from already made presets :
function buyMore(){
// calling the API ...
var obj = {
app_id: 'xxxxxxxxxxxxxxxxxxxxx',
method: 'pay',
order_info: n,
purchase_type: 'item',
credits_purchase: true
};
to show the user my monetary presets I think I need to pass different values to the function:
<p><a onclick="buyMore('100'); return false;">Buy More Credits 100</a></p>
<p><a onclick="buyMore('1000'); return false;">Buy More Credits 1000</a></p>
function buyMore(price) {
var order_info = {
"title":'title',
"description":'description',
"price":price,
"image_url":'http://....img_url',
"product_url":'http://....product_url'
};
// calling the API ...
var obj = {
app_id: '153230661424821',
method: 'pay',
order_info: order_info,
purchase_type: 'item'
};
}
Not sure if I got it right.
Can anyone push me in the right direction?
Yeah, you'll have to have your users select the item they want to purchase, which will then call the buyMore function to have them confirm their purchase via the Credits dialog (like you're doing in your second example).
First thing I'd do is check my Credits setting in the Developer app though. I've gotten that error before on a new app before realizing I'd forgotten to set my credits callback URL or set my user as a Credits test user.
Why are you asking the user to buy a set number of credits?
Surely it's an easier flow if you ask the user to buy an item (priced in credits) and Facebook handles the step of the user buying the necessary credits themselves?
Going a bit mad here... :)
I'm just trying to add CCK fields from a Content Profile content type into page-user.tpl.php (I'm creating a highly-themed user profile page).
There seem to be two methods, both of which have a unique disadvantage that I can't seem to overcome:
'$content profile' method.
$var = $content_profile->get_variables('profile');
print $var['field_last_name'][0]['safe'];
This is great, except I can't seem to pass the currently viewed user into $content_profile, and it therefore always shows the logged in user.
'$content profile load' method.
$account_id = arg(1);
$account = user_load($account_id);
$user_id = $account->uid;
$var = content_profile_load('profile', $user_id);
print $var->field_first_name[0]['value'];
Fine, but now I can't access the full rendered fields, only the plain values (i.e. if the field has paragraphs they won't show up).
How can I have both things at once? In other words how can I show fields relating to the currently viewed user that are also rendered (the 'safe' format in 1)?
I've Googled and Googled and I just end up going round in circles. :(
Cheers,
James
Your content profile load method seems to be the closest to what you want.
In your example:
$account_id = arg(1);
$account = user_load($account_id);
$user_id = $account->uid;
$var = content_profile_load('profile', $user_id);
print $var->field_first_name[0]['value'];
The $var is just a node object. You can get the "full rendered fields" in a number of ways (assuming you mean your field with a filter applied).
The most important thing to check is that you're field is actually configured properly.
Go to:
admin/content/node-type/[node-type]/fields/field_[field-name] to configure your field and make sure that under text processing that you've got "Filtered text" selected.
If that doesn't fix it,try applying this:
content_view_field(content_fields("field_last_name"), $var, FALSE, FALSE)
(more info on this here: http://www.trevorsimonton.com/blog/cck-field-render-node-formatter-format-output-print-echo )
in place of this:
print $var->field_first_name[0]['value'];
if none of that helps... try out some of the things i've got on my blog about this very problem:
http://www.trevorsimonton.com/blog/print-filtered-text-body-input-format-text-processing-node-template-field-php-drupal
When you're creating a user profile page there is a built in mechanism for it. just create a user template file, user_profile.tpl.php.
When you use the built in mechanism you automatically get access to the $account object of the user you are browsing, including all user profile cck fields. You have the fields you are looking for without having to programmatically load the user.
I have a field called profile_bio and am able to spit out any mark up that is in without ever having to ask for the $account.
<?php if ($account->content[Profile][profile_bio]['#value']) print "<h3>Bio</h3>".$account->content[Profile][profile_bio]['#value']; ?>
I've tried themeing content profiles by displaying profile node fields through the userpage before and it always seems a little "hacky" to me. What I've grown quite fond of is simply going to the content profile settings page for that node type and setting the display to "Display the full content". This is fine and dandy except for the stupid markup like the node type name that content profile injects.
a solution for that is to add a preprocess function for the content profile template. one that will unset the $title and remove the node-type name that appears on the profile normally.
function mymodule_preprocess_content_profile_display_view(&$variables) {
if ($variables['type'] == 'nodetypename') {
unset($variables['title']);
}
}
A function similar to this should do the trick. Now to theme user profiles you can simply theme your profile nodes as normal.