why dont display relation data in Rest Yii2 - php

why dont display relation data in Rest Yii2
i have two tables.
sample:
category , subcategory
<?php
namespace app\controllers;
use app\models\Category;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use yii\rest\Controller;
class ApiController extends Controller
{
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats'] = ['application/json' => Response::FORMAT_JSON];
return $behaviors;
}
public function actionGetSk($cId)
{
$result= Category::find()->with('subCategory')->where(['id' => $cId])->all()
return $result;
}
}
i result i have only from Category. (result is json)
but print_r($result) i have data from Category and subCategory.
web.php
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => 'api',
],

Try this: in your Category model, add this method:
public function extraFields() {
return [
'subcategory' => 'subCategory',
];
}
And now, call your api with the expand get parameter like:
http://yourapi.com/api/get-sk?cID=1&expand=subcategory

Related

Using Spatie Roles Library In GraphQl Query ( Rebing ) Always Returns NULL

The Files I'm Using :
<?php
namespace App\GraphQl\Query\User;
use App\GraphQl\Traits\UserTrait;
use App\Models\User;
use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Facades\GraphQL;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Query;
The GraphQl UserRolesQuery File :
use Closure;
class UserRolesQuery extends Query
{
use UserTrait;
protected $attributes = [
'name' => 'user',
];
public function type(): Type
{
return GraphQL::type('UserType');
}
public function args(): array
{
return [
'id' => [
'name' => 'id',
'type' => Type::int(),
// 'rules' => ['required'] validation
],
];
}
public function resolve($root, array $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
The Resolve Function Where I Expect To Return User Role Names
$user = User::find($args['id']);
$result = $user->getRoleNames();
return $result;
}
}
I Expect The** $user->getRoleNames(); To Return The User Roles Name .. But it always returns NULL**

Backpack for laravel -> I can't get + Add Inline Create

I want to use the Inline Create functionality of Backpack for Laravel but the button "Add +" doesn't shows up.
I have a 1 to n relationship
The primary model is Inscription and the secondary is InscriptionProduct
This is my code:
Models\Inscription
...
class Inscription extends Model
{
public function product() {
return $this->hasMany('App\Models\InscriptionProduct');
}
...
Models\InscriptionProduct
...
class InscriptionProduct extends Model
{
public function inscription()
{
return $this->belongsTo(Inscription::class);
}
...
Http\Controllers\Admin\InscriptionProductCrudController
...
class InscriptionProductCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
...
Http\Controllers\Admin\InscriptionCrudController
...
class InscriptionCrudController extends CrudController
{
protected function setupCreateOperation()
{
...
$this->crud->addField([
'type' => "relationship",
'name' => 'product',
'ajax' => true,
'inline_create' => true,
// 'data_source' => backpack_url('/admin/inscription-product/inline/create'),
// 'data_source' => backpack_url('inscription/fetch/inscription-product'),
// 'inline_create' => [ 'entity' => 'inscriptionproduct' ]
// These 3 commented lines are alternatives also tried with no results
]);
...
The Relationship is well constructed because I can see the Products I have created via the CRUD of InscriptionProduct
What am I missing?
I solve it to, in your main CrudController, you should call the InLineCreate just below CreateOperation.
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation { store as traitStore; }
Also in my secondary CrudController I had to create a fetch function, something I did
protected function fetchFeatures()
{
return $this->fetch([
'model' => \App\Models\Features::class, // required
'searchable_attributes' => ['name', 'slug'],
'query' => function($model) {
return $model;
} // to filter the results that are returned
]);
return $this->traitFetch();
}

Yii2 Allow action access only by POST request

I have created a yii2 controller, which meant to display statistics from database, for a specific user. There is a ajax request, performed to my controller action, but i want to restrict to allow only POST method for this action.
<?php
use yii\web\Response;
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\filters\VerbFilter;
use app\models\StatsModel;
class DataController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['stats'],
'formats' => [
'application/json' => Response::FORMAT_JSON
],
],
];
}
/**
* {#inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
public function actionStats()
{
//how can i restrict this action to only POST http method?
return StatsModel::find()->all();
}
}
I need to restrict actionStats() to HTTP Post method only.
Usually you'd allow post only adding something like this to your behaviors:
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'stats' => ['POST'],
],
],
And if you are accessing this action only through ajax, in your action you could add the following check
if(Yii::$app->request->isAjax)
{
//in case you want to return JSON formatted response
Yii:$app->response->format = Response::FORMAT_JSON;
}
You can check this cookbook as well:
https://books.google.com.sv/books?id=CJrcDgAAQBAJ&pg=PA193&lpg=PA193&dq=yii2+isajax&source=bl&ots=lRFEiPbN3K&sig=MFGo7VostVkxNZDbXGemXrm-qA8&hl=es&sa=X&ved=0ahUKEwjE9ZXSh7nbAhWPk1kKHW3wCeEQ6AEIYTAF#v=onepage&q=yii2%20isajax&f=false
Finally, you can just make the check for post in your action like this
public function actionStats()
{
if(Yii::$app->request->isPost())
{
//your logic here
return StatsModel::find()->all();
}
else
//throw an exception or return false
}

Route is redirecting before calling the controller method

I am using Laravel 5.5.40 along with the Zizaco\Entrust Pacakge
In my routes/web.php file i have the following route setup.
Route::group(['prefix' => 'order'], function() {
Route::get('', 'OrderController#getMe');
});
It is supposed to call the getMe() method inside the OrderController.php but it instead redirects to www.mydomain.co.uk/home
namespace App\Http\Controllers;
class OrderController extends Controller
{
public function getMe() {
return "You got me!";
}
}
As a test, I added a __construct function to the OrderController.php to see if the class was even been loaded.
public function __construct() {
dd("Testing");
}
When accessing www.mydomain.co.uk/order i now get
"Testing"
I can't seem to work out why it is not running the getMe() method. Could anyone possibly shine some light on this please?
I have also tried changing the route to use ClientController#list which works fine.
Contents of ClientController.php
namespace App\Http\Controllers;
use App\Client;
class ClientController extends Controller
{
public function __construct() {
//
}
// Display all the clients
public function list() {
$tabContent = [
'display_type' => 'list',
'data' => Client::orderBy('name', 'asc')->get(),
'view_params' => [
'columns' => [
'name' => 'Client Name',
'address_line_1' => 'Address Line 1',
'town' => 'Town',
'county' => 'County',
'post_code' => 'Post Code'
],
'links' => 'client',
'controls' => True
]
];
return view('tables.list', ['data' => $tabContent]);
}
}
It has become apparent that if the controller does not have the constructor function in it, it will automatically redirect to the root of the URI with no error.
public function __construct() {
//
}

How auto prepend post's category to url?

In Yii2 I have blog with articles, each one has 1 category. Rules are so:
'rules' => [
'<category_slug>/<article_slug>' => 'article/view',
],
controller:
public function actionView($category_slug, $article_slug)
{
...
}
Categories are stored in params.php:
<?php
return [
'categories' => [
[
'id' => 1,
'name' => 'First category',
'slug' => 'first_category',
],
...
],
];
Url to article:
Url::to(['article/view', 'category_slug' => $model->category_slug, 'article_slug' => $model->article_slug])
Question: Is it possible to auto prepend category slug to Url::to? I mean, you need only make Url::to with article_slug param. I suppose best solution will be to change url rules somehow, but how exactly?
'rules' => [
'<Yii::$app->MyFunction->GetCategorySlugByArcticleId(..)>/<article_slug>' => 'article/view',
],
This should be an easy one.
Option one: extend the Url-Helper
Simply extend the Url-Helper as follows:
class MyUrl extends \yii\helpers\Url
{
//extending regular `to`-method
public static function to($url = '', $scheme = false)
{
//check if url needs completion and meets preconditions
if (is_array($url) && strcasecmp($url[0], 'article/view') === 0 && isset($url['article_slug']) && !isset($url['category_slug'])) {
//add category slug if missing...assuming you have a relation from article to category and category having a property `slug`
$url['category_slug'] = $article->category->slug;
}
return parent::to($url, $scheme);
}
//...or custom method for your case which is even more convenient
public static function toArticle($article, $scheme=false)
{
//article could be an article model itself or an id
$articleModel = $article instanceof Article ? $article : Article::findOne($article);
return parent::to([
'article/view',
'article_slug'=>$articleModel->slug,
'category_slug'=>$articleModel->category->slug,
], $scheme);
}
}
All you have to do now is use that class instead of the regular Url-helper!
Option two: add a method within your article model
Simply add a method as follows:
class Article extends \yii\db\ActiveRecord
{
//...
public function link($scheme=false)
{
return Url::to([
'article/view',
'article_slug'=>$this->slug,
'category_slug'=>$this->category->slug,
], $scheme);
}
//...
}
Let me know if you need more info!

Categories