how to pass variables "$tid, $id" into raw function? - mongodb

when i call $id and $tid in raw function to fetch some data from sub document of mongodb collection it show me an error these two variables are undefined($tid,$id)?
<?php
$id=IntValue;
$tId=IntValue;
if($tId==0)
{
$maxPlayers=0;
}
else
{
$result = DB::collection('PrizeDistributionTemplate')->raw(function($collection)
{
return $collection->aggregate(array(
array(
'$match' => array( 'id' => $id,'templates.tId' => $tid)
),
array( '$unwind' => '$templates' ),
array(
'$match' => array( 'id' => $id,'templates.tId' => $tid)
),
));
});
$result=json_decode(json_encode($result),true);
$maxPlayers=$result['result'][0]['templates']['maxPlayers'];
$maxPlayers=intval($maxPlayers)+2;
}
?>

When you use a callback function in PHP, the function as it own scope and can't access variables from outside of it's scope.
$foo = true;
DB::collection('something')->raw(function ($collection) {
echo $foo;// $foo is undefined here, this create an error
});
echo $foo;// here it work
But you can feed your callback with variables using the PHP use keyword:
$foo = true;
DB::collection('something')->raw(function ($collection) use ($foo) {
echo $foo;// now it works
});

It will work great with bulk addition, this way you just need to create on array and pass it.
$temp = [
[
'item' => "envelopes"
],
[
'item' => "envelopesas"
],
[
'item' => "lala"
]
];
$userData = DB::table('log') - > raw(function ($collection) use($temp)
{
return $collection - > insertMany($temp);
});

Related

when selecting an option, show data from the database - Woocommerce custom fields (checkout)

I have the following code to generate a select and bring the values inside the options:
add_action('woocommerce_after_order_notes', 'cliente_woocommerce');
function cliente_woocommerce($checkout)
{
global $wpdb;
/// in tab_clientes have id, nome, cpf, cnpj, ie, email, data_since columns
$results = $wpdb->get_results("SELECT * FROM tab_clientes");
$options = ['' => __('Selecione o cliente')];
foreach ($results as $result) {
$options[$result->nome] = $result->razao_social;
}
echo '<div id="cliente_woocommerce"><h2>' . __('Cliente') . '</h2>';
woocommerce_form_field(
'cliente',
[
'type' => 'select',
'class' => ['cliente form-row-wide'],
'label' => __('Campo de Teste (Cliente)'),
'options' => $options,
],
$checkout->get_value('cliente')
);
woocommerce_form_field(
'nome',
[
'type' => 'text',
'class' => ['nome form-row-wide'],
'label' => __('Razão Social'),
'default' => '',
],
$checkout->get_value('nome')
);
woocommerce_form_field(
'cnpj',
[
'type' => 'text',
'class' => ['cnpj form-row-wide'],
'label' => __('CNPJ'),
'default' => '',
],
$checkout->get_value('cnpj')
);
echo '</div>';
}
with the following script:
$(document).ready(function()
{
$('#cliente').change(function() {
$('#nome').val( $( this ).val() );
});
$('#nome').change(function() {
$('#cnpj').val( $( this ).val() );
});
});
When I select the client, the #nome field (razão social - in the table = razao_social) appears with the correct value, but the value repeats within CNPJ field.
what am I doing wrong?

Guzzle HTTP send file stream throws error- "json_encode error: Type is not supported"

I am using Guzzle client in my Laravel application to send a request to API endpoint along with a file. I am achieving this by creating a multipart data as follow-
$rid = $this->wsl->curlWSl('POST', '/throttle', [], [
'verify' => false,
'multipart' => [
[
'name' => 'csv',
'contents' => fopen($dest, 'rb')
],
[
'name' => 'name',
'contents' => $request->input('name')
],
[
'name' => 'description',
'contents' => $request->input('description')
],
[
'name' => 'header',
'contents' => '1'
]
]
]);
The curlWSL method I have defined as given below -
public function curlWSl(string $method, string $path, Array $headers = [], Array $data = null, Array $options = [])
{
$endPoint = $this->getUri() . $path;
if (!empty($headers)) {
$options['headers'] = $headers;
}
if ($method == 'GET' && $data) {
$endPoint .= http_build_query($data);
}
if ($method == 'POST') {
$options['json'] = $data;
}
try {
$response = $this->getClient()->request(
$method,
$endPoint,
$options
);
} catch (\Exception $ex) {
return ['statusCode'=>$ex->getCode(), 'errorMsg' => $ex->getMessage()];
}
return json_decode($response->getBody()) ?? (string)$response->getBody();
}
Doing this, throws me an exception -
InvalidArgumentException {#296 ▼
#message: "json_encode error: Type is not supported"
#code: 0
#file: "/var/www/html/vendor/guzzlehttp/guzzle/src/functions.php"
#line: 327
trace: {▶}
}
I am sure, this is because of fopen file stream because when I remove that, my request is received at the endpoint.
I am also looking for some help on how can I validate the request data at the API endpoint using laravel validators.
Your help is much appreciated.
Note: I am much looking to pass the file object and not only the file data, which I am able to do with file_get_contents.
I got it fixed.
The Guzzle don't process too many parameters to send as in request to the endpoint. As we are setting up $options['json'] = $data and this considers the data in json format which is actually not. So, I had to turn it to multipart instead of json to make things working. I had to modify the call as below -
$rid = $this->wsl->curlWSl('POST', '/throttle', [], [
[
'name' => 'csv',
'contents' => fopen($dest, 'rb')
],
[
'name' => 'name',
'contents' => $request->input('name')
],
[
'name' => 'description',
'contents' => $request->input('description')
],
[
'name' => 'header',
'contents' => '1'
]
]);
And in the method curlWSL, I modified the code as to accept the data as multipart-
public function curlWSl(string $method, string $path, Array $headers = [], Array $data = null, Array $options = [])
{
$endPoint = $this->getUri() . $path;
if (!empty($headers)) {
$options['headers'] = $headers;
}
if ($method == 'GET' && $data) {
$endPoint .= http_build_query($data);
}
if ($method == 'POST') {
$options['multipart'] = $data;
}
try {
$response = $this->getClient()->request(
$method,
$endPoint,
$options
);
} catch (\Exception $ex) {
return ['statusCode'=>$ex->getCode(), 'errorMsg' => $ex->getMessage()];
}
return json_decode($response->getBody()) ?? (string)$response->getBody();
}

Yii2-advanced : dataProvider

I want to increment my dataProvider in siteController. That is, at each iteration, my dataProvider should be incremented by 1 & renamed as dataProvider1,dataProvider2,dataProvider3,....& so on.
I tried to append $i to dataProvider, but it says 'dataProvider can't be converted to String...!'
My actionIndex is as follows :
public function actionIndex()
{
$query = new \yii\db\Query;
for ($i = 1; $i <= 20; $i++) {
$query->select('*')->from('business_main_categories')->where(['bmc_id' => $i]);
$query->createCommand();
$dataProvider.$i = new ActiveDataProvider([
'query' => $query,
'pagination' => false,
]);
return $this->render('index', [
'dataProvider' => $dataProvider.$i,
]);
}
}
And, I also want to user that dataProvider in my 'index.php' with iterations; I tried to insert a for loop & written all statements in 'echo', but I'm unable to get it done.
My way to access it in 'index.php' is as follows :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'summary' => '',
'columns' => [
[
'attribute' => 'bmc_image',
'format' => 'html',
'label' => '',
'value' => function ($data) {
return Html::img($data['bmc_image'],
['width' => '190px']);
},
],
]
]); ?>
Please help me to solve my issue.
I solved my problem without using gridview. As follows -
My SiteController -
public function actionIndex()
{
$searchModel = new BusinessMainCategoriesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->pagination->pageSize = $dataProvider->getTotalCount(); //-1 : disable
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
using this code I get all records in dataProvider from my db.
(Note that, I'm using ActiveDataProvider in my 'BusinessMainCategoriesSearch' model)
And, my index.php is -
<?php
$m = $dataProvider->getModels();
foreach ($m as $dp) {
echo "<img src = '".$dp['bmc_image']."' />";
echo '<center><font color = "white">'.$dp['bmc_name'].'<font/></center>';
} ?>
It worked great for me & it's a easiest way to do so.

How to populate Yii2 Autocomplete with AJAX call

I am trying to switch to Yii2 from Yii 1.1. This was source attribute of TextAreaJuiAutoComplete widget
'source'=>"js:function(request, response) {
$.getJSON('".$url"', {
term: extractLast(request.term)
}, response);
}",
This is not working in Yii2 with yii\jui\AutoComplete anymore. Can anyone give me a hint what is the cause? Underlying JavaScript objects should be the same.
If I put following code it works, but I want to use ajax calls instead.
'source' => [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby" ],
Try this:
use yii\web\JsExpression;
.....
.....
'source'=>new JsExpression("function(request, response) {
$.getJSON('".$url."', {
term: request.term
}, response);
}"),
Try this:
AutoComplete::widget([
'name'=>'myacfield',
'clientOptions' => [
'source' => Url::to(['autocomplete']),
'minLength'=>'2',
],
'options'=>[
'class' => 'form-control'
]
]);
But your AutoComplete action must return a one dimensional array like
...
$rs = Yii::$app->db->createCommand($sql)->queryAll();
$row_set = [];
foreach ($rs as $row)
{
$row_set[] = $row['name']; //build an array
}
echo json_encode($row_set); //format the array into json data
Examle with like.
Controller:
public function actionSearch($term)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$rs = Cure::find()->where(['like', 'name_uz', $term])->all();
if($rs !=null){
$row_set = [];
foreach ($rs as $row)
{
$row_set[] = $row->name_uz; //build an array
}
return $row_set;
}else{
false;
}
}
In view:
<? use yii\jui\AutoComplete;?>
<?= AutoComplete::widget([
'model' => $model,
'attribute' => 'country',
'options' => ['class' => 'form-control'],
'clientOptions' => [
'source' => Url::to(['cure/search']),
'minLength'=>'2',
],
]); ?>

Get all parameters after action in Zend?

When I call a router like below in Zend:
coupon/index/search/cat/1/page/1/x/111/y/222
And inside the controller when I get $this->_params, I get an array:
array(
'module' => 'coupon',
'controller' => 'index',
'action' => 'search',
'cat' => '1',
'page' => '1',
'x' => '111',
'y' => '222'
)
But I want to get only:
array(
'cat' => '1',
'page' => '1',
'x' => '111',
'y' => '222'
)
Could you please tell me a way to get the all the params just after the action?
IMHO this is more elegant and includes changes in action, controller and method keys.
$request = $this->getRequest();
$diffArray = array(
$request->getActionKey(),
$request->getControllerKey(),
$request->getModuleKey()
);
$params = array_diff_key(
$request->getUserParams(),
array_flip($diffArray)
);
As far as I know, you will always get the controller, action and module in the params list as it is part of the default. You could do something like this to remove the three from the array you get:
$url_params = $this->getRequest()->getUserParams();
if(isset($url_params['controller']))
unset($url_params['controller']);
if(isset($url_params['action']))
unset($url_params['action']);
if (isset($url_params['module']))
unset($url_params['module']);
Alternatively as you don't want to be doing that every time you need the list, create a helper to do it for you, something like this:
class Helper_Myparams extends Zend_Controller_Action_Helper_Abstract
{
public $params;
public function __construct()
{
$request = Zend_Controller_Front::getInstance()->getRequest();
$this->params = $request->getParams();
}
public function myparams()
{
if(isset($this->params['controller']))
unset($this->params['controller']);
if(isset($this->params['action']))
unset($this->params['action']);
if (isset($this->params['module']))
unset($this->params['module']);
return $this->params;
}
public function direct()
{
return $this->myparams();
}
}
And you can simply call this from your controller to get the list:
$this->_helper->myparams();
So for example using the url:
http://127.0.0.1/testing/urls/cat/1/page/1/x/111/y/222
And the code:
echo "<pre>";
print_r($this->_helper->myparams());
echo "</pre>";
I get the following array printed:
Array
(
[cat] => 1
[page] => 1
[x] => 111
[y] => 222
)
How about this?
In controller:
$params = $this->getRequest()->getParams();
unset($params['module'];
unset($params['controller'];
unset($params['action'];
Pretty clunky; might need some isset() checks to avoid warnings; could jam this segment into its own method or helper. But it would do the job, right?