Missing creative spec facebook - facebook-graph-api

I'm trying to create an ad using the php sdk.
I can create the campaign, targeting, adset, and the creative (which returns a creative_id that I can validate using the graph explorer).
But when I finally run the code to create the ad itself, I get an exception that looks like this:
"error_user_title" => "Missing creative spec"
"error_user_msg" => "No creative spec found for given adgroup."
I just can't find anything referring to this error.
Below is the relevant portion of my code:
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::LINK => $route,
AdCreativeLinkDataFields::MESSAGE => $petition_statement,
AdCreativeLinkDataFields::NAME => $banner_title,
AdCreativeLinkDataFields::IMAGE_HASH => $image_hash,
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => $pageid,
AdCreativeObjectStorySpecFields::INSTAGRAM_ACTOR_ID=>$instagram_id,
AdCreativeObjectStorySpecFields::LINK_DATA=>$link_data
));
$creative = new AdCreative(null,$account_id);
$creative->setData(array(
AdCreativeFields::TITLE => $banner_title,
AdCreativeFields::BODY => $banner_subtitle,
AdCreativeFields::IMAGE_HASH => $image_hash,
AdCreativeFields::OBJECT_TYPE => 'SHARE',
AdCreativeFields::OBJECT_STORY_SPEC=>$object_story_spec
));
$creative->create();
echo 'Creative ID: '.$creative->id . "\n";
$ad = new Ad(null, $account_id);
$ad->setData(array(
AdFields::NAME => $short_name,
AdFields::ADSET_ID => $adset->id,
AdFields::CREATIVE => $creative,
AdFields::TRACKING_SPECS => array(array(
'action.type' => 'offsite_conversion',
'fb_pixel' => $pixel_code,
))
));
$ad->create(array(Ad::STATUS_PARAM_NAME => Ad::STATUS_PAUSED));
Appreciate any help.

I've often said that the only skill you need to be a successful developer is the ability to agonize over a problem for days, read through source code, google it, refactor, rewrite and then realize you forgot something fucking obvious.
AdFields::CREATIVE => $creative,
should read
AdFields::CREATIVE => $creative->id,
But the ability to persist isn't the skill you need. The real skill is to somehow resist the overwhelming urge to chuck your computer out the window and do something productive with your life instead.

After hours of testing it seems Trevor's answer is incorrect. This is the right syntax:
AdFields::CREATIVE => array('creative_id'=>$creative->id)

Related

WP_Query meta_query REGEXP

I am pretty much below beginner level for REGEX/REGEXP and have hit a blocking point in a project I am working in, where I am trying to get the ids for posts that match the search criteria , but I want to restrict the search between 2 sub-strings. I am trying to figure out is how to write the REGEXP in the meta_query:
$args = array(
'post_type'=> 'custom',
'order' => 'DESC',
'posts_per_page' => 10,
'paged' => $page,
'meta_query' => array(
array(
'key' => 'key',
'value' => "title*".$search."*_title",
'compare' => 'REGEXP',
)
),
);
And an example of the field in the DB :
a:302:{s:5:"title";s:10:"Test title";s:6:"_title";s:19:"
Unfortunately none of the combinations I tried based on documentation of SQL REGEXP won't return any values and I am trying to understand how I can pull this off and would appreciate any input.
Also would rather stick to WP_Query for now even though an SQL LIKE "%title%{$search}%_title%" works perfectly , so an alternative solution would be how to set the compare to 'LIKE' and parse it '%' since that is not possible out of the box as the % get escaped I believe.

InvalidArgumentException: Unknown formatter while writing unit tests

I am writing phpUnit tests for our application, So for this I wrote a model factory, after that when I try to run the unit test then I am getting an error like " InvalidArgumentException: Unknown formatter 'publicId' ". I have declared table's all column names in my Model factory. Is it required to mention all columns in the factory?
ModelFactory.php
$factory->define(App\Campaign::class, function (Faker\Generator $faker) {
return [
'public_id' => $faker->publicId,
'client_id' => $faker->clientID,
'name' => $faker->name,
'criteria_age' => $faker->criteriaAge,
'criteria_state' => $faker->criteriaState,
'criteria_postcode' => $faker->criteriaPostcode,
'dncr_required' => $faker->dncrRequired,
'criteria_state' => $faker->criteriaState,
'active' => $faker->active,
'method' => $faker->method,
'server_parameters' => $faker->serverParameters,
'parameter_mapping' => $faker->parameterMapping,
];
});
\tests\Unit\Campaign\CampaignTest.php
namespace Tests\Unit\Campaign;
use App\Campaign;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class CampaignTest extends TestCase
{
use DatabaseTransactions;
public function testCampaignCreation()
{
factory(\App\Campaign::class)->create(['name' => 'tinku']);
$this->seeInDatabase('campaigns', ['name' => 'tinku']);
}
}
after running "phpunit tests/Unit/Campaign/CampaignTest.php" I got this error "InvalidArgumentException: Unknown formatter 'publicId'". I am new to Laravel I know there is a procedure to create factories but I couldn't figure out. Hope someone helps. Thanks.
The formatter is from Faker not Laravel and you can only use Faker formatters Faker ships with.
The error message just tells you that there is no such formatter named publicId. For a list of all Faker formatters please see: https://github.com/fzaninotto/Faker#formatters
If you compare that list with the formatters you've used in your example it becomes more and more obvious that you confused the formatters with some database properties, most likely a translation failure from an existing example? But I think you will know better and this hopefully gives you the information you need to continue setting up your test-case.

Yii2 MaskedInput / MaskedMoney for Integer Only money storage

In my database I store money as an integer, similar to Stripe. For instance 12.99 is stored as 1299. Basically taking the number and dividing by 100.
I'm trying to incorporate this with Yii2 activeForm, specifically using either the MaskInput or MaskMoney widgets. However, I cannot figure out how to configure either widget so that when the value is "1299" it displays as "12.99". So if a person types in "1200" it displays as "12.00".
This is for a simple frontend solution and not backend so I'm not looking for Yii scenarios or behaviors in this question.
I'm not sure if I understood correctly, but this is the closest I've ever got to what you want.
<?php echo \yii\widgets\MaskedInput::widget([
'name' => 'masked-input',
'clientOptions' => [
'alias' => 'decimal',
'digits' => 2,
'digitsOptional' => false,
'radixPoint' => '.',
'groupSeparator' => ',',
'autoGroup' => true,
'removeMaskOnSubmit' => true,
],
]); ?>
The behaviour of the decimal part is what bothers me, but it works as intended.

PHP Unit testing and mocking a file system scandir()

I have a method in a class that scans a directory and creates an array of all the subdirectories. It's pretty simple and works great. However, I would like to add a unit test for this method and I am having a hard time figuring out how.
Here's my problem: I can create a virtual file system using vfsstream and it works fine. However, I can't pass that to my class to create an array from. It needs a real directory to scan. I want to test against a controlled directory (obviously so I know exactly what will the be result of every scan so I can test it). The scanned directory in production may change frequently.
So, my only solution is to create a test-specific fake directory in my test folders, pass that path to my scanner, and then check it against what I know to be in that fake directory. Is this best practice or am I missing something?
Thank you!
Here is some code:
The Test
function testPopulateAuto()
{
$c = new \Director\Core\Components\Components;
// The structure of the file system I am checking against. This is what I want to generate.
$check = array(
'TestFolder1',
'TestFolder2',
);
$path = dirname( __FILE__ ) . "/test-file-system/"; // Contains TestFolder1 and TestFolder1
$list = $c->generateList( $path ); // Scans the path and returns an array that should be identical to $check
$this->assertEquals($check, $list);
}
Sorry if I misunderstood your question, but scandir should work with custom stream. Example:
$structure = array(
'tmp' => array(
'music' => array(
'wawfiles' => array(
'mp3' => array(),
'hello world.waw' => 'nice song',
'abc.waw' => 'bad song',
'put that cookie down.waw' => 'best song ever',
"zed's dead baby.waw" => 'another cool song'
)
)
)
);
$vfs = vfsStream::setup('root');
vfsStream::create($structure, $vfs);
$music = vfsStream::url('root/tmp/music/wawfiles');
var_dump(scandir($music));
Output:
array(5) {
[0]=>
string(7) "abc.waw"
[1]=>
string(15) "hello world.waw"
[2]=>
string(3) "mp3"
[3]=>
string(24) "put that cookie down.waw"
[4]=>
string(19) "zed's dead baby.waw"
}

Parsing a big json then multiple small jsons

My english is not the best, but I will try to explain what I want. So, we have a big json which has a lot of data, now because the server cant show us all the data at the same time, there will be multiple links to small json inside this big json, like when there are 20 comment on a page, and after that there is a "Show more comments" button. My problem is that I dont know how to do this, how to request the smaller json, the parse it. Another question is how to parse a json which links at the end to another json, something like when requestiong a json from graph api and at the end it has
[paging] => stdClass Object
(
[previous] => https://graph.facebook.com/$group_id$/feed?access_token=$valid_token$&__paging_token=$paging_token$&__previous=1
[next] => https://graph.facebook.com/$group_id$/feed?access_token=$valid_token$&limit=25&until=1375310522&__paging_token=$paging_token$
)
When the link from the [next] is opened, it shows more post from that group, then again at its end there is a next link.
As for the first question, I have a bit longer example from the facebook graph api comments
[comments] => stdClass Object
(
[data] => Array
(
[0] => stdClass Object
(
[id] => 53575265890127
[from] => stdClass Object
(
[name] => Pop Dan
[id] => 10000897827962
)
[message] => Random message
[can_remove] => 1
[created_time] => 2013-08-18T20:01:44+0000
[like_count] => 0
[user_likes] =>
)
... more coments...
[paging] => stdClass Object
(
[cursors] => stdClass Object
(
[after] => NTM1ODIxODE5ODA2NTQ0
[before] => NTM1NzUyNjU2NDgwMTI3
)
next] => https://graph.facebook.com/$group_id$_$post_id$/comments?access_token=$accestoken$&limit=25&after=NTM1ODIxODE5ODA2NTQ0
)
)
There I want to continue parsing the json from the [next] and then print it in the same html page, without any breaks or anything between comments. Thanks ;)
Some of the details depend on the language you are using for querying graph api.
Json returned from graph api can consist of json arrays and json objects. Json objects can further have named value entities
If you are doing it in android then first of all you have to get the inner json object from the response first. you can do it in this way
GraphObject go = response.getGraphObject();
JSONObject jso = go.getInnerJSONObject();
Now to get an object from the json you can use
jso.getJSONObject("object_name");
and to get json array you can use
jso.getJSONArray("array_name")
other languages will have similar interfaces
For general understanding of json refer to this link
Regarding your second question you should understand that next is just another query to the graph node but with different parameters. How the parameters can be set depends on the api but in Android you can pur parameters as follows
Bundle params=r.getParameters();
params.putString("offset", ""+25);
r.setParameters(params);
r is the object of type Request