How can I access private value from object - yii2

I have the following object
[yii\authclient\clients\Twitter_ef71f520786335688cd762d29aaa2ac98b6bd42f_token] => yii\authclient\OAuthToken Object
(
[tokenParamKey] => oauth_token
[tokenSecretParamKey] => oauth_token_secret
[createTimestamp] => 1447473086
[_expireDurationParamKey:yii\authclient\OAuthToken:private] =>
[_params:yii\authclient\OAuthToken:private] => Array
(
[oauth_token] => 48575497-RTIItaMJBC5LrFl0I2TjYw0ihByC0QuRdRxf44tVX
[oauth_token_secret] => IcdvTgwiclWGNhX4TrsDjEkEdNwVF7l1XzXmgpNstGfkV
[user_id] => **********
[screen_name] => ***********
[x_auth_expires] => 0
)
)
and in the above object I want to access the parameter oauth_token and oauth_token_secret which are under _params:yii\authclient\OAuthToken:private
How do I get those values in php?

https://github.com/yiisoft/yii2-authclient/blob/master/OAuthToken.php#L86
yii\authclient\OAuthToken has public method getParams() and getParam($name)

Related

How to use custom php function to filter in ActiveDataProvider

I have this problem: I need to get data from database and filter them. but then I need to use custom php function to filter those filtered results using data from it.
Clasic search function in ActiveDataProvider
public function search($params) {
$query = Passenger::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
// I guess my function would go like here
Passenger::filterResultsEvenMore($dataProvider);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'passenger_id' => $this->passenger_id,
// ...
'version' => $this->version,
'status' => $this->status,
]);
return $dataProvider;
}
So my question is how to work with results of dataProvider because if I vardump the variable it looks like this and no actual data there.
yii\data\ActiveDataProvider Object
(
[query] => common\models\PassengerQuery Object
(
[sql] =>
[on] =>
[joinWith] =>
[select] =>
[selectOption] =>
[distinct] =>
[from] =>
[groupBy] =>
[join] =>
[having] =>
[union] =>
[params] => Array()
[_events:yii\base\Component:private] => Array()
[_behaviors:yii\base\Component:private] => Array()
[where] => Array
(
[status] => 1
)
[limit] =>
[offset] =>
[orderBy] =>
[indexBy] =>
[emulateExecution] =>
[modelClass] => common\models\Passenger
[with] =>
[asArray] =>
[multiple] =>
[primaryModel] =>
[link] =>
[via] =>
[inverseOf] =>
)
[key] =>
[db] =>
[id] =>
[_sort:yii\data\BaseDataProvider:private] =>
[_pagination:yii\data\BaseDataProvider:private] =>
[_keys:yii\data\BaseDataProvider:private] =>
[_models:yii\data\BaseDataProvider:private] =>
[_totalCount:yii\data\BaseDataProvider:private] =>
[_events:yii\base\Component:private] => Array()
[_behaviors:yii\base\Component:private] =>
)
UPDATE
I need to use function like this for each record:
if (myFunction(table_column_1, table_column_2)) {
result_is_ok_return_it
} else {
do_not_return_this_record
}
Why do you don't add your additional filters to query object used in DataProvider?
You can parse your conditions to $query->andFilterWhere(). If you need custom function for it just modify $dataProvider->query object inside function. After execute query in data provider you can only filter results by manually filter array of models stored in $dataProvider->models
To get result use models property or getModels()
For example,
$dataProvider->models;
OR
$dataProvider->getModels();
I think I came across a solution, (looks like it is working)
http://www.yiiframework.com/doc-2.0/yii-data-basedataprovider.html#setModels()-detail
After I do all my usual search stuff as described in question at beginning, I would do something like this using setModels() function
class PassengerSearch extends Passenger
public $status; // virtual attribute not present in database table
public function rules()
{
return [
// ... some other rules
[['status'], 'safe'],
];
}
// ...
$filtered_models = [];
$filter_models = false; // if you only want to filter if there is some value
foreach ($dataProvider->models as $model) {
// if ($model->status == 1) // example
if (!empty($this->status) && $model->status == $this->status) { // better approach, using virtual attribute $status
$filter_models = true;
$filtered_models[] = $model;
}
}
if ($filter_models)
$dataProvider->setModels($filtered_models);
return $dataProvider;
}

TYPO3 Extbase JsonView FAL

This is my Controller Action:
public function jsonAction()
{
$this->view->setVariablesToRender(array('produkte'));
$this->view->setConfiguration(
array(
'produkte' => array(
'_descendAll' => array(
'only' => array('titel', 'beschreibung', 'bild', 'download', 'categories'),
'_descend' => array(
'bild' => array(),
'download' => array(),
'categories' => array(),
)
)
)
)
);
$this->view->assign('produkte', $this->produktRepository->findAll());
}
and I get a very nice JSON-String. Unfortunately I get only the PID und UID for contained files (FAL). How can I get the full object or at least the path to the contained files?
/**
* Returns the bild
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $bild
*/
public function getBild()
{
return $this->bild;
}
/**
* Returns the download
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $download
*/
public function getDownload()
{
return $this->download;
}
Try descending to the originalResource of the FileReference and expose publicUrl:
$this->view->setConfiguration(
array(
'produkte' => array(
'_descendAll' => array(
'only' => array('titel', 'beschreibung', 'bild', 'download', 'categories'),
'_descend' => array(
'download' => array(
'_descendAll' => array(
'_only' => array('originalResource');
'_descend' => array(
'originalResource' => array(
'_only' => array('publicUrl');
);
);
);
),
)
)
)
)
);
The originalResource is partly a computed property, on invoking the getter-method the entity will be retrieved automatically - that's how it's implemented in Extbase's FileReference model.
/**
* #return \TYPO3\CMS\Core\Resource\FileReference
*/
public function getOriginalResource()
{
if ($this->originalResource === null) {
$this->originalResource = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileReferenceObject($this->getUid());
}
return $this->originalResource;
}
However, please make sure to write the JSON view configuration correct. All control-related properties are prefixes with an underscore _ - in the code examples above it should be _only instead of only. Valid control-names are _only, _exclude, _descend, _descendAll, _exposeObjectIdentifier, _exposedObjectIdentifierKey, _exposeClassName.
Find more details in the Flow documentation, which is still valid for the JsonView in TYPO3 CMS.
Try using \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> instead of \TYPO3\CMS\Extbase\Domain\Model\FileReference for your FAL properties in your Model.
I dont need more than one File, but after i changed this i get the publicUrl.

Google Visualization JSON PHP

I spent the whole day trying to get a pie chart with Google Charts.
I am getting my results from a MySQL Database using PHP.
The result is a JSON which looks like this:
stdClass Object
(
[cols] => Array
(
[0] => stdClass Object
(
[label] => Firma
[type] => string
)
[1] => stdClass Object
(
[label] => Zeit
[type] => number
)
)
[rows] => Array
(
[0] => stdClass Object
(
[Firma] => Firma1
[Zeit] => 60
)
[1] => stdClass Object
(
[Firma] => Firma2
[Zeit] => 40
)
)
)
Javascript Code looks like this:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable(<?=$jsongesamtzeiten;?>);
//data.addColumn('string', 'Firma');
//data.addColumn('number', 'Zeit');
//data.addRows([ ['Firma1',40], ['Firma2',60] ]);
var options = {
title: 'Arbeitsverteilung gesamt',
colors: ['#3B2BC1', '#7EBB58'],
width: 600,
height: 400,
backgroundColor: { stroke: "#CCC", strokeWidth: 2, fill: "#f5f5f5" }
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
};
I get a:
Cannot read property '1' of undefined
as reply.
If I uncomment the data.addColumn and data.addRows and remove the <?=$jsongesamtzeiten;?> it works. But that's not what I want, because I want to recieve the data from a MySQL-database.
I did many google-searches and found some similiar questions here, but nothing helped me.
Thanks.
I believe the problem lies in the JSON rows column value keys.
It appears you're naming the object keys according to their column labels.
However, the key for a value should simply be v
See the first example under the DataTable class reference
Try changing the JSON as follows...
stdClass Object
(
[cols] => Array
(
[0] => stdClass Object
(
[label] => Firma
[type] => string
)
[1] => stdClass Object
(
[label] => Zeit
[type] => number
)
)
[rows] => Array
(
[0] => stdClass Object
(
[v] => Firma1
[v] => 60
)
[1] => stdClass Object
(
[v] => Firma2
[v] => 40
)
)
)
Also, since you're already including the column and row definitions in your JSON,
you will not need to use data.addColumn or data.addRows
only need...
var data = new google.visualization.DataTable(<?=$jsongesamtzeiten;?>);
(once the format is correct)

Update a HasMany records

I am converting a working app from cakephp2 to cakephp3. I'm struggling to get a form that updates hasMany records to work.
The app has the following structure:
MODELS:
use Cake\ORM\Table;
use Cake\Validation\Validator;
class AwardsTable extends Table
{
public function initialize(array $config)
{
$this->hasMany('Levels', ['sort' => 'sort_order']);
}
}
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;
class Award extends Entity
{
protected $_accessible = [
'name' => true,
'url' => true,
'organisation' => true,
'detail' => true,
'logo' => true,
'levels' => true,
'Levels' => true
];
}
IN THE FORM:
<?= $this->Form->input("levels.$i.name", 'label'=>false,'type'=>'text','value' => $award->name]);?>
<?= $this->Form->input("levels.$i.id", ['value' => $award->id]); ?>
CONTROLLER
$this->Awards->patchEntity($award, $this->request->data, ['associated' => ['Levels']]);
if ($this->Awards->save($award)) {
$this->Flash->success(__('Your Award has been saved.'));
$this->redirect(['action' => 'index']);
}
This seems inline with what is recommended here: http://book.cakephp.org/3.0/en/views/helpers/form.html#associated-form-inputs
I've tried a few variations with capitalisation & pluralisation. The award data saves correctly but the associated levels data does not save.
What am I missing to get the has_many association data to save?
EDIT: Example Data array submitted:
2016-01-28 23:32:56 Error: Array
(
[id] => 4
[name] => test award
[organisation] => test org
[url] => http://www.example.com
[detail] =>
[levels] => Array
(
[0] => Array
(
[name] => test 1
[id] => 4
)
[11] => Array
(
[name] => test
[id] => 16
)
)
[image] => Array
(
[name] =>
[type] =>
[tmp_name] =>
[error] => 4
[size] => 0
)
)
In LevelEntity verify if 'id' is accessible
protected $_accessible = [
'*' => true,
'id' => true,
];

How to implement filtering of a CGridView table for an ENUM columnt in Yii?

In a Yii application I display the data as a table. I use CGridView, that deals for me with (search based) data filter and sorting. It works.
Now I added an ENUM column status to the user database table. In the grid I can sort and filter this, but only by the value in the table. Well, it makes sense. But the user don't actually know, how it's saved n the database and works with (and wants to sort and filter by) labels.
Is there a way to provide sorting and filtering by custom labels for an ENUM database table column in Yii (using a CActiveRecord model and a CGridView generated data grid)?
database table
CREATE TABLE `users` (
`userid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(45) NOT NULL,
...
`status` enum('processed', 'waiting') NOT NULL,
PRIMARY KEY (`userid`),
UNIQUE KEY `email_UNIQUE` (`email`)
);
User model
/**
* ...
* #property string $userid
* #property string $email
* ...
* #property string $status
*/
class User extends CActiveRecord
{
public function tableName()
{
return 'users';
}
public function getFirstAndLastName(){
return CHtml::encode($this->firstname." ".$this->lastname);
}
public function rules()
{
return array(
...
array('userid, email, status', 'safe', 'on'=>'search'),
);
}
public function attributeLabels()
{
return array(
'userid' => 'Userid',
'email' => 'Email',
...
'status' => Yii::t('app', 'status'),
);
}
public function relations()
{
return array(
...
);
}
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('userid',$this->userid,true);
$criteria->compare('email',$this->email,true);
...
$criteria->compare('status',$this->status,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
"pagination"=>array(
"pageSize"=>25
)
));
}
public static function model($className=__CLASS__)
{
return parent::model($className);
}
protected function beforeSave()
{
return parent::beforeSave(); // TODO: Change the autogenerated stub
}
public function getProcessingStatus()
{
return Yii::t('app', $this->processing_status);
}
}
UserController
class UserController extends Controller
{
...
/**
* Manages all models.
*/
public function actionAdmin()
{
// Yii::app()->cache->flush();
$model=new User('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['User']))
$model->attributes=$_GET['User'];
$this->render('admin',array(
'model'=>$model,
));
}
...
}
view
...
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'user-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'email',
'status',
array(
'class' => 'CButtonColumn',
'template' => '{view}{update}',
'buttons' => array(
'view' => array(
)
),
),
),
));
Model:
class User extends CActiveRecord {
const STATUS_PROCESSED = 'processed';
const STATUS_WAITING = 'waiting';
public static function getStatusList(){
return array(
self::STATUS_PROCESSED => 'Processed',
self::STATUS_WAITING => 'Waiting',
);
}
public function getStatusValue(){
$list = self::getStatusList();
return array_key_exists( $this->status, $list ) ? $list[ $this->status ] : 'Undefined';
}
}
View:
$this->widget('zii.widgets.grid.CGridView', array(
// other params
'columns' => array(
// other columns
array(
'name' => 'status',
'value' => '$data->getStatusValue()',
'filter' => User::getStatusList(),
),
)
));
That's all
You can specify a custom filter in your CDataColumn, by setting the filter property to be an array. It will result in a dropdown list filter instead of a text field filter.
Example:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'user-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'email',
array(
'name' => 'status',
'filter' => array(
'processed' => 'Processed',
'waiting' => 'Waiting',
),
),
array(
'class' => 'CButtonColumn',
'template' => '{view}{update}',
'buttons' => array(
'view' => array(
)
),
),
),
));
Also check out the docs