perl JSON decode is not giving expected result - json

I have below JSON input -
{"links":{"self":"/some/path"},"data":
[{"type":"some_service","id":"foo","attributes":
{"created":true,"active":true,"suspended":false}},
{"type":"some_service","id":"dummy","attributes":{"created":false}}]}
I am using below code -
use strict;
use warnings;
use JSON::XS;
use Data::Dumper;
my $result = decode_json($input);
print Dumper($result) . "\n";
But i am getting below output -
$VAR1 = {
'data' => [
{
'attributes' => {
'active' => bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' ),
'created' => $VAR1->{'data'}[0]{'attributes'}{'active'},
'suspended' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' )
},
'id' => 'foo',
'type' => 'some_service'
},
{
'id' => 'dummy',
'attributes' => {
'created' => $VAR1->{'data'}[0]{'attributes'}{'suspended'}
},
'type' => 'some_service'
}
],
'links' => {
'self' => '/some/path'
}
};
Looks like the value in 'created' is $VAR1->{'data'}[0]{'attributes'}{'active'} which does not seems to be accurate and same happens at other places too.
Am i missing somewhere in code or the JSON input has some error?
Kindly provide your suggestions.

The JSON decoder is just "mapping/pointing" the values to previous values that have already been parsed. You can see your first created points to
$VAR1->{'data'}[0]{'attributes'}{'active'},
, the value of which is true, just like active should be. You are looking at the Data::Dumper representation of the hash array.
If you were to retrieve an element from the Perl variable, you would find that it matches up with your original input:
print $result->{"data"}[0]->{"attributes"}->{"created"}; # prints 1
To print the Data::Dumper output without this occurring, simply set this flag in your script:
$Data::Dumper::Deepcopy = 1;

Why do you think it's inaccurate? If we look at the JSON, active and created both have the same value: true. Maybe you'll find it clearer to dump the structure as follows:
use JSON::XS qw( decode_json );
use Data::Dumper qw( );
my $data = decode_json(<<'__EOI__');
{"links":{"self":"/some/path"},"data [{"type":"some_service","id":"foo","attributes": {"created":true,"active":true,"suspended":false}}, {"type":"some_service","id":"dummy","attributes":{"created":false}}]}
__EOI__
print(Data::Dumper->Dump(
[ JSON::XS::true, JSON::XS::false, $data ],
[qw( true false data )],
));
Output:
$true = bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' );
$false = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
$data = {
'data' => [
{
'attributes' => {
'active' => $true,
'created' => $true,
'suspended' => $false
},
'id' => 'foo',
'type' => 'some_service'
},
{
'attributes' => {
'created' => $false
},
'id' => 'dummy',
'type' => 'some_service'
}
],
'links' => {
'self' => '/some/path'
}
};

Related

Yii2 Internationalization with code instead of a whole sentence

I'm currently working on internationalization for a website using Yii2.
Usually, I use it like this:
Yii::t('frontend', 'Do you have something to eat?')
Then, I have two folders in common\messages called en-EN and id-ID. Each has frontend.php inside of it.
en-EN/frontend.php
return [
];
id-ID/frontend.php
return [
'Do you have something to eat?' => 'Ada yang bisa dimakan?'
];
It works fine, but I don't think it's practical because the sentence is too long and one character miss will not work.
So I tried using something like this:
Yii::t('frontend', 'My.Random.Sentence');
en-EN/frontend.php
return [
'My.Random.Sentence' => 'Do you have something to eat?',
];
id-ID/frontend.php
return [
'My.Random.Sentence' => 'Ada yang bisa dimakan?'
];
It only works for id-ID, but when I change back to english, it still displays My.Random.Sentence instead of Do you have something to eat.
This is my config in i18n.php
return [
'sourcePath' => __DIR__. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
'languages' => ['en-EN','id-ID'],
'translator' => 'Yii::t',
'sort' => false,
'removeUnused' => false,
'only' => ['*.php'],
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages',
'overwrite' => true,
];
And this is in frontend/config/main.php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['lang']))
$_SESSION['lang'] = 'en-US';
return [
// other options
'language' => $_SESSION['lang'],
'sourceLanguage' => 'en-EN',
'components' => [
'i18n' => [
'translations' => [
'frontend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
'backend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
],
],
],
//other options
];
Is this not possible? What is the correct way for my problem?
By default, i18n component doesn't translate the string when $sourceLanguage and $language are same. Instead it returns the source string.
But fortunately you can force it to translate the strings even when the $sourceLanguage and $language properties are same. To do that you need to set $forceTranslation property of MessageSource to true. You can do it in you frontend/config/main.php like this:
return [
// other options
'components' => [
'i18n' => [
'translations' => [
'frontend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
'forceTranslation' => true,
],
// ...
],
],
],
//other options
];

Yii2 Select2 multiple with ajax: Illegal offset type

I use Yii2 and widget Select2. I want onkeyup to search products from table "Products" with options for multiple select, because i must save result in second table "rel_products". I do know why it return error : "Illegal offset type"
Here is model:
public $products = array(); =>because i write result in second table
here is view:
$url = \yii\helpers\Url::to(['/product/prodlist']);
echo $form->field($model, 'products')->widget(Select2::classname(), [
'initValueText' => 'Search for a city ...', // set the initial display text
'model' => $model,
'attribute' => 'products',
'theme' => 'bootstrap',
'options' => ['placeholder' => 'Search for a city ...'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => $url,
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(product) { return product.text; }'),
'templateSelection' => new JsExpression('function (product) { return product.text; }'),
],
]);
Here is Controller:
public function actionProdlist($q = null, $id = null) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
$query = new Query;
$query->select()
->from('product')
->joinWith('translation')
->where(['like', 'title', $q])
->limit(20);
$command = $query->createCommand();
$data = $command->queryAll();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
$out['results'] = ['id' => $id, 'text' => Product::find($id)->title];
}
return $out;
}
change in model:
public $products; =>because i write result in second table

What's the difference between ActiveDataProvider and SQLDataProvider?

I'm a little bit confused. I'm wondering what is the difference between Yii2 ActiveDataProvider and SQLDataProvider? I was looking in the documentation for it, but couldn't get it too.
Could someone explain me when should I use one or another? And what is the difference between it?
Thank you for your time.
SqlDataProvider works with a raw SQL statement which is used to fetch the needed data and ActiveDataProvider can take either a yii\db\Query or yii\db\ActiveQuery object.
SqlDataProvider example:
$provider = new SqlDataProvider([
'sql' => 'SELECT * FROM post WHERE status=:status', //HERE
'params' => [':status' => 1],
'totalCount' => $count,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => [
'title',
'view_count',
'created_at',
],
],
]);
ActiveDataProvider example:
$query = Post::find()->where(['status' => 1]); // ActiveQuery here
$provider = new ActiveDataProvider([
'query' => $query, // and here
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
'title' => SORT_ASC,
]
],
]);

'value' function doesn't work in Yii2 view

in my view I'm trying to add 'value' function, which shows the field if the id = 0, otherwise it doesn't show it. I'm trying to do it like so:
echo $form->field($model, 'test', [
'options' => [
'class' => $twoColumns . ' required',
'value' => function ($model) {
return $model->testvar == 0 ? 'Test' : null;
}
]
])
I've added function into 'value', but somehow it doesn't work. Could someone explain me why?
I'm getting htmlspecialchars error
Closure here is not supported and there is no reason to use it anyway.
You only need something like:
$model->interest = null;
if ($model->is_interest_variable == 0) {
$model->interest = 'Test';
}
echo $form->field($model, 'interest', [
'addon' => [
'append' => [
'content' => '%',
],
],
'options' => [
'class' => $twoColumns . ' required',
]
])->textInput([
'placeholder' => '0.0000',
'class' => 'form-control amount-4'
]);

generate json data with mysql help

Any idea how to get this out put with queries?
$obj = array(
"attr" => array(
"id" => 1,
"rel" => "drive"
),
"data" => "My Documents",
"children" => array(
array(
"attr" => array(
"id" => 2,
"rel" => "file"
),
"data" => "file1.doc",
"state" => ""
)
)
);
echo json_encode($obj);
i need to loop only below part of above code.
array(
"attr" => array(
"id" => 2,
"rel" => "file"
),
"data" => "file1.doc",
"state" => ""
)
any help would be great.
Thanks
$x = 0;
while($row = mssql_fetch_object($query) )
{
$json[$x] = array (
'lastname' => $row->firstname,
'firstname' => $row->lastname
);
$x++;
}
echo json_encode($json);
You might try compiling and installing the third-party JSON UDFs:
http://www.mysqludf.org/lib_mysqludf_json/index.php