Laravel custom each directive - php

I am working on a custom package for one of my projects and came up with an idea to create a custom blade directive for the elements that I want to loop through.
I made a sample code that does not work:
// WIRES
\Blade::directive('startWire', function($params) {
$wires = [
0 => [
'name' => 'test1',
'image' => 'http://image.jpg'
],
];
return "<?php foreach($wires as $wire): ?>";
});
\Blade::directive('endWire', function() {
return "<?php endforeach; ?> ";
});
And in the Blade file I wan to use it like:
#startWire()
#endWire
But I got the following error:
Array to string conversion
I tried to escape the string but nothin seems to be a good choice. Shall I extend the default Blade #foreach directive or how it supposed to work?
Thank you for your answers!
Gábor

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);
});

Return an #include from Controller DataTables Laravel

I am trying to re-write an table from my view to a DataTables for easy filtering etc. For this I am using yajra/laravel-datatables. Within my original view I would conditionally return the following line:
#include("partials.delete", ["id" => $advice->id, "url" => URL::action("AdviceController#destroy")])
I would now need to return this line from my Controller which uses DataTables. But unfortuanlly, I can't seem to get it right. I also haven't found other people with this issue. My code in the controller is defined like:
return Datatables::of($advice)
->addColumn('delete', function($row){
if($row->original_user_id == \Auth::id()){
return '{{ #include("partials.delete", ["id" => '.$advice->id.', "url" => URL::action("AdviceController#destroy")]) }}';
}
})
->make(true);
But this literally returns the line of code in my view. Could someone help me to return the #include line?
Try using view()->render();
if($row->original_user_id == \Auth::id()){
return view("partials.delete", ["id" => '.$advice->id.', "url" => URL::action("AdviceController#destroy")])->render();
}

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

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");

Yii2 ActiveForm encodeErrorSummary property... what is it intended for?

I was trying to use the Yii2 ActiveForm encodeErrorSummary property because I wanted to put line-breaks on Yii2 validation error messages:
Example code snippet in MODEL file
public function rules()
{
return [['username', 'required', 'message' => 'long message first line here<br> long message last line here']];
}
Example code snippet in VIEW file
$form = ActiveForm::begin(['id' => 'myform',
'encodeErrorSummary' => false
]);
...
echo $form->field($model, 'username');
...
ActiveForm::end();
Official Yii2 Documentation describes encodeErrorSummary property as:
Whether to perform encoding on the error summary.
but it seemed not suitable for that in my case... Maybe it's me misunderstanding something (...error summary)?
So... what is it intended for, then?
Thank you!
It seems like you need to configure the $fieldConfig property like this:
ActiveForm::begin([
'fieldConfig' => [
'errorOptions' => ['encode' => false],
],
]);
for your requirement. The errorSummary is the summary that you echo with
<?= $form->errorSummary($model) ?>
before or after the form. What you want is a behavior at the field level, while this is an option to disable the encoding at the summary level.

Yii2 DropDownList Onchange change Autocomplete Widget "source" attribute?

I have already tried this : yii2 dependent autocomplete widget
but i don't know why it's not working.
here my html with script:
<?= $form->field($model, 'lbt_holder_type')->dropDownList(['prompt' => '--- Select Holder Type ---', 'S' => 'Student', 'E' => 'Employee'],
['onChange' => 'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).autoComplete({source: '. $e_data.');}
'])?>
Autocomplete:
<?= $form->field($model, 'name')->widget(\yii\jui\AutoComplete::classname(), [
'options' => ['class' => 'form-control', 'placeholder' => 'Enter Name/ID'],
'clientOptions' => [
'source' => $s_data,
'autoFill' => true,
'minLength' => '1',
'select' => new yii\web\JsExpression("function( event, ui ) {
$('#libraryborrowtransaction-lbt_holder_id').val(ui.item.id);
}")
],
])?>
i want to change autocomplete source according to dropdownlist value, if S then load $s_data else load $e_data.
Any help with this. Thanks.
Here's my data,
$s_data = (new \yii\db\Query())
->select(["CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as value","CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as label","s_info.stu_info_stu_master_id as id"])
->from('stu_master stu')
->join('join','stu_info s_info','s_info.stu_info_id = stu_master_stu_info_id')
->where('is_status = 0')
->all();
and,
$e_data = (new \yii\db\Query())
->select(["CONCAT(emp_unique_id, ' - ',emp_first_name,' ',emp_last_name) as value","info.emp_info_emp_master_id as id"])
->from('emp_master emp')
->join('join', 'emp_info info', 'info.emp_info_id = emp_info_emp_master_id')
->where('is_status = 0')
->all();
Well, I've added your code snippets to my test yii2 environment to test what's wrong. So there are some problems with your code:
[
'onChange' =>
'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $e_data.');}
']
First of all I noticed what yii apply some escaping for quotation mark symbols for your "S" and "E", and your code in browser looks like "S".
Next, jui autocomplete plugin adds a property to jquery prototype with name "autocomplete" but not "autoComplete". As for as js is case sensitive, this two names looks different for it.
So my solution was to move all js from onchange property to separate js script, as it shown below (for testing purposes you can add it right in your yii view file where you use code provided in your question)
<script>
function holderTypeChangeHandler(ev) {
var value = (this.value);
if(value == 'S'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $s_data . '});
}
if(value == 'E'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $e_data . '});
}
}
window.onload = function(){
$('#libraryborrowtransaction-lbt_holder_type').on('change', holderTypeChangeHandler);
};
</script>
And paste name of this new event handler to your dropdownList's onchange property like this:
['onChange' => 'holderTypeChangeHandler']
UPDATE: ---------------------
Since Yii2 Autocomplete based on JQuery UI autocomplete widget and Yii2 Autocomplete clientOptions contains settings for JUI autocomplete widget, then we can refer to JUI API docs for explanation of the source option. As you can see, this option can be a string (in this case it used as URI to JSON data), a function or an js array of data or js array of objects.
In your question you are using \yii\db\Query to fetch some data from db with help of method all(), which returns an array of data. So finally you need to convert the array of data which you get with \yii\db\Query->all to js array of objects. To do it, use php json functions, particulary for your case you need to use json_encode() function:
// Let's say this is a result of your query to db with use of `\yii\db\Query->...->all();`
$some_array = [
[
"value" => "Val 1",
"label" => "Label 1",
"id" => 1
],
[
"value" => "Val 2",
"label" => "Label 2",
"id" => 2
]
]
// Just convert it to json string
$s_data = json_encode($some_array);
...
// When concat this json string as a value of source attribute for Yii Autocomplete
$('#libraryborrowtransaction-name').autocomplete({source: <?= $s_data ?> });
The same if for your $e_data. Just pay attention, your get your data from db with PHP, but use it with JS, so php array needs to be converted to a string presentation js array of objects, and this conversion you can do with json_encode.

Categories