How Do I Prevent Duplicates When Adding Leads to SuiteCRM? - php

The developer guide for SuiteCRM is kind of incomplete (at least here in Q4 2017) compared to the old SugarCRM one that it was based on before the software fork. So, by downloading the WordPress Plugin for SugarCRM, I was able to figure out the REST API and JSON for adding a sales lead into SuiteCRM with the following code.
Now how do I prevent duplicates by home phone, mobile phone, or email address?
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
header('Content-Type: text/plain');
CRM::loginCRM('admin','xxxxPASSWORDxxxxxx');
$aResult = CRM::addLead(array(
'name' => 'John Doe',
'description' => 'sample description',
'salutation' => 'Mr.',
'first_name' => 'John',
'last_name' => 'Doe',
'do_not_call' => 'No',
'phone_home' => '202-111-2222',
'phone_mobile' => '202-111-2222',
'email1' => 'test#example.com',
'primary_address_street' => '123 Main Street',
'primary_address_street2' => '',
'primary_address_street3' => '',
'primary_address_city' => 'New York',
'primary_address_state' => 'NY'
));
print_r($aResult);
CRM::logoutCRM();
die('OK');
/////////////////////////
class CRM {
private static $SessionID = '';
private static $URL = 'https://mycrmserver-example.com/service/v4_1/rest.php';
private static $User = '';
private static $Shadow = '';
public static function sendJSON($a) {
$s = file_get_contents(
self::$URL,
false,
stream_context_create(
array(
'http' => array (
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($a)
)
)
)
);
$a2 = json_decode($s);
return $a2;
}
public static function loginCRM($sUser,$sPass) {
$sShadow = md5($sPass);
self::$User = $sUser;
self::$Shadow = $sShadow;
$asLogin = array (
'method' => 'login',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'user_auth' => array(
'user_name' => $sUser,
'password' => $sShadow,
'version' => 1
),
'application_name' => 'RestTest',
'name_value_list' => array()
))
);
$a = self::sendJSON($asLogin);
self::$SessionID = $a->id;
}
public static function logoutCRM() {
$asLogin = array (
'method' => 'logout',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'user_auth' => array(
'user_name' => self::$User,
'password' => self::$Shadow,
'version' => 1
),
'application_name' => 'RestTest',
'name_value_list' => array()
))
);
self::sendJSON($asLogin);
}
public static function addLead($a) {
$asNameValueList = array();
foreach($a as $sKey => $sVal) {
$asNameValueList[] = array('name'=>$sKey,'value'=>$sVal);
}
$asAddEntry = array (
'method' => 'set_entry',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'name_value_list' => $asNameValueList
))
);
$a = self::sendJSON($asAddEntry);
return $a;
}
} // end CRM

Add these functions into your CRM class and check them before adding a lead. I had a little help from this answer that incidentally gave me some insights. Also, I recommend you do things to tighten down your security such as add an .htaccess or NGINX rule that only allows certain IP addresses or require certain headers to reach anything in your /service folder, and /service/* subfolders either over HTTP or HTTPS.
public static function leadExistsByPhone($sHomePhone,$sMobilePhone) {
$sHomePhone = (empty($sHomePhone)) ? 'xxxxxinvalid' : $sHomePhone;
$sMobilePhone = (empty($sMobilePhone)) ? 'xxxxxinvalid' : $sMobilePhone;
$asCheck = array (
'method' => 'get_entry_list',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'query' => "
leads.phone_home = '$sHomePhone'
OR leads.phone_mobile = '$sMobilePhone'
",
'order_by' => 'leads.date_entered DESC',
'offset' => '0',
'select_fields' => array(),
'link_name_to_fields_array' => array(),
'max_results' => 999999,
'deleted' => false
))
);
$a = self::sendJSON($asCheck);
$nCount = # $a->result_count;
$nCount = intval($nCount);
return ($nCount > 0);
}
public static function leadExistsByEmail($sEmail) {
if (!filter_var($sEmail, FILTER_VALIDATE_EMAIL)) {
die('DENIED: invalid email address format');
}
$asCheck = array (
'method' => 'get_entry_list',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'query' => "
leads.id IN
(
SELECT email_addr_bean_rel.bean_id
FROM email_addr_bean_rel
JOIN email_addresses
ON email_addr_bean_rel.email_address_id = email_addresses.id
WHERE
email_addresses.email_address = '$sEmail'
)
",
'order_by' => 'leads.date_entered DESC',
'offset' => '0',
'select_fields' => array(),
'link_name_to_fields_array' => array(),
'max_results' => 999999,
'deleted' => false
))
);
$a = self::sendJSON($asCheck);
$nCount = # $a->result_count;
$nCount = intval($nCount);
return ($nCount > 0);
}

Related

How to combine a fields_list + .tpl view in 1 admincontroller?

I can't figure out how to display, in my custom admin controller, 1 fields_list + content of a .tpl file. The goal is to display my product keys in stock + some extra features below (content from a tpl file).
I can display either the fields list OR the message from the .tpl file. But not combined... I found a tutorial online and this comes very close, but not working.
<?php
require_once(_PS_MODULE_DIR_ . 'avanto_key/classes/AvantoStock.php');
class AdminAvantokeyStockController extends ModuleAdminController
{
protected $position_identifier = 'id_avanto_keys';
public function __construct()
{
//$this->fields_form = $this->fieldForm();
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
parent::__construct();
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
}
public function renderView()
{
$tpl = $this->context->smarty->createTemplate(
dirname(__FILE__).
'/../../views/templates/admin/view.tpl');
return $tpl->fetch();
}
public function renderList()
{
$this->toolbar_title = $this->l('Stock Management');
$this->toolbar_btn['new'] = null;
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
return parent::renderList();
}
public function init()
{
parent::init();
}
public function initContent()
{
$this->context->smarty->assign(array(
'form' => $form,
'base_dir' => _PS_MODULE_DIR_,
));
$this->setTemplate('stock.tpl');
$lists = parent::initContent();
$this->renderList();
$lists .= parent::initContent();
return $lists;
}
public function renderForm()
{
$this->display = 'edit';
$this->initToolbar();
$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->l('Edit product key'),
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Key ID'),
'name' => 'id_product',
),
array(
'type' => 'text',
'label' => $this->l('Product ID'),
'name' => 'id_avanto_keys',
),
array(
'type' => 'text',
'label' => $this->l('Serial Key'),
'required' => true,
'name' => 'serial_key',
),
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
return parent::renderForm();
}
}
?>
The code above only displays the message hello world and not my product listing.
Anyone has an idea how to combine this?
Thanks in advance!!!
It's a little bit confused, we have to make some tidy :):
First:
The fields of the list it's better to declare in the __construct so:
public function __construct()
{
$this->module = 'YourModuleName'; // Here you have to put your module name
$this->bootstrap = true;
$this->table = 'avanto_keys'; // DB table name where your object data stored
$this->className = "AvantoStock"; // The class name of my object
//$this->identifier = 'id_avanto_keys';
//$this->list_id = 'id_avanto_keys';
$this->_defaultOrderBy = 'id_avanto_keys';
//$this->lang = FALSE;
$this->explicitSelect = true; // This if you do a select manually after
$this->addRowAction('edit');
$this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'),
'confirm' => $this->l('Delete selected items?')), );
//Shop::addTableAssociation($this->table, array('type' => 'shop'));
$this->_select = 'pl.`name` as product_name, a.`serial_key` as serial_display';
$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = a.`id_product` AND pl.`id_lang`
= '.(int)$this->context->language->id.')';
$this->fields_list = array(
'id_avanto_keys' => array(
'title' => $this->l('ID Key'),
'width' => 140,
),
'id_product' => array(
'title' => $this->l('Product ID'),
'width' => 140,
),
'serial_key' => array(
'title' => $this->l('Serial Keys'),
'width' => 140,
),
'product_name' => array(
'title' => $this->l('Product Name'),
'width' => 140,
),
);
parent::__construct();
}
Second
The parent renderList method make other stuff, let's separate that from what do you want to display:
public function renderList()
{
// Here we retrieve the list (without doing any strange thing)
$list = parent::renderList();
// Assign some vars to pass to our custom tpl
$this->context->smarty->assign(
array(
'var1' => "Test",
'var2' => "Test2"
)
);
// Get the custom tpl rendered
$content = $this->context->smarty->fetch(_PS_MODULE_DIR_ . "avanto_key/views/templates/admin/avantokeystock/customcontent.tpl");
// return the list plus your content
return $list . $content;
}
Third
Leave the parent initContent as is, do not override, because he make a lot of stuffs
I guess that is a great point to start :)
Try this way and let me know ;)

how to add a button which calls a webservice in my custom admin menu page of prestashop

how to add a button and a text box in which when I click the button it calls a webservice in my custom admin menu page of prestashop, ie i am developing a admin module in which i created a menu and i am able to display grid with pagination the defalut prestashop grid in that page , but i want a button and a text box above the grid how to do this in prestashop 1.6.
here is my controllers code:
class QueryController extends ModuleAdminController
{
public $module;
public function __construct()
{
$this->module = new querydr();
$this->addRowAction('view');
//$this->removeButton('add'); // this code to remove the add button
$this->explicitSelect = false;
$this->context = Context::getContext();
$this->id_lang = $this->context->language->id;
$this->lang = false;
$this->ajax = 1;
$this->path = _MODULE_DIR_.'querydr';
$this->default_form_language = $this->context->language->id;
$dormant_filter_days= Configuration::get('DORMANTUSERS_DORMANT_FILTER_DAYS');
$this->table = 'query_dr';
$this->className = 'QueryDr';
$this->identifier = 'id_query_dr';
$this->allow_export = true;
$this->_select = " id_query_dr,order_no,ni_online_ref_id,transaction_type,response,status,error_code,error_msg,date_add,date_upd
";
$this->name = 'Query';
//d( $this->select);
$this->bootstrap = true;
$this->fields_list = array(
'id_query_dr' => array(
'title' => $this->l('Id'),
'align' => 'text-center',
'remove_onclick' => true,
'search' => false,
),
'order_no' => array(
'title' => $this->l('Order Number'),
'align' => 'text-center',
'remove_onclick' => true,
//'search' => false,
),
'ni_online_ref_id' => array(
'title' => $this->l('Online Reference ID '),
'align' => 'text-center',
'remove_onclick' => true,
//'search' => false,
),
'transaction_type' => array(
'title' => $this->l('Transaction type'),
'align' => 'text-center',
'remove_onclick' => true
),
'status' => array(
'title' => $this->l('Status'),
'align' => 'text-center',
'remove_onclick' => true
),
'error_code' => array(
'title' => $this->l('Error Code'),
'align' => 'text-center',
'remove_onclick' => true
),
'error_msg' => array(
'title' => $this->l('Error Message'),
'align' => 'text-center',
'remove_onclick' => true
),
'date_add' => array(
'title' => $this->l('Date Added'),
'align' => 'text-center',
'remove_onclick' => true
),
'date_upd' => array(
'title' => $this->l('date_upd'),
'align' => 'text-center',
'remove_onclick' => true
),
);
parent::__construct();
}
public function initPageHeaderToolbar()
{
$this->page_header_toolbar_title = $this->l('Query Dr Logs');
parent::initPageHeaderToolbar();
}
public function initToolbar()
{
parent::initToolbar();
$this->context->smarty->assign('toolbar_scroll', 1);
$this->context->smarty->assign('show_toolbar', 1);
$this->context->smarty->assign('toolbar_btn', $this->toolbar_btn);
}
}
You need to override the method initContent().
Example :
/**
* #see AdminController::initContent
*/
public function initContent()
{
$this->getLanguages();
$this->initToolbar();
$this->initTabModuleList();
$this->initPageHeaderToolbar();
$this->content .= $this->renderModulesList();
$this->content .= $this->renderKpis();
$this->content .= $this->renderMyCustomFormList();
$this->content .= $this->renderList();
$this->content .= $this->renderStats();
$this->content .= $this->renderOptions();
$this->context->smarty->assign(array(
'page_header_toolbar_btn' => $this->page_header_toolbar_btn,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'title' => $this->page_header_toolbar_title,
'toolbar_btn' => $this->page_header_toolbar_btn,
'content' => $this->content,
'lite_display' => $this->lite_display,
'url_post' => self::$currentIndex . '&token=' . $this->token
));
}
And your render for your form :
public function renderMyCustomFormList()
{
$html = $this->context->smarty->fetch(
parent::getTemplatePath().'my_template_form_list.tpl'
);
return ($html);
}

Elastica add documents overrides existing ones

When i try to add new documents to an index type , i loose existing documents which are overwritten by the new added ones . The problem can be related to the id of each added document ??
Here is the code :
$elasticaClient = new \Elastica\Client(array(
'host' => $this->container->getParameter('elastic_host'),
'port' => $this->container->getParameter('elastic_port')
));
$elasticaIndex = $elasticaClient->getIndex('app');
$elasticaIndex->create(
array(
'number_of_shards' => 4,
'number_of_replicas' => 1,
'analysis' => array(
'analyzer' => array(
'indexAnalyzer' => array(
'type' => 'custom',
'tokenizer' => 'standard',
'filter' => array('lowercase', 'mySnowball')
),
'searchAnalyzer' => array(
'type' => 'custom',
'tokenizer' => 'standard',
'filter' => array('standard', 'lowercase', 'mySnowball')
)
),
'filter' => array(
'mySnowball' => array(
'type' => 'snowball',
'language' => 'German'
)
)
)
),
true
);
$elasticaType = $elasticaIndex->getType('type');
$mapping = new \Elastica\Type\Mapping();
$mapping->setType($elasticaType);
$mapping->setParam('index_analyzer', 'indexAnalyzer');
$mapping->setParam('search_analyzer', 'searchAnalyzer');
$mapping->setProperties(array(
'id' => array('type' => 'string'),
'title' => array('type' => 'string'),
'duration' => array('type' => 'string'),
'start' => array('type' => 'string'),
'end' => array('type' => 'string'),
));
// Send mapping to type
$mapping->send();
$documents = array();
foreach($medias as $media) {
$id = uniqid() ;
$documents[] = new \Elastica\Document(
$id,
array(
'id' => $id,
'title' => $media['title'],
'duration' => $media['duration'],
'start' => $media['start'],
'end' => $media['end'],
)
);
}
$elasticaType->addDocuments($documents);
$elasticaType->getIndex()->refresh();
Please i need your help . Thank you
PHP does not recommend using uniqid for this use case. Since you are wanting a random, safe id, let Elasticsearch do it for you. The Elastica Document construct method notes that the id field is optional. So don't pass it and let Elasticsearch issue the id.
Several things
$elasticaIndex->create (....) you only have to enter it once. Index is unique after creating the index that you can comment or generate a different index and other things. I leave an example that works.
class PersistencyElastic
{
private $conection;
public function __construct()
{
$this->conection = new \Elastica\Client(['host' => '127.0.0.1', 'port' => 9200]);
}
public function save($ msg)
{
// $ msg is an array with whatever you want inside
$index = $this->conection->getIndex('googlephotos');
// This is the index I created, it's called googlephotos
// $index->create(array (), true);
$type = $index->getType('googlephotos');
$type->addDocument(new Document (uniqid ('id _', false), $msg, $type, $index));
$index->refresh();
}
}

PHP GetResponse API and CF7 connection

Im trying to take data from Contact Form 7 WordPress plugin and pass it with json to GetResponse API
I have a php file that pull the data and send it, and its looks like this
I'm getting the CF7 email of confirmation but im not getting GetResponse Email confirmation for newsletter, i don't understand why, i tried to do some debugging and there was no errors
add_action('wpcf7_before_send_mail', 'mytheme_save_to_getresponse', 10, 1);
function mytheme_save_to_getresponse($form)
{
include 'ChromePhp.php';
require_once 'jsonRPCClient.php';
$api_key = 'some_api_key';
$api_url = 'http://api2.getresponse.com';
$client = new jsonRPCClient($api_url);
$result = NULL;
try {
$result = $client->get_campaigns(
$api_key,
array (
# find by name literally
'name' => array ( 'EQUALS' => 'testcase_001' )
)
);
}
catch (Exception $e) {
# check for communication and response errors
# implement handling if needed
die($e->getMessage());
}
$campaigns = array_keys($result);
$CAMPAIGN_ID = array_pop($campaigns);
$subscriberName = $_POST['name'];
$subscriberEmail = $_POST['email'];
$subscriberPhone = $_POST['c_phone'];
$subscriberCellphone = $_POST['c_cellphone'];
$subscriberArea = $_POST['c_area'];
$subscriberInsuranceType = $_POST['c_type'];
$subscriberCarType = $_POST['c_cartype'];
$subscriberManifacture = $_POST['c_manifacture'];
$subscriberManifacturemodel = $_POST['c_manifacturemodel'];
$subscriberManifactureYear = $_POST['c_manifactureyear'];
$subscriberDriverAge = $_POST['c_driversage'];
$subscriberPrevent = $_POST['c_prevent'];
$subscriberClaim = $_POST['c_claim'];
try {
$result = $client->add_contact(
$api_key,
array (
'campaign' => $CAMPAIGN_ID,
'name' => $subscriberName,
'email' => $subscriberEmail,
'cycle_day' => '0',
'customs' => array(
array(
'name' => 'home_phone',
'content' => $subscriberPhone
),
array(
'name' => 'cell_phone',
'content' => $subscriberCellphone
),
array(
'name' => 'living_area',
'content' => $subscriberArea
),
array(
'name' => 'drivers_age',
'content' => $subscriberDriverAge
),
array(
'name' => 'insurance_type',
'content' => $subscriberInsuranceType
),
array(
'name' => 'car_type',
'content' => $subscriberCarType
),
array(
'name' => 'manifacture_type',
'content' => $subscriberManifacture
),
array(
'name' => 'manifacture_model',
'content' => $subscriberManifacturemodel
),
array(
'name' => 'manifacture_year',
'content' => $subscriberManifactureYear
),
array(
'name' => 'license_loss',
'content' => $subscriberPrevent
),
array(
'name' => 'claims_number',
'content' => $subscriberClaim
)
)
)
);
}
catch (Exception $e) {
# check for communication and response errors
# implement handling if needed
die($e->getMessage());
}
}
Thanks in advance
everything was OK with this code, i GetResponse don't send confirmation requests more than once on the same email..

if is_numeric condition issue

I have a http_build_query array and file_get_contents that looks like this:
$optionValues = http_build_query( array(
'leadcomm' => getVariable('LEADCOMM'),
'CCID' => getVariable('CCID'),
'QTR' => getVariable('QTR'),
'CLK' => getVariable('CLK'),
'dck' => getVariable('DCK'),
'bal_one' => getVariable('BAL_ONE'),
'product' => getVariable('PRODUCT'),
'prop_st' => getVariable('PROP_ST'),
'cred_grade' => getVariable('CRED_GRADE'),
'prop_zip' => getVariable('PROP_ZIP'),
'prop_desc' => getVariable('PROP_DESC'),
'spec_home' => getVariable('SPEC_HOME'),
'purchase_contract' => getVariable('PURCHASE_CONTRACT'),
'est_val' => getVariable('EST_VAL'),
'down_pmt' => getVariable('DOWN_PMT'),
'loan_type' => getVariable('LOAN_TYPE'),
'buy_timeframe' => getVariable('BUY_TIMEFRAME'),
'agent_found' => getVariable('AGENT_FOUND'),
'va_status' => getVariable('VA_STATUS'),
'income' => getVariable('INCOME'),
'annual_verifiable_income' => getVariable('ANNUAL_VERIFIABLE_INCOME'),
'fha_bank_foreclosure' => getVariable('FHA_BANK_FORECLOSURE'),
'num_mortgage_lates' => getVariable('NUM_MORTGAGE_LATES'),
'email' => getVariable('EMAIL'),
'fname' => getVariable('FNAME'),
'lname' => getVariable('LNAME'),
'address' => getVariable('ADDRESS'),
'city' => getVariable('CITY'),
'state' => getVariable('STATE'),
'zip' => getVariable('ZIP'),
'pri_phon' => getVariable('PRI_PHON'),
'sec_phon' => getVariable('SEC_PHON'),
'capture_method' => getVariable('CAPTURE_METHOD'),
'aid' => getVariable('AID'),
'srlp' => getVariable('SRLP'),
'scid' => getVariable('SCID'),
'buyer_id' => getVariable('BUYER_ID'),
'cid' => getVariable('CID'),
'ppcid' => getVariable('PPCID')
)
);
$url = 'http://api.example.com/import-lead-data.php';
$options['http'] = array(
'method' => "POST",
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $optionValues,
);
$context = stream_context_create($options);
$result = file_get_contents($url, NULL, $context);
I need to check if $results returns a numeric value. If it does, I need to set a new variable ($lead_id) to equal $results, pass $lead_id through another http_build_query array and finally do another file_get_contents $results. The code above works fine. The second part of the code is where I need some assistance. This is what I have for the second part of my code:
if (is_numberic($result)) {
$lead_id(isset($results));
};
$leadValues = http_build_query( array(
'lead_id' => "LEAD_ID"
)
);
$leadurl = 'http://api.bankradar.com/import-lead-response.php';
$leadoptions['http'] = array(
'method' => "POST",
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $leadValues,
);
$leadcontext = stream_context_create($leadoptions);
$leadResult = file_get_contents($leadurl, NULL, $leadcontext);
I think my problem is with the isset part of the code but I'm not sure.
you put
if (is_numberic($result)) {
should be
if (is_numeric($result)) {
But, i use this way
if (ctype_digit($result)) {
that way it can only containt digits, no decimals or any other characters... not sure if thats what your after
You are calling $lead_id as a function. Just change
$lead_id(isset($results));
to
$lead_id = $results;
You misspelled is_numeric (there's a b in yours) - is_numberic

Categories