Yii2 REST other actions - rest

I have a controller called DepartementsController which extends the yii\rest\ActiveController.
I have to know which are the department in my region.
When I test my action http://localhost/yii_2/ws_localisation/web/regions/01/departements
I have this error :
{
"name": "PHP Notice",
"message": "Trying to get property of non-object",
"code": 8,
"type": "yii\base\ErrorException",
"file": "E:\wamp\www\yii_2\ws_localisation\controllers\DepartementsController.php",
"line": 58,
"stack-trace": [
"#0 E:\wamp\www\yii_2\ws_localisation\controllers\DepartementsController.php(58): yii\base\ErrorHandler->handleError(8, 'Trying to get p...', 'E:\\wam...', 58, Array)",
"#1 [internal function]: app\controllers\DepartementsController->actionDepartements('01')",
"#2 E:\Laetitia\wamp\www\yii_2\ws_localisation\vendor\yiisoft\yii2\base\InlineAction.php(55): call_user_func_array(Array, Array)",
"#3 E:\Laetitia\wamp\www\yii_2\ws_localisation\vendor\yiisoft\yii2\base\Controller.php(154): yii\base\InlineAction->runWithParams(Array)",
"#4 E:\Laetitia\wamp\www\yii_2\ws_localisation\vendor\yiisoft\yii2\base\Module.php(454): yii\base\Controller->runAction('departements', Array)",
"#5 E:\Laetitia\wamp\www\yii_2\ws_localisation\vendor\yiisoft\yii2\web\Application.php(84): yii\base\Module->runAction('departements/de...', Array)",
"#6 E:\Laetitia\wamp\www\yii_2\ws_localisation\vendor\yiisoft\yii2\base\Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))",
"#7 E:\Laetitia\wamp\www\yii_2\ws_localisation\web\index.php(12): yii\base\Application->run()",
"#8 {main}"
]
}
Can you help me please.
Regards.
web.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['departements'],
'prefix' => '/regions/<id:\\w+>',
'patterns' => [
'GET,HEAD' => 'departements',
],
],
[
'class' => 'yii\rest\UrlRule',
'controller' => ['regions','departements','communes','sylvoecoregions'],
'tokens' => ['{id}' => '<id:\\w+>'],
'except' => ['create','update','delete'],
],
],
],
DepartementsController.php
namespace app\controllers;
use yii\rest\ActiveController;
use yii\db\ActiveRecord;
use yii\web\ServerErrorHttpException;
class DepartementsController extends ActiveController
{
public $modelClass = 'app\models\Departements';
public function behaviors()
{
return
\yii\helpers\ArrayHelper::merge(parent::behaviors(), [
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
],
]);
}
public function actionDepartements($id)
{
$model = new $this->modelClass;
$model_departement = $model->find()->where('region_id=:id',[':id'=>$id])->all();
if($model_departement)
{
//$this->setHeader(200);
echo json_encode(array('status'=>1,'data'=>array_filter($model_departement->attributes)),JSON_PRETTY_PRINT);
}
else
{
//$this->setHeader(400);
echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
}
}}

If do you know what class that $model_departement is an instance
just change your if condition as
`if ($model_departement instanceof ModelDepartmentClass) {`
But if you have no idea about that. Below line also works.
if (is_object($model_departement)) {
if ($model_departement) is not a qualified check.
Please check related documents for more information.
http://php.net/manual/tr/function.is-object.php
http://php.net/manual/en/language.operators.type.php
http://php.net/manual/en/language.expressions.php

Related

Access translator in Shopware 6 Plugin

I am developing my first Shopware 6 plugin and was wondering how to access snippets in the Plugin class. I checked the Developer Guide but could not make it work.
I want to use the plugin translation as label in customField select options.
myfirstplugin.en-GB.json
{
"myfirstplugin": {
"my_custom_field_option_1": "Option 1",
"my_custom_field_option_2": "Option 2",
}
}
MyFirstPlugin.php
class MyFirstPlugin extends Plugin
{
// ....
private function createCustomFields(Context $context): void
{
if ($this->customFieldSetExists($context)) {
return;
}
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$customFieldSetRepository->create([
[
'id' => '294865e5c81b434d8349db9ea6b4e135',
'name' => 'my_custom_field_set',
'customFields' => [
[
'name' => 'my_custom_field',
'type' => CustomFieldTypes::SELECT,
'config' => [
'label' => [ 'en-GB' => 'My custom field'],
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
// Access my_custom_field_option_1 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_1',
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
// Access my_custom_field_option_2 of snippet myfirstplugin.en-GB.json
'label' => 'my_custom_field_option_2',
],
],
'customFieldType' => 'select',
'componentName' => 'sw-single-select',
'customFieldPosition' => 1,
],
],
]
],
], $context);
}
}
You can inject an argument of type Translator to your service
in services.xml
<argument type="service" id="translator"/>
in your service
use Shopware\Core\Framework\Adapter\Translation\Translator;
/**
* #var Translator
*/
private $translator;
public function __construct($translator)
{
$this->translator = $translator;
}
then down the way you can use this pretty much the same as in a twig template:
$translated = $this->translator
->trans(
'myfirstplugin.product.detail.294865e5c81b434d8349db9ea6b4e487');
I think you can use the snippet repository and search the label as you want in the Plugin class like
$sRepo = $this->container->get('snippet.repository');
$labels = $sRepo->search((new Criteria())
->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_OR,
[
new ContainsFilter('translationKey', 'my_custom_field_option_1'),
new ContainsFilter('translationKey', 'my_custom_field_option_2')
]
)
), $context)->getElements();
When you create the custom field you don't have to reference a translation snippet. Instead you can just provide the translations in the payload directly.
'config' => [
'label' => ['en-GB' => 'Label english', 'de-DE' => 'Label german'],
'type' => CustomFieldTypes::SELECT,
'options' => [
[
'value' => '294865e5c81b434d8349db9ea6b4e487',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
[
'value' => '1ce5abe719a04346930c7e43514ed4f1',
'label' => ['en-GB' => 'Option english', 'de-DE' => 'Option german'],
],
],
],

Method not allowed(#405)

following code throws out error like this:
"Method Not Allowed (#405)
Method Not Allowed. This url can only handle the following request methods: ."
Any ideas,how to fix this?
['label' => 'Logout', 'url' => ['/site/logout'], 'linkOptions' => ['data' => ['method' => 'post']]],
Here is still method in SiteController:
public function actionLogout() {
Yii::$app->user->logout();
return $this->goHome();
}
use data-method in linkOptions
['label' => 'logOut',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
],
notice:check behavior in sitecontroller
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'dashboard'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}

Saving manyToMany data cakephp3

I'm struggling about this issue for a while. I have three tables prestation, tools and prestation_tools. And my entities are linked as follow :
#ToolsTable
public function initialize(array $config)
{
parent::initialize($config);
$this->table('tools');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsToMany('Prestation', [
'joinTable' => 'prestation_tools',
'foreignKey' => 'tools_id'
]);
}
#PrestationTable
public function initialize(array $config)
{
parent::initialize($config);
$this->table('prestation');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsToMany('Tools', [
'through' => 'PrestationTools'
]);
$this->belongsToMany('Competences', [
'through' => 'PrestationCompetences'
]);
}
#PrestationToolsTable
public function initialize(array $config)
{
parent::initialize($config);
$this->table('prestation_tools');
$this->displayField('prestation_id');
$this->primaryKey(['prestation_id', 'tools_id']);
$this->belongsTo('Prestation', [
'foreignKey' => 'prestation_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Tools', [
'foreignKey' => 'tools_id',
'joinType' => 'INNER'
]);
}
And of my form is :
<?= $this->Form->input("Prestation.Tools.1.tools_id", [
'label' => false,
'type' => 'select',
'options' => $tools,
'empty' => "Sélectionner l'outil 1",
'templates' => [
'inputContainer' => '{{content}}'
],
'class' => 'form-control',
]) ?>
<label >Spécifications de l'outil 1</label>
<?= $this->Form->textarea('Prestation.Tools.1.details', [
'templates' => [
'inputContainer' => '<div class="form-group">{{content}}</div>'
],
'class' => 'form-control',
'placeholder' => 'Spécifications de l\'outil',
'label' => 'Spécifications de l\'outil'
]) ?>
When trying to save from PrestationController, on prestation record is saved. Can anyone help me ?
Update
My PrestationController's add() action looks like this :
public function add(){
#...
$prestation = $this->Prestation->patchEntity($prestation, $this->request->data, [
'associated' => [
'Tools',
'Competences'
]
]);
#...
}

Yii2 create custom rest action with post params

In my yii2 application i need to develop a rest action authUser()
public function actionAuthUser($username, $password)
{
return \api\models\User::findOne(['username' => $username, 'password' => sha1($password)]);
}
The params should be passed with post method because they contain sensitive informations.
How can i do this? How can i set the url manager to receive with post method my params?
Thanks in advance for all the help
[
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
// ...
[
'POST site/auth-user' => 'site/auth-user',
]
],
],
],
]
Or add behavior to Controller
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'auth-user' => ['post'],
],
],
];
}
And in controller action
public function actionAuthUser()
{
return \api\models\User::findOne(['username' => Yii::$app->request->post('username'), 'password' => sha1(Yii::$app->request->post('password'))]);
}

Yii2 backend url manager rules for module

I have created a module in Yii2 using Gii code generator. My new generated module location is
backend/modules/cms
cms is new generated module name.
backend/config/main.php after setting module configuration looks as following
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'bootstrap' => ['log'],
'modules' => [
'gii' => [
'class' => 'yii\gii\Module', //adding gii module
'allowedIPs' => ['127.0.0.1', '::1'] //allowing ip's
],
'cms' => [
'class' => 'backend\modules\cms\Cms',
],
],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<controller:\w+>/<action:\w+>/<id:\w+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
'<module:\w+>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>',
'<module:\w+><controller:\w+>/<action:update|delete>/<id:\d+>' => '<module>/<controller>/<action>',
]
],
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'js' => []
],
],
],
],
'params' => $params,
];
behaviors function in controller looks as after setting access rules
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index', 'create', 'update', 'delete'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
Only index action of my controller is accessible. when i access any other action in controller url changes but shows index action contents.
How can i access all actions in controller?
It will be appreciable if someone help me resolving this issue.
my controller
namespace backend\modules\cms\controllers;
use Yii;
use yii\filters\AccessControl;
use backend\modules\cms\models\Pages;
use backend\modules\cms\models\PagesSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* PagesController implements the CRUD actions for Pages model.
*/
class PagesController extends Controller
{
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index', 'create', 'update', 'delete'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
// 'delete' => ['post'],
],
],
];
}
/**
* Lists all Pages models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new PagesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->post());
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Pages model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Pages model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
echo "here";
exit;
$model = new Pages();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing Pages model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Pages model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Pages model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Pages the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Pages::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
I am using Url as follows:
http://localhost/yii2-demo/backend/cms/pages/index
http://localhost/yii2-demo/backend/cms/pages/create
What Url(s) are you using?
For a module it should be:
?r=cms/pages/index,
?r=cms/pages/create
etc...
The only problem I can spot is on your $matchCallback attribute on the second AccessControl rule. It should use this signature
function ($rule, $action)
And it should return a boolean that indicates wheter this rule should be applied or not. In your case, you're saying that it should be applied to users that are not guests and that have the role '0'. You're also calling a redirect inside the function, and it doesn't return a boolean. See more info here http://www.yiiframework.com/doc-2.0/yii-filters-accessrule.html#$matchCallback-detail
Try to remove this attribute completely and see if you get a different result.