Joining two SugarCRM modules on linked field using SugarQuery() - php

Background and Context
I am attempting to create a custom REST module in SugarCRM 8.0 that joins two modules on a linked field. The two modules are;
Accounts ( a OOTB module )
ConsumerLeads ( a custom module )
These two modules are a linked field named w002_consumerleads_accounts_1 such that when I invoke the following endpoint I get a JSON response with all the ConsumerLead data associated with that specific account uuid.
/rest/v11_4/Accounts/{ account_uuid }/link/w002_consumerleads_accounts_1
However, instead of returning the joined results based on the account uuid, my custom module returns the the joined results based on a different account attribute that uniquely identifies an account.
/rest/v11_4/customer/{ customer_id }/leads
The reason I am attempting to build a custom module for this ( instead of using the predefined rest api listed above ) is due to the fact that the system invoking this call does not know the sugar account uuid, and instead knows a business key that uniquely identifies the account ( and is an attribute on the Accounts module ).
The Issue
When I use SugarQuery in my custom rest module to join Accounts and ConsumerLeads my results do not match the results specified in the first rest api ( the predefined rest api ). The result only returns the Accounts module, and does not join the ConsumerLeads module.
The issue is with the joining of the two modules on the linked field; the issue is not related to using the customer uuid v. the account uuid.
Reference Implementations
Based on the SugarCRM Developers Guide I written the following piece of code.
public function GetLinkLeads($api, $args) {
try {
$query = new SugarQuery();
$query->from(BeanFactory::getBean('Accounts'));
$query->join('w002_consumerleads_accounts_1');
$query->limit(10);
$results = $query->execute();
return $results;
} catch ( Exception $e ) {
return $e->getCode();
}
return 1;
}
Based on all the information I can gather, this function should return the first 10 account records joined with their ConsumerLeads. However, the response only contains the Accounts module data, it does not join the ConsumerLeads data.
Additionally, I have also tried the following way.
public function GetLinkLeads($api, $args) {
try {
$account = BeanFactory::getBean('Accounts', '4606e963-9213-7764-d83f-4cc050c8473d');
if ( $account->load_relationship('w002_consumerleads_accounts_1') ) {
$lead = $account->w002_consumerleads_accounts_1->getBeans();
return $lead;
}
} catch ( Exception $e ) {
return $e->getCode();
}
return 1;
}
Where 4606e963-9213-7764-d83f-4cc050c8473d is an account uuid that has associated ConsumerLeads, but I still cannot get ConsumerLeads data to return.
Question
I would like to either:
Use SugarQuery() to join these two modules based on a linked field
Use the default rest api to join the two modules based on an attribute on the Accounts module (not the account uuid)
I have found this exact question on Stack Overflow and the implementation above is based off the recommendation from that post. However, it still is not joining the records.

What you want to achieve should work OOTB using the filter API and specifying the required field's contents in your requests filter definition. Then you should receive the linked record you wanted.
It should work similar to https://stackoverflow.com/a/50608304/4068476
As quick test you could try calling this in your browser or program (here: GET, that's why I pass filter in query string)
/rest/v11_4/w002_ConsumerLeads?filter[0][w002_consumerleads_accounts_1.consumer_id]={ customer_id }
Notes:
I guessed the spelling of the module name in the URL, make sure to get uppercase/lowercase right.
If you want to receive both the Accounts and the ConsumerLeads in a single request - just use the /bulk API to wrap two requests into one.

Try the following code:
function outright_load_relationship( $left_bean, $rel_name,$return_beans = 0 ) {
$rel_obj = $left_bean->load_relationship( $rel_name );
if ( !$rel_obj ){
$rel_name =outright_get_bean_fields( $rel_name );
$rel_obj = $left_bean->load_relationship( $rel_name );
}
if( $return_beans ){
$relatedBeans = $left_bean->$rel_name->getBeans();
return $relatedBeans;
}
return $left_bean->$rel_name;
}
function outright_get_bean_fields( $left_bean, $fld_name = false, $fld_key = false ) {
if( !$fld_name && !$fld_key ) {
return $left_bean->field_defs;
} else {
foreach( $left_bean->field_defs as $key=>$value ) {
if( $fld_name && $key == $fld_name ) {
return $left_bean->field_defs[$key];
} else if( $fld_key && $value[$fld_key] == $fld_name ){
return $left_bean->field_defs[$key];
}
}
}
}
All you need to pass correct $rel_name in above functions. Please let me know if this does not work.

Related

API Understanding made with codeigniter

I have bought one android application with web service made in codeigniter. There API in this web service is like below.
<?php
if (!defined("BASEPATH"))
exit("No direct script access allowed");
class Site extends back {
public function __construct() {
parent::__construct();
$this->lang->load("site", "english");
$this->load->model("site_model", "site");
}
//=====================================================================
public function get_updates($last_author, $last_quote) {
$this->db->where("_auid > ", $last_author);
$this->db->where("au_status", 1);
$result["authors"] = $this->db->get("authors")->result_array();
$this->db->select("quotes.*, authors._auid, authors.au_status");
$this->db->from("quotes");
$this->db->join("authors", "authors._auid = quotes.qu_author AND authors.au_status = 1");
$this->db->where("_quid > ", $last_quote);
$this->db->where("qu_status", 1);
$result["quotes"] = $this->db->get()->result_array();
echo json_encode($result);
}
}
I am learning php yet. I have made another fresh corephp web service for use. I am not understanding above api and so not able to make similar api for my new web service. Both web service use same database...anyone can please suggest me how can I use above API in my new corephp web service ?
sorry for my bad knowledge.
Thanks
It is very simple
function get_updates get 2 parameter as input
1) $last_author //value of _auid(id) field belong to table author
2) $last_quote //value of _quid(id) field belong to table quotes
$this->db->where("_auid > ", $last_author);
$this->db->where("au_status", 1);
$result["authors"] = $this->db->get("authors")->result_array();
These lines fetch data from table author with matches value of $last_author parameter
And second query fetch data from table quotes and it is join with author with matches value of $last_quote parameter.
Join is use for smashing two or more tables into a single table.
$last_author and $last_quote is request parameter send from application.
Desired result will be stored in $result and return with json object as response data to application.

Retrieve All User Lists using Aweber API

I am adding AWeber as an autoresponder in a web application. Using AWeber API, I am able to add a new subscriber to list with a known name which is in this case is firstlist:
$app = new MyApp();
$app->findSubscriber('whtever#aol.com');
$list = $app->findList('firstlist');
$subscriber = array(
'email' => 'someemail#gmail.com',
'name' => 'Name here'
);
$app->addSubscriber($subscriber, $list);
Function definition for findList() is:
function findList($listName) {
try {
$foundLists = $this->account->lists->find(array('name' => $listName));
return $foundLists[0];
}
catch(Exception $exc) {
print $exc;
}
}
As I am developing a public application, so I need to provide users an option to select from their available lists.
Please guide me how I can retrieve all the lists name.
You are returning $foundLists[0] so it will return single list. Try to return foundLists and check what it returns.
This may help you: https://labs.aweber.com/snippets/lists
In short, I pulled the lists by first finding the Aweber User Id so that I could use it in the URL https://api.aweber.com/1.0/accounts/<id>/lists
To find the User ID, I first got the account.
$this->aweber->getAccount($token['access'], $token['secret']);
Then, I retrieve the user's information.
$aweber_user = $this->aweber->loadFromUrl('https://api.aweber.com/1.0/accounts');
From that, I grabbed the user ID with...
$id = $aweber_user->data['entries'][0]['id'];
Once I had the user ID, I could then retrieve their lists with...
$lists = $this->aweber->loadFromUrl('https://api.aweber.com/1.0/accounts/'.$id.'/lists');
This example is more of a procedural approach, of course, I recommend utilizing classes.

How I can add subscriber to couple lists in MailChimp via API?

I want to create couple lists in mailchimp, and I need to have some users in couple lists. I successfully added user to first list, but can't add to second, because I get an error "This user is already subscribed".
I read about segmentation but this doesn't resolve issue, also I see that there is a posibility to copy user from one list to another via mailchimp admin panel, but I can't find which method can do this is in API v2.0
function cog_add_user_email_mailchimp( $user_id ) {
$user_data = get_userdata( $user_id );
if ( is_object( $user_data ) && ! empty( $user_data->user_email ) ) {
$mailchimp_obj = new COG_Mailchimp_Newsletters( MAILCHIMP_APIKEY );
$mailchimp_obj->user_id = $user_id;
$result = $mailchimp_obj->subscibe_user( $mailchimp_obj->lists_id['all_user_list'], array( 'email' => $user_data->user_email ) );
if ( $mailchimp_obj->check_user_subscribe_meta( $result ) ) {
$mailchimp_obj->subscibe_user( $mailchimp_obj->lists_id['just_registered'], array( 'euid' => $result['euid'] ) );
$mailchimp_obj->init_compaing_object( $mailchimp_obj );
$response = $mailchimp_obj->send_mail( $mailchimp_obj->lists_id['just_registered'] );
}
}
}
Where:
$mailchimp_obj->lists_id - array with lists id
$mailchimp_obj->subscibe_user - wrapper for subscribe method of mailchimp API
So I successfully add user into this list $mailchimp_obj->lists_id['all_user_list'], but when I try to subscribe into this list $mailchimp_obj->lists_id['just_registered'] I get an error.
Yes, you can. You'd better use segments inside the same list, though, as using separate lists count your subscribers twice (and, thus, increase the monthly bill).
Now, what have you tried so far? It is good practice to tell the community what code you have tried and didnt work. Or what did you google that yield no desired results but failed ones, etc.
The MailChimp API is a boon to work with. Read the docs.
http://apidocs.mailchimp.com/

How do I pull the subscriber count from a MailChimp list with the API?

I'm trying to display the subscriber count from a MailChimp mailing list using their API, and I've got it partially working, except the code below is currently spitting out the subscriber count for all lists, rather than for one specific list. I've specified the list id in the line $listId ='XXX'; but that doesn't seem to be working. Because I have five lists in total, the output from the PHP below shows this:
10 0 0 1 9
What do I need to do in my code below to get the subscriber count from a specific list id?
<?php
/**
This Example shows how to pull the Members of a List using the MCAPI.php
class and do some basic error checking.
**/
require_once 'inc/MCAPI.class.php';
$apikey = 'XXX';
$listId = 'XXX';
$api = new MCAPI($apikey);
$retval = $api->lists();
if ($api->errorCode){
echo "Unable to load lists()!";
echo "\n\tCode=".$api->errorCode;
echo "\n\tMsg=".$api->errorMessage."\n";
} else {
foreach ($retval['data'] as $list){
echo "\t ".$list['stats']['member_count'];
}
}
?>
I just came across this function (see below) that let's me return a single list using a known list_id. The problem is, I'm not sure how to add the list_id in the function.
I'm assuming I need to define it in this line? $params["filters"] = $filters;
The MailChimp lists() method documentation can be referred to here: http://apidocs.mailchimp.com/rtfm/lists.func.php
function lists($filters=array (
), $start=0, $limit=25) {
$params = array();
$params["filters"] = $filters;
$params["start"] = $start;
$params["limit"] = $limit;
return $this->callServer("lists", $params);
}
I'd strongly recommend not mucking with the internals of the wrapper as it's not going to be nearly as helpful as the online documentation and the examples included with the wrapper. Using the wrapper means the line you tracked down will effectively be filled when make the proper call.
Anywho, this is what you want:
$filters = array('list_id'=>'XXXX');
$lists = $api->lists($filters);
Mailchimp provides a pre-built php wrapper around their api at http://apidocs.mailchimp.com/downloads/#php. This api includes a function lists() which, according to its documentation, returns among other things:
int member_count The number of active members in the given list.
It looks like this is the function which you are referring to above. All you should have to do is iterate through the lists that are returned to find the one with the proper id. From there you should be able to query the subscriber count along with a number of other statistics about the list.

Hide Drupal nodes from search

I made a private section on a drupal site by writing a module that checks the RERQUEST_URI for the section as well as user role. The issue I am running into now is how to prevent those nodes/views from appearing in the search.
The content types used in the private section are used in other places in the site.
What's the best way to get Druapl search to ignore the content/not index/not display it in search results?
There is a wonderful article that explains just this on the lullabot site.
It's worth reading the comments to the post too, because people there suggested alternate ways of doing that, also by mean of contrib modules (rather than implementing some hooks in your own code). Code for D6 is in the comment as well.
HTH!
The lullabot article is a bit outdated and contains many blunt approaches. It also contains the answer in the comments - the Search Restrict module which works for DP6 and allows fine-grained and role-based control. Everything else either prevents content from being indexed, which may not be desirable if there are different access levels to content, or affects all search queries equally, which will also not work if there are different access levels.
If the content types used within the Private section are also used elsewhere how are you hoping to filter them out of the search results (note that I've not looked at the lullabot article by mac yet).
Basically, if you look at the details of two nodes, one private and one public, what differentiates them?
Note: I'm assuming that you want the nodes to appear to users with access to the Private area but not to 'anonymous' users.
For Drupal 7.
You can hide the node from search results by using custom field. In my case, I have created a custom field in the name of Archive to the desired content type and with the help of that custom field you can write the my_module_query_alter functionality.
Code
function my_module_query_alter(QueryAlterableInterface $query) {
$is_search = $is_node_search = FALSE;
$node_alias = FALSE;
foreach ( $query->getTables() as $table ) {
if ( $table['table'] == 'search_index' || $table['table'] == 'tracker_user') {
$is_search = TRUE;
}
if ( $table['table'] == 'node' || $table['table'] == 'tracker_user') {
$node_alias = $table['alias'];
$is_node_search = TRUE;
}
}
if ( $is_search && $is_node_search ) {
$nids = [];
// Run entity field query to get nodes that are 'suppressed from public'.
$efq = new EntityFieldQuery();
$efq->entityCondition('entity_type', 'node')
->fieldCondition('field_archive', 'value', 1, '=');
$result = $efq->execute();
if ( isset($result['node']) ) {
$nids = array_keys($result['node']);
}
if ( count($nids) > 0 ) {
$query->condition(sprintf('%s.nid', $node_alias), $nids, 'NOT IN');
}
}
}

Categories