Directus Hooks - how to use the "item.read" - directus

Anyone know how the "item.read" hooks is meant to work?
return [
'filters' => [
'item.update.table:before' => function (\Directus\Hook\Payload $payload) {
$payload->set('field', my_encrypt($payload->get('password'), $key));
return $payload;
},
'item.read.table:before' => function(\Directus\Hook\Payload $payload){
<how to set the 'field' before view??>
return $payload;
},
],
];
I need to unecrypt the stored field for view....

I found the way.
First you need the
'item.read.coll' => function ($payload)
Second you get the data from the payload - alter the data and replace the data in the payload - like this
$data = $payload->getData();
$data[0]['field'] = "NEW DATA";
$payload->replace($data);
return $payload;

Related

How To Access All Indexes In Nested Array (Vue-chartjs)

so I am trying to display data on my doughnut chart and I am having issues accessing my data from a nested array. When I use the following it just gives me the selected index of the nested array.
So I am wondering is there something else I need to do the computed data or if there is something I am doing wrong.
here is the computed property
countEngagementsByStatus () {
const selectedWorkflow = this.allWorkflows.filter(workflow => workflow.id === this.workflowKey)
const res = selectedWorkflow.map(({statuses, id}) => ({
workflow_id: id,
statuses: statuses.reduce((acc, cur) => {
const count = this.allEngagements.filter(({workflow_id, status}) => workflow_id === id && status === cur.status).length;
acc.push(count);
return acc;
}, [])
}))
return res
},
And on my doughnut chart I am accessing the data. *note removed styling data to clean up the question
datasetsfull() {
return {
labels: this.mapStatuses[0].statuses,
datasets: [
{
label: 'Data One',
data: [
//this is the line I have issues with
this.countEngagementsByStatus[0].statuses[0]
]
}
]
}
},
here is an image of what I am getting
Now If I do this
data: [
this.countEngagementsByStatus[0]
]
I get this as a result however it cannot access the array of numbers shown
So my question is, am I doing something wrong with computed property or am I accessing the data incorrectly or both? Lol
Here is a Js Fiddle To give an idea
So my issue was I was wrapping the data in an array
data: [
this.countEngagementsByStatus[0].statuses
]
I changed it to this
data: this.countEngagementsByStatus[0].statuses

Amazon S3 PHP SDK, Transfer folder, but skip specific files?

I am using the Amazon PHP SDK to upload a folder on my server to a bucket. This is working great:
$skip = ['index.html', '_metadata.txt', '_s3log.txt'];
$meta = [
'key' => $options->EWRbackup_s3_key,
'region' => $options->EWRbackup_s3_region,
'bucket' => $options->EWRbackup_s3_bucket,
'directory' => 's3://'.$options->EWRbackup_s3_bucket.'/'.$subdir,
];
$client = new S3Client([
'version' => 'latest',
'region' => $meta['region'],
'credentials' => [
'key' => $meta['key'],
'secret' => $options->EWRbackup_s3_secret,
]
]);
$s3log = fopen($subpath.'/_s3log.txt', 'w+');
fwrite($s3log, "-- Connecting to ".$meta['region'].":".$meta['bucket']."...\n");
$manager = new Transfer($client, $subpath, $meta['directory'], [
'before' => function ($command)
{
$filename = basename($command->get('SourceFile'));
fwrite($this->s3log, "-- Sending file $filename...\n");
},
]);
$manager->transfer();
fwrite($s3log, "-- Disconnecting from ".$meta['key'].":".$meta['bucket']."...");
fclose($s3log);
However, in the folder I am uploading using the Transfer method, there are 3 files I want to skip. They are defined in the $skip variable on line one. I was wondering if there was a way I could get the Transfer to skip these 3 files...
I modified the AWS client in a WordPress plugin I created. The AWS/S3/Transfer.php file is where the uploads are managed, in this case. I modified the private function upload($filename) to look for a boolean return value from the before function:
private function upload($filename)
{
$args = $this->s3Args;
$args['SourceFile'] = $filename;
$args['Key'] = $this->createS3Key($filename);
$command = $this->client->getCommand('PutObject', $args);
if ($this->before) {
if (false!==call_user_func($this->before, $command)) {
return $this->client->executeAsync($command);
}
} else {
return $this->client->executeAsync($command);
}
}
This replaces the original lines:
$this->before and call_user_func($this->before, $command);
return $this->client->executeAsync($command);
with
if ($this->before) {
if (false!==call_user_func($this->before, $command)) {
return $this->client->executeAsync($command);
}
} else {
return $this->client->executeAsync($command);
}
Then, in your declared before function, you can return false if you do not want this particular file uploaded.
I was able to do this because I can control when the AWS PHP SDK is updated and can therefore modify the code it contains. I have not found any hooks in the PHP SDK to do this in a better way.

Update v-for When Data Is Added To Array - VueJS

I'm kinda new to VueJS so I was hoping to get some help. I'm currently returning an array of json objects from a PHP file.
Example:
<?php
/*
Returns an array similar to this:
[
{name: 'foo'},
{name: 'bar'},
{name: 'banana'}
]
*/
echo json_encode(array_values($array));
?>
And I'm appending this array of objects to an already existing array of objects in Vue:
axios.post('http://localhost/get_array.php').then(response => {
// Append returned array to already existing array
for (var i = 0; i <= response.data.length - 1; i++) {
this.existingArray.push(response.data[i])
}
}).catch(e => {
console.log("Error")
})
Right now I'm appending the data with a for loop but I was wondering if VueJS has an in-built function that does this automatically without having to use the for loop?
You can use concat which returns a new concatenated array:
axios.post('http://localhost/get_array.php')
.then(response => {
this.existingArray = this.existingArray.concat(response.data)
})
.catch(e => {
console.log("Error")
})
Updating existingArray with the result of calling concat with the response data should trigger the update.

How to call a function within the same controller?

I have to call a soap service using laravel and done so correctly. This soap service requires me to send a login request prior to sending any other request.
The code I'm using works, but I want to improve by removing the login from all the functions and creating one function.
I tried changing the following for one function:
public function getcard($cardid)
{
SoapWrapper::add(function ($service) {
$service
->name('IS')
->wsdl(app_path().'\giftcard.wsdl')
->trace(true);
});
$data = [
'UserName' => 'xxxx',
'Password' => 'xxxx',
];
$card = [
'CardId' => $cardid,
];
SoapWrapper::service('IS', function ($service) use ($data,$card) {
$service->call('Login', [$data]);
$cardinfo=$service->call('GetCard', [$card]);
dd($cardinfo->Card);
});
}
Into:
public function login()
{
SoapWrapper::add(function ($service) {
$service
->name('IS')
->wsdl(app_path().'\giftcard.wsdl')
->trace(true);
});
$data = [
'UserName' => 'xxxx',
'Password' => 'xxxx',
];
SoapWrapper::service('IS', function ($service) use ($data) {
return $service->call('Login', [$data]);
//$service->call('Login', [$data]);
//return $service;
});
}
public function getcard($cardid)
{
$this->login();
$card = [
'CardId' => $cardid,
];
$cardinfo=$service->call('GetCard', [$card]);
dd($card);
}
But this doesn't work. I also tried it with the commented out part, but that doesn't work. Both options result in an error that it didn't find 'service'.
I know it has something to do with oop, but don't know any other option.
I took this as an example, but I probably implemented it wrong?
So my question is: How do I reuse the login part for all other functions?
Your return statement in the login() method is within the scope of that closure. You need to return the result of the closure as well.
return SoapWrapper::service('IS', function ($service) use ($data) {
return $service->call('Login', [$data]);
});
EDIT:
To explain a little bit. You have a function:
SoapWrapper::service('IS' ,function() {}
Inside of a function : public function login()
If you need to return data from your login() method, and that data is contained within your SoapWrapper::service() method, then both methods need a return statement

Yii2 whenClient validation issue

For some reason I cannot get conditional rule 'required' to work. Even if I reduce the condition to "always return false", required-validation seems to check this unnecessary field:
public function rules() {
return [
[['order_id', 'product_id', 'quantity'], 'required'],
['product_date', 'required',
'whenClient' => "function(attribute, value) {
return false;
}"
],
// more rules here
[['date_create', 'date_update', 'product_date'], 'safe'],
// more rules here
];
}
On form submit save() fails and $model->getErrors() points to product_date as a necessary field. What have I missed? Thank you in advance.
You should add the server-side condition to the rule as well (documentation: when):
['product_date', 'required',
'when' => function ($model) {
return false;
},
'whenClient' => "function(attribute, value) {
return false;
}"
],
whenClient is only for JS on the client side. When the form gets submitted the validation has to be done (or skipped) at the server as well. Usually you should have a when definition if you have whenClient definition. The when definition is much more important, whenClient is just to improve the user experience.
Find more infos here.
Replace
['product_date', 'required',
'whenClient' => "function(attribute, value) {
return false;
}"
],
With
['product_date', function(attribute, value) {
return false;
}],