Zendesk API using PHP: dynamic content updateMany gives invalid attribute error - php

I try to update a dynamic content field via Zendesk API using PHP API client (https://developer.zendesk.com/rest_api/docs/api-clients/php):
// auth and config goes here...
$itemId = 123;
$variantId = 456;
$data = [
'id' => $variantId,
'content' => 'my example content'
];
$zendesk->dynamicContent()->items($itemId)->variants()->updateMany(['variants' => $data]);
I get an UnknownAttributeError ("Invalid attribute: missing variants parameter"). What did I miss? I tried different ways to give the variant parameter but still the same error. Thanks!

must follow the Format as like Ticket -> updateMany()
Refer Ticket Update Many Test File
$itemId = 12345;
$variantIds = [456,787];
$this->assertEndpointCalled(function () use ($itemId, $variantIds) {
$this->client->dynamicContent()->items($itemId)->variants()->updateMany(
[
'ids' => $variantIds
'content' => 'My Example Content'
]
);
}, "dynamic_content/items/$itemId/variants/update_many.json");

Related

CakePHP 3 autocomplete AJAX responses

I have been trying to get cakephp to suggest input from data that is from my tables like autocomplete. I've done some reading about how some other people have done this but still can't figure it out. Currently it seems that every time my controller is waiting for an ajax request and it is always false. No errors come up from the console some i'm not sure what i'm doing wrong. I tried removing the if ($this->request->is('ajax')) statement but then I get a error about it cannot emit headers.
Here is my search function in InvoicesController which I have taken code from someone else example but failed to implement it.
public function search()
{
if ($this->request->is('ajax')) {
$this->autoRender = false;
pr('b');
$name = $this->request->query['term'];
$results = $this->Invoices->find('all', [
'conditions' => [ 'OR' => [
'id LIKE' => $id . '%',
]]
]);
$resultsArr = [];
foreach ($results as $result) {
$resultsArr[] =['label' => $result['full_name'], 'value' => $result['id']];
}
echo json_encode($resultsArr);
}
}
And here is my search.ctp
<?php use Cake\Routing\Router; ?>
<?php echo $this->Form->input('id', ['type' => 'text']);?>
<script>
jQuery('#id').autocomplete({
source:'<?php echo Router::url(array('controller' => 'Invoices', 'action' => 'search')); ?>',
minLength: 1
});
</script>
This is my invoice table and the ids are what I want to be suggested from what users type in.
I may not be seeing your exact problem but let me point out a few things I see that might help this issue.
Remove this line. It is not necessary
$this->autoRender = false;
Instead you should be doing this at the end. See using the RequestHandler
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', 'resultsArr');
This will return the data without a root key
[
{"label":"Label Value"},
{"label":"Another Label Value"}
]
Or you can do it like this
$this->set('_serialize', ['resultsArr']);
This will return data like
{"resultArr":[
{"label":"Label Value"},
{"label":"Another Value"}
]}
Replace your finder query with this.
$resultArr = $this->Invoices->find('all')
->where(['id LIKE' => $id . '%'])
// If you want to remap your data use map
// All queries are collections
->map(function ($invoice) {
return ['label' => $invoice->full_name, 'id' => $invoice->id];
});
It seems to me you might want to review the new cakephp 3 orm. A lot of hard work went into writing these docs so that they could be easily read and relevant. I'm not one to push docs on people but it will save you hours of frustration.
Cakephp 3 ORM documentation
A few minor things I noticed that are also problems.
You never define $id.
You define $name but never use it.
pr is a debug statement and I am not sure why you have it.
Based on your comment, here is an update on ajax detection.
// By default the ajax detection is limited to the x-request-with header
// I didn't want to have to set that for every ajax request
// So I overrode that with the accepts header.
// Any request where Accept is application/json the system will assume it is an ajax request
$this->request->addDetector('ajax', function ($request) {
$acceptHeaders = explode(',', $request->env('HTTP_ACCEPT'));
return in_array('application/json', $acceptHeaders);
});

Laravel - how to get a parameter of an object in a request file

I am using Laravel 5.3 and I would like to make a query in requests file which I made to have some validation rules for a form where a user can edit his channel. In that file I would like to make a query which would look something like this:
$channelId = Auth::user()->channels()->where('id', $this->id)->get();
So that I can get the channel id and exclude it from the rules array, this is how a file looks like:
public function rules()
{
$channelId = Auth::user()->channels()->where('id', $this->id)->get();
return [
'name' => 'required|max:255|unique:channels,name,' . $channelId,
'slug' => 'required|max:255|alpha_num|unique:channels,slug,' . $channelId,
'description' => 'max:1000',
];
}
I am not sure how to get the channel id of that object that is being updated in the requests file?
When inside of a Requestobject, you can access input as #Silwerclaw correctly said by calling $this->input("id") when you have an input with name "id".
When outside of the object, you can use the facade: Request::input("id").
I used model for that matter, in the request file we can access that object by $this and by model name using this we can access all property, So change just as below.
$channel = Auth::user()->channels()->where('id', $this->channel->id))->first();
But I am not doing like this, i am directly use $this->channel->id in rule as below.
return [
'name' => 'required|max:255|unique:channels,name,' . $this->channel->id,
'slug' => 'required|max:255|alpha_num|unique:channels,slug,' . $this->channel->id,
'description' => 'max:1000',
];
I used a session for that matter, I have stored a key in edit function and then retrieved it in the request file in my query like this and now it works, and the user is not able to manipulate it in the form:
$channel = Auth::user()->channels()->where('id', session('channel_id'))->first();

CakePHP 2 accessing variable defined in the view

In both cakephp-1.2 and cakephp-1.3 I have used the following code snippet in an element named head called from the blog layout:
$this->preMetaValues = array(
'title' => __('SiteTitle', true).' '.$title_for_layout,
'desc' => Configure::read('siteTitle').', '.Configure::read('siteSlogan'),
'keywords' => Configure::read('keywords'),
'type' => 'article',
'site_name' => __('SiteTitle', true),
'imageURL' => $html->url('/img/logo.png', true)
);
if(!isset($this->metaValues)){
$this->metaValues = $this->preMetaValues;
}
else{
$this->metaValues = array_merge($this->preMetaValues, $this->metaValues);
}
<?php echo $html->meta('description',$this->metaValues['desc']); ?>
<?php echo $html->meta('keywords', $this->metaValues['keywords']);?>
I used the above code to define or modify meta-tags values from the any view file. The preMetaValues is regarded as the default values. If there is any metaValues defined in the view, this code will modify it and make the metaValues ready to be used.
Now with cakephp-2.4, the described code generates the following error:
Helper class metaValuesHelper could not be found.
Error: An Internal Error Has Occurred.
Indeed, I don't know why CakePHP regards this variable as helper? and how could I fix this issue?
You can do it by setting the variable from your controller action:
$this->set('title_for_layout', 'Your title');
And then in the view, printing it with:
<title><?php echo $title_for_layout?></title>
You have an example of this at the documentation:
http://book.cakephp.org/2.0/en/views.html#layouts
Just treat them as any other variable.
Why you're using $this object? Can't you use a simple solution like this:
$preMetaValues = array(
'title' => __('SiteTitle', true).' '.$title_for_layout,
'desc' => Configure::read('siteTitle').', '.Configure::read('siteSlogan'),
'keywords' => Configure::read('keywords'),
'type' => 'article',
'site_name' => __('SiteTitle', true),
'imageURL' => $html->url('/img/logo.png', true)
);
if(!isset($metaValues)){
$metaValues = $preMetaValues;
}
else{
$metaValues = array_merge($preMetaValues, $metaValues);
}
<?php echo $html->meta('description',$metaValues['desc']); ?>
<?php echo $html->meta('keywords', $metaValues['keywords']);?>
Finally I have found the solution. It is simply about how to set a variable for the layout from a view. It seems that in earlier versions of cakephp the view was processed before the layout while now in cakephp-2.4 the layout is processed first, so any override of any variable defined in the layout from the view will not success.
Hence, the solution will depend on the set method of the view object something as follows:
//in some view such as index.ctp
$this->set('metaValues', array(
'title', 'The title string...',
'desc' => 'The description string...'
)
);
Also as Alvaro regarded in his answer, I have to access those variable without $this, i.e as local variables.
This answer is inspired from: Pass a variable from view to layout in CakePHP - or where else to put this logic?

Yii php: Displaying a widget in a Tab

i've been using Yii framework for some time now, and i've been really having a good time especially with these widgets that makes the development easier. I'm using Yii bootsrap for my extensions..but i'm having a little trouble understanding how each widget works.
My question is how do i display the widget say a TbDetailView inside a tab?
i basically want to display contents in tab forms..however some of them are in table forms...some are in lists, detailviews etc.
I have this widget :
$this->widget('bootstrap.widgets.TbDetailView',array(
'data'=>$model,
'attributes'=>$attributes1,
));
that i want to put inside a tab
$this->widget('bootstrap.widgets.TbWizard', array(
'tabs' => $tabs,
'type' => 'tabs', // 'tabs' or 'pills'
'options' => array(
'onTabShow' => 'js:function(tab, navigation, index) {
var $total = navigation.find("li").length;
var $current = index+1;
var $percent = ($current/$total) * 100;
$("#wizard-bar > .bar").css({width:$percent+"%"});
}',
),
and my $tabs array is declared like this :
$tabs = array('studydetails' =>
array(
'id'=>'f1study-create-studydetails',
'label' => 'Study Details',
'content' =>//what do i put here?),
...
...);
when i store the widget inside a variable like a $table = $this->widget('boots....);
and use the $table variable for the 'content' parameter i get an error message like:
Object of class TbDetailView could not be converted to string
I don't quite seem to understand how this works...i need help..Thanks :)
You can use a renderPartial() directly in your content, like this:
'content'=>$this->renderPartial('_tabpage1', [] ,true),
Now yii will try to render a file called '_tabpage1.php' which should be in the same folder as the view rendering the wizard. You must return what renderPartial generates instead of rendering it directly, thus set the 3rd parameter to true.
The third parameter that the widget() function takes is used to capture output into a variable like you are trying to do.
from the docs:
public mixed widget(string $className, array $properties=array ( ), boolean $captureOutput=false)
$this->widget('class', array(options), true)
Right now you are capturing the object itself in the variable trying to echo out an object. Echo only works for things that can be cast to a string.

pycurl PostFields option usage

I'm trying to use pycurl to upload a file to Processmaker. app, self.usr, and doc are strings. file is a django file field object. I'm currently just passing the object. I'm fairly sure I'm just passing the incorrect object/type/thing to the ATTACH_FILE field.
The working php POSTFIELDS definition looks like this:
$params = array (
'ATTACH_FILE' => '#/home/test.txt',
'APPLICATION' => $resultCase->caseId,
'INDEX' => 1,
'USR_UID' => $oRandomUser->guid,
'DOC_UID' => '3154812864d55a6e017ff65089604572',
'APP_DOC_TYPE' => 'INPUT',
'TITLE' => "Initial document".date("Y-m-d H:i:s"),
'COMMENT' => "this document was uploaded by the system"
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
And the currently broken python:
c = pycurl.Curl()
data = [
('ATTACH_FILE', (pycurl.READFUNCTION, file.read)),
('APPLICATION', app),
('INDEX' , 1),
('USR_UID', self.usr),
('DOC_UID', doc),
('APP_DOC_TYPE', 'INPUT')
]
post = urllib.urlencode(data)
print post
url = "http://192.168.51.155/sysworkflow/en/green/services/upload"
c.setopt(pycurl.URL, url)
c.setopt(pycurl.VERBOSE, 1)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.POSTFIELDS, post)
c.perform()
c.close()
Any ideas?
I found a way to solve my own issue. Here is what I did, using poster located here: http://atlee.ca/software/poster/ I did the following:
from poster.streaminghttp import register_openers
import poster
register_openers()
url = "http://192.168.51.155/sysworkflow/en/green/services/upload"
params = {
'APPLICATION' : app,
'INDEX' : 1,
'USR_UID' : self.usr,
'DOC_UID' : doc,
'APP_DOC_TYPE' : 'INPUT',
'TITLE' : 'Test',
'ATTACH_FILE' : open(file.path, "rb")
}
datagen, headers = poster.encode.multipart_encode(params)
request = urllib2.Request(url, datagen, headers)
result = urllib2.urlopen(request)
print result.read()
Much easier to use than pycurl! The problem with my first attempt was that POSTFIELDS can't accept files (without some wrangling) and using an HTTPPOST option would work with the files but was difficult to get working with both file data and field data.

Categories