Yii2 REST API fields (user?fields=id) does not work - rest

I've got the REST API working with the user table provided in the base migration. I can "GET /users" just fine, but according to the docs, I should also be able to "GET /users?fields=id" and receive a response limited to the id fields.
But instead I get the full result set.

Under the topic Fields in Yii2 Guide it says;
// only returns field id and email, provided they are declared in fields()
http://localhost/users?fields=id,email
so you have to override the fields() function to get the expected result.
// explicitly list every field, best used when you want to make sure the changes
// in your DB table or model attributes do not cause your field changes (to keep API backward compatibility).
public function fields()
{
return [
// field name is the same as the attribute name
'id',
// field name is "email", the corresponding attribute name is "email_address"
'email' => 'email_address',
// field name is "name", its value is defined by a PHP callback
'name' => function ($model) {
return $model->first_name . ' ' . $model->last_name;
},
];
}

Related

Netsuite - REST API - Making query with Token Based Authentication (TBA) - (in Python)

This is a follow up to the successful call using Netsuite Token Based Authentication (TBA) REST webservice,
I would like to get some guidance on how to perform a query.
I am supposed to read records like this (please see screenshot)
how can I perform a specifc query (by table for a list of records and also specific record) ?
https://gist.github.com/axilaris/4386c3537d04737d3775c156562b7545 <-- here is the python code for the TBA that has worked successful. I would like to know how to construct the next step on how to perform the query and read specific record (as shown in the screenshot).
This is a custom record with an ID like this customrecord1589
To query a specific record: You're going to need to create/ deploy a RESTlet in Netsuite similar to the following:
/**
* #NApiVersion 2.1
* #NScriptType Restlet
*/
define([
"N/log",
"N/search",
], function (log, search) {
function post(context) {
return JSON.stringify(getCustomRecords(context));
}
function getCustomRecords(context) {
log.debug('POST Context', context);
return search.lookupFields({
//Change CUSTOM_RECORD to the type of custom record you are querying
type: search.Type.CUSTOM_RECORD + '1589',
id: context.id,
columns: context.fields,
});
}
return {
post: post,
};
});
In your Python Script: Make sure you change the URL of the request to the deployment URL of this new RESTlet. Also, make sure to pass any parameters you need (like 'id' or 'fields' in my example) in your POST request payload. So instead of:
payload = {
"name":"value",
"foo":"bar",
"duck":"hunt",
}
pass
payload = {
"id":"9999999",
"fields": ["custrecord_field1", "custrecord_field2"],
}
where id is the internalid of the record you want to query and the fields array are the internalids of the fields you want values from.
If this goes successfully, the result should show up as conn.text in your python script!

Add a Field to a CrudController that ONLY passes values to Store / Update Methods

I'm trying to handle how a field within a CrudController stores or updates the data on the particular model in a completely custom way. I would like the traitStore() and traitUpdate() methods to ignore this field entirely, but would like the data to still be passed in via the request. This is specifically in reference to a many-many relationship using a select2_multiple field.
I would like it so that the relationship ID's are passed via the request object to the Store or Update methods, but I DO NOT want the traitStore() or traitUpdate() methods to actually perform updates on that particular field reference.
For example...
I have this field within my crud controller
$this->crud->addField(
[
'label' => "Groups",
'type' => 'select2_multiple',
'name' => 'groups',
'entity' => 'groups',
'attribute' => 'title',
'model' => "App\Models\Group",
'pivot' => true
]
);
And I'm overriding the Store and Update Methods like so.
public function store()
{
$this->crud->setValidation(UserRequest::class);
// WOULD LIKE TO SAVE EVERYTHING BUT IGNORE THE GROUPS FIELD
$response = $this->traitStore();
// DO WHATEVER I WANT WITH GROUPS AT THIS POINT
$groups = $request->groups
return $response;
}
public function update()
{
$this->crud->setValidation(UserRequest::class);
// WOULD LIKE TO SAVE EVERYTHING BUT IGNORE THE GROUPS FIELD
$response = $this->traitUpdate();
// DO WHATEVER I WANT WITH GROUPS AT THIS POINT
$groups = $request->groups
return $response;
}
Looking at my comments I would like to get a reference to the groups and handle updating the model however I want.
I've tried to unset the groups value in the request, unset($this->request{'groups'}), but it still updates / removes the relationships when I do that.
Here is what you need to do to remove the references from being updated by the CrudController.
public function update()
{
$this->crud->setValidation(UserRequest::class);
$request = clone $this->request;
$this->crud->request->request->remove('groups');
$this->crud->removeField('groups');
$groups = $request->groups
$response = $this->traitUpdate();
return $response;
}
I found an easy way to ignore/pass form field.
Example:
In your form fields have first_name, last_name, gender and in your database is only have fullname, gender then you wanna create/update the form, it will show Column not found: 'first_name' not found...,
How to fix it:
Add $fillable in the model and fill the array data with name field that you want to store/update. In example case $fillable = ['fullname', 'gender'];
Then, just use mutators inside the model too.
public function setFullnameAttribute(){
return $this->attributes['fullname'] = \Request::input('first_name') . ' ' . \Request::input('last_name');
}
NB: You should have hidden field name 'fullname' in your CrudController.
$this->crud->addField(['name' => 'fullname', 'type' => 'hidden']);

Web Services call - core_group_create_groups - Unexpected keys (courseid) detected in parameter array

I'm having an issue with a specific Rest webservice call :
Method: core_group_create_groups
Is throwing the following error:
Unexpected keys (courseid) detected in parameter array.
I'm passing in the exact properties defined in the documentation:
_ //List of group object. A group has a courseid, a name, a description and an enrolment key.
list of (
object {
courseid int //id of course
name string //multilang compatible name, course unique
description string //group description text
descriptionformat int Default to "1" //description format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN)
enrolmentkey string Optional //group enrol secret phrase
idnumber string Optional //id number
}
)_
I'm using Moodle 3.1+ (Build: 20160623)
Any ideas why it doesn't like courseid in the request even though its a valid parameter?
having problems here with Moodle documentation too.
parameters marked as optional in docs actually are required.
example:
in the method 'core_role_assign_roles' you MUST pass 'contextlevel' and 'instanceid', the doc say is optional.
I just used the 'core_group_create_groups' method and it worked fine. this time the docs were correct passed 3 params: courseid / name / description.
used like:
"groups[0][courseid]=2&groups[0][name]=grupo2&groups[0][description]=desc grupo2"
maybe double check if the code you are passing in courseid a) exists; b) is really a course id.
hope it helps,
rodrigo
You have to call the webservice using the "groups" key to make it works correctly (i.e. this code works for me in PHP):
`$this->callWSFunction(
'core_group_create_groups',[
groups =>[
0 =>
[
'courseid' => $id,
'name' => $groupname,
'description' => $groupdescription
]
]
]
);`

How to get specific fields or update theme and get the relation fildes from api calls in yii2 REST API?

I'm trying default yii2 api rest calls GET to get some model fields or PUT to update some model fields but I can't find a way to do this. I can only get all the fields or update theme all. Any help to do this? And how can I get the related relational field to this model?
I'm trying like this like
GET localhost/my-website-name/api/web/v1/vendors/
PUT localhost/my-website-name/api/web/v1/vendors/1
one way that I know for customizing fields is overriding fields function in your model like this
public function fields() {
return [
'id',
'iso3' => function() {
return base64_encode($this->iso3);
}
];
}
How to get specific fields and get the relation fields from api calls?
By default, yii\db\ActiveRecord::fields() returns all model attributes which have been populated from DB as fields, while yii\db\ActiveRecord::extraFields() should return the names of model's relations.
Take this model for example:
class Image extends ActiveRecord
{
public function attributeLabels()
{
return [
'id' => 'ID',
'owner_id' => 'Owner ID',
'name' => 'Name',
'url' => 'Url',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
public function getOwner()
{
return $this->hasOne(Owner::className(), ['id' => 'owner_id']);
}
public function extraFields()
{
return ['owner'];
}
}
Here I did override the extraFields() method to define the owner relationship. Now if I want to retreive all images but selecting id and name fields only and each resource should also hold its related owner data I would simply request this url:
GET example.com/images?fields=id,name&expand=owner
note: you can also use comma separation to expand more than one relation
In case you want to permanently remove some fields like created_at and updated_at you can also override the fields() method:
public function fields()
{
$fields = parent::fields();
unset($fields['created_at'], $fields['updated_at'], $fields['owner_id']);
return $fields;
/*
// or could also be:
return ['id', 'name','url'];
*/
}
this way the following request should only return image's id, name and url fields along with their related owner :
GET example.com/images?expand=owner
If owner's fields should be filtered too then override its fields() method too in its related class or a child class of it that you tie to the image model by using it when defining the relation.
See official documentation for further details.
PUT to update some model fields
Yii only updates dirty attributes. so when doing:
PUT example.com/images/1 {"name": "abc"}
the generated SQL query should only update the name column of id=1 inside database.
Hello i manage to find a solution for this situations
first get some model fields only and with related entities fildes:
public function fields() {
return [
'name',
'phone_number',
'minimum_order_amount',
'time_order_open',
'time_order_close',
'delivery_fee',
'halal',
'featured',
'disable_ordering',
'delivery_duration',
'working_hours',
'longitude',
'latitude',
'image',
'owner' => function() {
$owner = Owners::findOne($this->owner_id);
return array($owner);
}
];
}
if you want to remove some fildes
public function fields()
{
$fields=parent::fields();
unset($fields['id']);
return $fields;
}
update only specific fields
public function beforeSave($insert)
{
$lockedValues = ['name', 'halal', 'featured', 'latitude', 'longitude', 'image', 'status', 'created_at', 'updated_at'];
foreach ($lockedValues as $lockedValue) {
if ($this->attributes[$lockedValue] != $this->oldAttributes[$lockedValue])
throw new ForbiddenHttpException($lockedValue . " can't be changed.");
}
return parent::beforeSave($insert); // TODO: Change the autogenerated stub
}

sharepoint 2010 get value of choice field through api call

I have a sharepoint list ImageList, i have a column which stores its type
The column name is ImageType
the choices are "profile pic","thumbnail" etc
i want to fetch these choice values for this field
i tried accessing it using
http://myintranet:2010/sites/ImagesGallery/_vti_bin/listdata.svc/ImageList?$expand=ImageType
but it is not containing the choice values in it!
How can i get them?
The query:
http://myintranet:2010/sites/ImagesGallery/_vti_bin/listdata.svc/ImageList?$expand=ImageType
returns list items values for List resource only.
In order to retrieve field resource itself, the different endpoint have to be specified, in particular:
http://myintranet:2010/sites/ImagesGallery/_vti_bin/listdata.svc/ImageListImageType
It is assumed that list name is ImageList and field name is
ImageType
Example
$.getJSON(endpointUrl)
.done(function(data)
{
//print field choice options
data.d.results.forEach(function(item){
console.log(item.Value);
});
})
.fail(function(error){
console.log(JSON.stringify(error));
});