Can't update subscriber information Aweber API PHP - php

I'm trying to update Aweber subscriber information, specifically the custom fields and I'm using Aweber API but it's not working and probably I'm not writing correctly the code:
require_once('../AweberAPI/aweber_api/aweber_api.php');
include("../config.php");
$email=$_POST["email"];
$threefears=$_POST["3fears"];
$handlefears=$_POST["handlefears"];
$threeactions=$_POST["3actions"];
$changelife=$_POST["changelife"];
$consumerKey = '';
$consumerSecret = '';
$accessKey = '***'; # put your credentials here
$accessSecret = '***'; # put your credentials here
$account_id = ''; # put the Account ID here
$list_id = ''; # put the List ID here
$aweber = new AWeberAPI($consumerKey, $consumerSecret);
try {
$custom_field->name = 'Favorite Color';
$custom_field->save();
$params = array('email' => '$email');
$found_subscribers = $account->findSubscribers($params);
foreach($found_subscribers as $subscriber) {
$subscriber->custom_fields = array(
'Top 3 biggest fears related to dating' => '$threefears',
'How would the person you most admire handle these fears' => '$handlefears',
'What are 3 actions you can take today to act more like the person you most admire' => '$threeactions',
'How will taking these actions change your attitude towards dating and your life' => '$changelife',
);
$subscriber->save();
}
}

The custom fields you are submitting must already exist on your list before you can submit them via the API. This can be done within your aweber control panel using this process: https://help.aweber.com/hc/en-us/articles/204027516-How-Do-I-Create-Custom-Fields-
So if you created a custom field named 'age' then your code would look something like this (assuming an existing $subscriber object):
$fields = array(
'age' => '21',
);
$subscriber->custom_fields = $fields;
$subscriber->save();
or
$subscriber['custom_fields']['age'] = '21';
$subscriber->save();

I guess that instead of writing the values you are writing $threefears, $handlefears etc as text.
In your example you are putting variables as '$variable' instead of just $variable. That would write variable name instead of variable content.
so, instead of
$subscriber->custom_fields = array(
'Top 3 biggest fears related to dating' => '$threefears',
'How would the person you most admire handle these fears' => '$handlefears',
'What are 3 actions you can take today to act more like the person you most admire' => '$threeactions',
'How will taking these actions change your attitude towards dating and your life' => '$changelife',
);
try
$subscriber->custom_fields = array(
'Top 3 biggest fears related to dating' => $threefears,
'How would the person you most admire handle these fears' => $handlefears,
'What are 3 actions you can take today to act more like the person you most admire' => $threeactions,
'How will taking these actions change your attitude towards dating and your life' => $changelife
);
Note that even stackoverflow is correctly hightlighting variable names now.
And for Pete's sake, make the custom field's names shorter :) Most certainly there is a limit on the post you can make. Having such long variable name makes for less space in variable value, per post.
Oh and delete
$custom_field->name = 'Favorite Color';
$custom_field->save();
And modify from
$params = array('email' => '$email');
to
$params = array('email' => $email);
or to
$params = array('email' => $email, 'status' => 'subscribed');

It is correct that the custom fields you are submitting must already exist on your list before you can submit them via the API. This can be done within your aweber control panel using this process: https://help.aweber.com/hc/en-us/articles/204027516-How-Do-I-Create-Custom-Fields-
after creating a custom field named 'age' , the php code will be like this
$fields = array(
'age' => '21',
);
$subscriber->custom_fields = $fields;
$subscriber->save();

Related

How to return a variable operator like $option[];

Obviously, I can't do this, but is there some way to achieve what I am trying to? I only found can not do's online, but no potential workarounds.
Here is what I am trying to do.
Currently I get the following error... "Cannot use [] for reading"
For my theme, I have a framework and the fields from that framework are built using an array that I create.
It looks something like this (minus the 300+ lines of code that I actually use)...
$options[] =
array(
'title' => 'This Field Tab Title',
'name' => 'this-field-tab-slug',
'fields' =>
array(
// ----------------------------------------------------------------------
// This Field Option Name
// ----------------------------------------------------------------------
array(
'type' => 'this_field_type',
'id' => 'this_field_types_id',
),
// ----------------------------------------------------------------------
// This Field Option Name
// ----------------------------------------------------------------------
array(
'type' => 'this_field_type',
'id' => 'this_field_types_id',
),
// ----------------------------------------------------------------------
// This Field Option Name
// ----------------------------------------------------------------------
array(
'type' => 'this_field_type',
'id' => 'this_field_types_id',
),
),
);
I am running a grouped field type, so my output has many options/fields within this grouped field/area which can then be added again and again as many times as the user needs. Then I am repeating that whole process/code again but for other taxonomies of the user's site.
So for example, the whole process above applies to post types, categories, tags, archived, etc. etc. So instead of having thousands of lines of repetitive codes, I'm trying to create my own function and pass the variables to that function.
But for the function, I find I can't return $options[];
Here is a screenshot of what I mean by the grouped field that can be added as many times as the user needs.
And here's an example of the function I am trying to create!
public static function layout_settings_config($title_name = '', $title_slug = '', $title_id = '', $query = '') {
$title_name = 'Post Type';
$title_slug = 'post-type';
$title_id = 'post_type';
$query = 'post_types';
$options[] =
array(
// all the config array codes in here...
);
return $options ??? $options[]; doesn't work.
}
Is this possible to achieve what I am trying to a different way? I'm still a little new to creating my own functions and OOP, but nothing I find online for this specific issue with a workaround.
Thanks!
$options[] is not object but it is an operation like function.
You should return $options instead.
and, by the way, when you say $options[] = something. it actually insert something inside an array called $option. so effectively you have to access your options like this.
$option[0]->title.
So I suggest Instead of making it complex like this. simply say
$option = something.

Quantity not appearing on invoice created by WHMCS

I am trying to place an order via WHMCS API on my local environment. This is my order code,
$postfields["action"] = "addorder";
$postfields["clientid"] = "104";
$postfields["billingcycle"] = "monthly";
$postfields["pid"] = "55";
$postfields['configoptions'] = base64_encode(serialize(array(1 => 3)));
$postfields["regperiod"] = "5";
$postfields["paymentmethod"] = "paypal";
It is listed on the API doc that 'configoptions',
$postfields['configoptions'] = base64_encode(serialize(array(1 => 3)));
^ is for changing the order quantity and other options(first element is for the quantity). Problem is that the invoice generated by WHMCS only contains quantity as 1 and not 3.
---------------------------------------------------------Edit 1 ------------------------------------------------------------------
I have looked into the product configurations, "Tick this box to allow customers to specify if they want more than 1 of this item when ordering" option is ticked as well!
A bit late to the game but oh well.
In the current WHMCS API documentation for the AddOrder function I have not been able to find anything regarding quantity, I have a feeling that at this point that simply enables an input in the order form and WHMCS handles that input somehow.
I did find a way that might work for you though. Im not sure how you are actually using the API if it's driven by some custom form somewhere or what but you can do the following.
in lieu of:$postfields['configoptions'] = base64_encode(serialize(array(1 => 3))); which doesn't seem to work you can just use the 'pid' field to specify the quantity, something like this:
$quantity = trim(str_repeat("{$pid},", $_POST['qty']), ',');
$postfields["pid"] = $quantity;
Simply repeating the product ID as many times as desired sets the quantity, you can do basically the same thing using the local API function, see below:
$quantity = array_fill(0, $_POST['qty'], $pid);
$command = 'AddOrder';
$postData = array(
'clientid' => '1',
'pid' => $quantity,
'domain' => array('example.com'),
'billingcycle' => array('monthly'),
'paymentmethod' => 'PayPal',
);
The result of the above code will be a single order with however many products ($pid) were specified in $_POST['qty']

CakePHP - SQL query Join

Ok, so i'm in a pickle trying to figure a way for how to do this :
I have a live search(using ajax) which allows the user to select a criteria from a dropdown list and then enter a value which will be matched to values inside the database. This is quite trivial stuff, and on direct fields of the main model, i don't have any issues.
I have a Donor Model/table which consists of attributes such as ID, Name, Surname etc, but more importantly it also has FK of other associated models such as blood_group_id, donor_type_id, which map back to the respective models (BloodGroup and DonorType).. These two are already set with the associations and I am beyond that part, as I am already retrieving Donor records with associated model data.
Here is the search method which will hopefully help you in understanding my problem better.
public function search() {
if($this->request->is('post')){
if(!empty($this->request->data)){
$criteria = $this->request->data['criteria'];
$query = $this->request->data['query'];
$conditions = array("Donor." .$criteria. " LIKE '". $query . "%'");
The above checks if its a post request and whether data was sent. The criteria and user input are used to construct the query..
This is where my problem arises.. (When the user select search By blood type, as a criteria from the drop down)the above expects the user to enter the id of the blood_group rather than A+ or A- for instance.. So if the input is 1(id of blood group A+), the results are returned as expected. But I want the user to be able to enter A+...
Here is the rest of the method :
$this->Paginator->settings = array(
'conditions' => $conditions,
'limit' => 2
);
$donors = $this->Paginator->paginate('Donor');
$this->set('donors', $donors);
$this->beforeRender();
$this->layout= 'ajax';
}
}
}
I have tried this approach, setting up the conditions using the Model's name such as
if($criteria == 'blood_group_id'){
$conditions = array("BloodGroup.id" . " LIKE '". $query . "%'");
}elseif($criteria == 'donor_type_id'){
$conditions = array("DonorType.id" . " LIKE '". $query . "%'");
}else{
$this->Paginator->settings = array(
'conditions' => $conditions,
'limit' => 2
);
}
But this returns all the records irrespective of the input.
I also tried changing the settings for the paginator with no luck
$settings = array(
'joins' => array(
'table' => 'blood_groups',
'alias' => 'BloodGroup',
'type' => 'LEFT',
'conditions' => array(
"BloodGroup.id" => "Donor.blood_group_id",
"AND" => $conditions
)
),
'limit'=> 2
);
Any help on how to accomplish what I explained above, would greatly be appreciated!
simply:
if($criteria == 'blood_group_id')
$conditions = array("BloodGroup.name LIKE" => $query.'%');
(assuming bood_types has a 'name' column)
Also let me suggest you to use the CakeDC search plugin (https://github.com/CakeDC/search).

Using the CakeDC search plugin with associated models

I'm using CakePHP 1.3.8, and I've installed the CakeDC Search plugin. I have a Tutorial model, which is in a HABTM relationship with a LearningGoal model.
I have a search action & view in the Tutorials controller with which I can successfully search fields in the Tutorial model. I'd also like to filter my tutorial search results using LearningGoal checkboxes on the same form. I've tried adding various parameters to Tutorial's $filterArgs and TutorialsController's $presetVars. I've also tried moving the relevant $filterArgs to the LearningGoal model. I have not yet been able to successfully trigger the entry for learning goals in $filterArgs.
I think I must be missing something obvious. Or maybe the Search plugin doesn't support what I'm trying to do. Does anyone know how to use this plugin to search on associated models?
So here's what I've figured out. You can combine what's below with the Search plugin directions to search on related models.
The $filterArgs piece in the Tutorial model must look like this:
var $filterArgs = array(
array('name' => 'LearningGoal', 'type' => 'subquery', 'method' => 'findByLearningGoals', 'field' => 'Tutorial.id'),
);
Here's the supporting function in the Tutorial model:
function findByLearningGoals($data = array()) {
$ids = explode('|', $data['LearningGoal']);
$ids = join(',', $ids);
$this->LearningGoalsTutorial->Behaviors->attach('Containable', array('autoFields' => false));
$this->LearningGoalsTutorial->Behaviors->attach('Search.Searchable');
$query = $this->LearningGoalsTutorial->getQuery('all',
array(
'conditions' => array('LearningGoalsTutorial.learning_goal_id IN (' . $ids . ')'),
'fields' => array('tutorial_id'),
)
);
return $query;
}
In TutorialsController, $presetVars should look like this:
public $presetVars = array(
array('field' => 'LearningGoal', 'type' => 'checkbox', 'model' => 'Tutorial'),
);
And in my search action in TutorialsController, I did this:
$this->LearningGoal = $this->Tutorial->LearningGoal;
The Prg component seems to need that.
I am using CakePHP version 2.X
Every time I come to do this in a project I always spend hours figuring out how to do it using CakeDC search behavior so I wrote this to try and remind myself with simple language what I need to do. I've also noticed that although Michael is generally correct there is no explanation which makes it more difficult to modify it to one's own project.
When you have a "has and belongs to many" relationship and you are wanting to search the joining table i.e. the table that has the two fields in it that joins the tables on either side of it together in a many-to-many relationship you want to create a subquery with a list of IDs from one of the tables in the relationship. The IDs from the table on the other side of the relationship are going to be checked to see if they are in that record and if they are then the record in the main table is going to be selected.
In this following example
SELECT Handover.id, Handover.title, Handover.description
FROM handovers AS Handover
WHERE Handover.id in
(SELECT ArosHandover.handover_id
FROM aros_handovers AS ArosHandover
WHERE ArosHandover.aro_id IN (3) AND ArosHandover.deleted != '1')
LIMIT 20
all the records from ArosHandover will be selected if they have an aro_id of 3 then the Handover.id is used to decide which Handover records to select.
On to how to do this with the CakeDC search behaviour.
Firstly, place the field into the search form:
echo $this->Form->create('Handover', array('class' => 'form-horizontal'));?>
echo $this->Form->input('aro_id', array('options' => $roles, 'multiple' => true, 'label' => __('For', true), 'div' => false, true));
etc...
notice that I have not placed the form element in the ArosHandover data space; another way of saying this is that when the form request is sent the field aro_id will be placed under the array called Handover.
In the model under the variable $filterArgs:
'aro_id' => array('name' => 'aro_id', 'type' => 'subquery', 'method' => 'findByAros', 'field' => 'Handover.id')
notice that the type is 'subquery' as I mentioned above you need to create a subquery in order to be able to find the appropriate records and by setting the type to subquery you are telling CakeDC to create a subquery snippet of SQL. The method is the function name that are going to write the code under. The field element is the name of the field which is going to appear in this part of the example query above
WHERE Handover.id in
Then you write the function that will return the subquery:
function findByAros($data = array())
{
$ids = ''; //you need to make a comma separated list of the aro_ids that are going to be checked
foreach($data['aro_id'] as $k => $v)
{
$ids .= $v . ', ';
}
if($ids != '')
{
$ids = rtrim($ids, ', ');
}
//you only need to have these two lines in if you have not already attached the behaviours in the ArosHandover model file
$this->ArosHandover->Behaviors->attach('Containable', array('autoFields' => false));
$this->ArosHandover->Behaviors->attach('Search.Searchable');
$query = $this->ArosHandover->getQuery('all',
array(
'conditions' => array('ArosHandover.aro_id IN (' . $ids . ')'),
'fields' => array('handover_id'), //the other field that you need to check against, it's the other side of the many-to-many relationship
'contain' => false //place this in if you just want to have the ArosHandover table data included
)
);
return $query;
}
In the Handovers controller:
public $components = array('Search.Prg', 'Paginator'); //you can also place this into AppController
public $presetVars = true; //using $filterArgs in the model configuration
public $paginate = array(); //declare this so that you can change it
// this is the snippet of the search form processing
public function admin_find()
{
$this->set('title_for_layout','Find handovers');
$this->Prg->commonProcess();
if(isset($this->passedArgs) && !empty($this->passedArgs))
{//the following line passes the conditions into the Paginator component
$this->Paginator->settings = array('conditions' => $this->Handover->parseCriteria($this->passedArgs));
$handovers = $this->Paginator->paginate(); // this gets the data
$this->set('handovers', $handovers); // this passes it to the template
If you want any further explanation as to why I have done something, ask and if I get an email to tell me that you have asked I will give an answer if I am able to.

How do I correctly create a Zend Feed?

I have successfully created a simple RSS feed, but entries keep coming back as unread and updated, and entries deleted from the client reappear everytime I ask mail to update the feed.
What am I doing wrong?
I use this simple function to create an rss feed:
public static function getFeed($db)
{
$title = 'Latest feeds';
$feedUri = '/rss/';
//link from which feed is available
$link = 'http://' . $_SERVER['HTTP_HOST'] . $feedUri;
//create array according to structure defined in Zend_Feed documentation
$feedArr = array('title' => $title,
'link' => $link,
'description' => $title,
'language' => 'en-us',
'charset' => 'utf-8',
//'published' => 1237281011,
'generator' => 'Zend Framework Zend_Feed',
'entries' => array()
);
$itemObjs = array();
$select = $db->select('id')->from('things')
->order('createddate desc')
->limit(10);
$results = $db->fetchAll($select->__toString());
$count = count($results);
for($i=0;$i<$count;$i++) {
$itemObjs[] = SiteUtil::getItemObjectInstance($db, $results[$i]['id']);
}
$count = count($itemObjs);
for($i=0;$i<$count;$i++) {
$obj = & $itemObjs[$i];
$feedArr['entries'][] = array('title' => $obj->getSummary(),
'link' => 'http://' . $_SERVER['HTTP_HOST'] . $obj->getDetailUri(),
'description' => $obj->description,
'publishdate' => $obj->publishedDate,
'guid' => 'http://' . $_SERVER['HTTP_HOST'] . $obj->getDetailUri()
);
}
$feed = Zend_Feed::importArray($feedArr, 'rss');
return $feed;
}
The action in the controller class is:
public function rssAction()
{
$feed = FeedUtil::getFeed($this->db);
$feed->send();
}
So to access the feed, I point the client to:
http://mysite.com/rss
I am using mac mail's rss client to test. The feed downloads just fine, showing all 5 items I have in the database for testing purposes. The problems are as follows:
1) If I mark one or more items as 'read' and then tell mail to update the feed, it pulls all items again as if I never downloaded them in the first place.
2) If I delete one or more items they come back again, unread, again as if it were the first time I subscribed to the feed.
3) Feeds are always marked as updated. Is that supposed to be the case?
Is is something to do with the parameters I'm setting, am I omitting something, or could the solution be something more subtle like setting HTTP content headers (e.g. '304 Not Modified')?
My understanding of rss is that once an item has been marked as read or deleted from the client, it should never come back, which is the behaviour I'm after.
Just to note, the 'link' and 'guid' parameters are always unique, and I have tried experimenting with 'published' and 'publishdate' (both optional) attributes only get the same result. The above code is a simplified version of what I have, showing only the relevant bits, and finally, yes, I have read the rss specification.
Thanks in advance for any help offered here, I'll be happy to clarify any point.
According to the Zend Framework Doc, you must use the lastUpdate parameter to set the last modification date of an entry.
'entries' => array(
array(
[...]
'lastUpdate' => 'timestamp of the publication date', // optional
[...]
So published for the feed, and lastUpdate for the entries.

Categories