How to use createUser in Facebook Ads (to replace deprecated addUsers) - facebook

Now that I've upgraded to "facebook/php-ads-sdk": "2.8.*" (https://github.com/facebook/facebook-php-ads-sdk), this function of mine doesn't work anymore:
public function addToCustomAudience($entriesArray, $audienceId, $inputType = CustomAudienceTypes::EMAIL) {
$audience = new CustomAudience($audienceId);
$result = $audience->addUsers($entriesArray, $inputType);
return $result;
}
Apparently addUsers is no longer available.
I see a createUser function, but it looks quite different, and there is no documentation online about how to migrate from addUsers to createUser.
What I want to do is simple.
Given an array of email addresses and an ID of an audience, how can I add all of those email addresses to that Facebook Custom Audience?

From what I can see in the code, addUsers is still there, and it's documented on the Developer site.
I just used the latest SDK along with the following code to update an audience:
use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Values\CustomAudienceTypes;
$emails = array(
'test1#example.com',
'test2#example.com',
'test3#example.com',
);
$audience = new CustomAudience(<CUSTOM_AUDIENCE_ID>);
$audience->addUsers($emails, CustomAudienceTypes::EMAIL);

This seems to work for my purposes.
I copied some code from the facebook-php-ads-sdk as a workaround.
$audience = new CustomAudience($audienceId);
$params = $this->formatParams($entriesArray, $inputType, [], false);
$audience->createUser([], $params, false);
/**
* Copied this from Facebook's https://github.com/facebook/facebook-php-ads-sdk/blob/d51193b19d730ae9274d45540986e1ac311b074d/src/FacebookAds/Object/CustomAudience.php#L363
* Take users and format them correctly for the request
*
* #param array $users
* #param string $type
* #param array $app_ids
* #param bool $is_hashed
* #return array
*/
protected function formatParams(array $users, $type, array $app_ids = array(), $is_hashed = false) {
if ($type == CustomAudienceTypes::EMAIL || $type == CustomAudienceTypes::PHONE) {
$normalizer = new EmailNormalizer();
$hash_normalizer = new HashNormalizer();
foreach ($users as &$user) {
if ($type == CustomAudienceTypes::EMAIL) {
$user = $normalizer->normalize(CustomAudienceTypes::EMAIL, $user);
}
if (!$is_hashed) {
$user = $hash_normalizer->normalize(
CustomAudienceTypes::EMAIL, $user);
}
}
}
$payload = array(
'schema' => $type,
'data' => $users,
);
if ($type === CustomAudienceTypes::ID) {
if (empty($app_ids)) {
throw new \InvalidArgumentException(
"Custom audiences with type " . CustomAudienceTypes::ID . " require"
. "at least one app_id");
}
$payload['app_ids'] = $app_ids;
}
return array('payload' => $payload);
}

Related

How to prevent SQL injection in PhalconPHP when using sql in model?

Let's say I am building a search that finds all the teacher and got an input where the user can put in the search term. I tried reading the phalcon documentation but I only see things like binding parameters. I read the other thread about needing prepare statements do I need that in Phalcon as well?
And my function in the model would be something like this:
public function findTeachers($q, $userId, $isUser, $page, $limit, $sort)
{
$sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
$result = new Resultset(null, $this,
$this->getReadConnection()->query($sql, array()));
$tagResult = $result->toArray();
$tagList = array();
foreach ($tagResult as $key => $value) {
$tagList[] = $value['id'];
....
}
}
My question is for the Phalcon framework is there any settings or formats I should code for this line $sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
And also any general recommendation for preventing SQL Injection in PhalconPHP controllers and index would be appreciated.
For reference:
My controller:
public function searchAction()
{
$this->view->disable();
$q = $this->request->get("q");
$sort = $this->request->get("sort");
$searchUserModel = new SearchUsers();
$loginUser = $this->component->user->getSessionUser();
if (!$loginUser) {
$loginUser = new stdClass;
$loginUser->id = '';
}
$page = $this->request->get("page");
$limit = 2;
if (!$page){
$page = 1;
}
$list = $searchUserModel->findTeachers($q, $loginUser->id, ($loginUser->id)?true:false, $page, $limit, $sort);
if ($list){
$list['status'] = true;
}
echo json_encode($list);
}
My Ajax:
function(cb){
$.ajax({
url: '/search/search?q=' + mapObject.q + '&sort=<?php echo $sort;?>' + '&page=' + mapObject.page,
data:{},
success: function(res) {
//console.log(res);
var result = JSON.parse(res);
if (!result.status){
return cb(null, result.list);
}else{
return cb(null, []);
}
},
error: function(xhr, ajaxOptions, thrownError) {
cb(null, []);
}
});
with q being the user's search term.
You should bind the query parameter to avoid an SQL injection. From what I can remember Phalcon can be a bit funny with putting the '%' wildcard in the conditions value so I put them in the bind.
This would be better than just filtering the query.
$tags = Tags::find([
'conditions' => 'name LIKE :name:',
'bind' => [
'name' => "%" . $q . "%"
]
])
Phalcon\Filter is helpful when interacting with the database.
In your controller you can say, remove everything except letters and numbers from $q.
$q = $this->request->get("q");
$q = $this->filter->sanitize($q, 'alphanum');
The shortest way for requests:
$q = $this->request->get('q', 'alphanum');

How to inserting data from install.xml file into mysql database in moodle

In moodle site (use moodle Version 2.6.3), I have generated install.xml file by XMLDB editor, but it's use only to create table in database during plugin installation. I want to insert some default rows in the table also.
Any body can help me how to edit in install.xml file for insert data
To add data after an install, create a file called yourplugin/db/install.php with
UPDATE: added xml parser
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/xmlize.php');
function xmldb_yourpluginname_install() {
global $CFG, $OUTPUT, $DB;
// Your add data code here.
$xmltext = file_get_contents('import.xml');
$records = parse_xml($xmltext, 'records', 'record');
foreach ($records as $record) {
$DB->insert_record('yourtablename', $record);
}
}
/**
* Converts XML text into an array of stdclass objects.
*
* #param type $text - xmltext
* #param type $elementnames - plural name of elements
* #param type $elementname - name of element
* #return array|boolean - array of record objects
*/
function parse_xml($text, $elementnames, $elementname) {
// Seems that xmlize needs a lot of memory.
ini_set('memory_limit', '256M');
// Ensure content is UTF-8.
$content = xmlize($text, 1, 'UTF-8');
$records = array();
if (!empty($content[$elementnames]['#'][$elementname])) {
$rows = $content[$elementnames]['#'][$elementname];
foreach ($rows as $row) {
$fields = $row['#'];
$row = new stdClass();
foreach ($fields as $fieldname => $fieldvalue) {
$row->$fieldname = $fieldvalue[0]['#'];
}
$records[] = $row;
}
return $records;
}
return false;
}

Jomsocial Extra Field

I am trying to create extra fields on the Jomsocial Groups Create New Group page, its suggested on the Jomsocial docs that the best way is to creat a plugin to do this.
As I have never created such a complex plugin do anyone have a working example to start with?
Here is the code that I have tried with
<?php
defined('_JEXEC') or die('Restricted access');
if (! class_exists ( 'plgSpbgrouppostcode' )) {
class plgSpbgrouppostcode extends JPlugin {
/**
* Method construct
*/
function plgSystemExample($subject, $config) {
parent::__construct($subject, $config);
// JPlugin::loadLanguage ( 'plg_system_example', JPATH_ADMINISTRATOR ); // only use if theres any language file
include_once( JPATH_ROOT .'/components/com_community/libraries/core.php' ); // loading the core library now
}
function onFormDisplay( $form_name )
{
/*
Add additional form elements at the bottom privacy page
*/
$elements = array();
if( $form_name == 'jsform-groups-forms' )
{
$obj = new CFormElement();
$obj->label = 'Labe1 1';
$obj->position = 'after';
$obj->html = '<input name="custom1" type="text">';
$elements[] = $obj;
$obj = new CFormElement();
$obj->label = 'Labe1 2';
$obj->position = 'after';
$obj->html = '<input name="custom2" type="text">';
$elements[] = $obj;
}
return $elements;

Zend Framework: Paypal

I have been attempting to implement a paypal functionality into my application by following the example here: http://www.alexventure.com/2011/04/02/zend-framework-and-paypal-api-part-2-of-2/
This is my paymentAction in my controller.
public function paymentAction()
{
$auth= Zend_Auth::getInstance();
$user= $auth->getIdentity();
$username = $user->username;
$cart = new Application_Model_DbTable_Cart();
$select = $cart->select()
->from(array('c' => 'cart'))
->join(array('p' => 'product'), 'p.productid = c.productid')
->where('username = ?', $username)
->setIntegrityCheck(false);
$fetch = $cart->fetchAll($select)->toArray();
$paypal = new My_Paypal_Client;
$amount = 0.0;
foreach($fetch as $item) {
$amount = $amount + ($item['price']*$item['quantity']);
}
$returnURL = 'http://www.google.com';
$cancelURL = 'http://www.yahoo.com';
$currency_code = 'USD';
$reply = $paypal->ecSetExpressCheckout(
$amount,
$returnURL,
$cancelURL,
$currency_code
);
if ($reply->isSuccessfull())
{
$replyData = $paypal->parse($reply->getBody());
if ($replyData->ACK == 'SUCCESS' || $replyData->ACK == 'SUCCESSWITHWARNING')
{
$token = $replyData->TOKEN;
$_SESSION['CHECKOUT_AMOUNT'] = $amount;
header(
'Location: ' .
$paypal->api_expresscheckout_uri .
'?&cmd=_express-checkout&token=' . $token
);
}
}
else
{
throw new Exception('ECSetExpressCheckout: We failed to get a successfull response from PayPal.');
}
}
However, this is the error that returns.
Message: No valid URI has been passed to the client
Where did i go wrong? I would be happy to provide code from other areas of my application if needed. Thanks.
Zend_Http_Client::request() has not received a valid instance of Zend_Uri_Http.
Here's where the error occurs:
/**
* Send the HTTP request and return an HTTP response object
*
* #param string $method
* #return Zend_Http_Response
* #throws Zend_Http_Client_Exception
*/
public function request($method = null)
{
if (! $this->uri instanceof Zend_Uri_Http) {
/** #see Zend_Http_Client_Exception */
require_once 'Zend/Http/Client/Exception.php';
throw new Zend_Http_Client_Exception('No valid URI has been passed to the client');//Note the exact message.
}//Truncated
The only obvious error I see in the code you provided is :
$paypal = new My_Paypal_Client;//no () at end of declaration
I hope you implemented part one of the tutorial where the constructor is built. Otherwise you may just need to pass a better uri.
[EDIT]
I think your problem is here:
//needs a uri value for Zend_Http_Client to construct
$paypal = new My_Paypal_Client($url);
ecSetExpressCheckout does not construct the http client so it has no idea of where it's requesting the token from.
Alternatively you could just add this line below $paypal and above $reply:
//pass the uri required to construct Zend_Http_Client
$paypal->setUri($url);
I just hope you know what the url shouild be.
Good Luck.

Overwrite Zend_Config and access parents nodes

I want to overwrite Zend_Config method __set($name, $value), but I have same problem.
$name - return current key of overwrite config value, eg:
$this->config->something->other->more = 'crazy variable'; // $name in __set() will return 'more'
Because every node in config is new Zend_Config() class.
So - how from overwritten __set() metod get access to the parents nodes names?
My application:
I must overwrite same config value in controller, but to have controll about the overwritting, and do not allow to overwrite other config variables, I want to specify in same other config variable, an tree-array of overwriting allowed config keys.
Zend_Config is read only unless you have set $allowModifications to true during construction.
From the Zend_Config_Ini::__constructor() docblock:-
/** The $options parameter may be provided as either a boolean or an array.
* If provided as a boolean, this sets the $allowModifications option of
* Zend_Config. If provided as an array, there are three configuration
* directives that may be set. For example:
*
* $options = array(
* 'allowModifications' => false,
* 'nestSeparator' => ':',
* 'skipExtends' => false,
* );
*/
public function __construct($filename, $section = null, $options = false)
This means that you would need to do something like this:-
$inifile = APPLICATION_PATH . '/configs/application.ini';
$section = 'production';
$allowModifications = true;
$config = new Zend_Config_ini($inifile, $section, $allowModifications);
$config->resources->db->params->username = 'test';
var_dump($config->resources->db->params->username);
Result
string 'test' (length=4)
In response to comment
In that case you can simply extend Zend_Config_Ini and override the __construct() and __set() methods like this:-
class Application_Model_Config extends Zend_Config_Ini
{
private $allowed = array();
public function __construct($filename, $section = null, $options = false) {
$this->allowed = array(
'list',
'of',
'allowed',
'variables'
);
parent::__construct($filename, $section, $options);
}
public function __set($name, $value) {
if(in_array($name, $this->allowed)){
$this->_allowModifications = true;
parent::__set($name, $value);
$this->setReadOnly();
} else { parent::__set($name, $value);} //will raise exception as expected.
}
}
Always there is another way :)
$arrSettings = $oConfig->toArray();
$arrSettings['params']['dbname'] = 'new_value';
$oConfig= new Zend_Config($arrSettings);