laravel + mongo + gpaphql get children array - php

i have data in mongodb
it is a road object that has a property and an array of points that it consists of:
my model in laravel
<?php
namespace App\Models;
use App\Traits\Uuids;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Road extends Eloquent
{
//use HasFactory;
use Uuids;
protected $connection = 'mongodb';
protected $collection = 'roads';
protected $fillable = ['id', 'roadId', 'code', 'name', 'points'];
#public $timestamps = false;
public $incrementing = false;
public function fields() : array
{
return [
'id' => [
'type' => Type::string(),
'description' => 'The identifier of the road',
],
'roadId' => [
'type' => Type::nonNull(Type::int()),
'description' => 'ID road of external database',
],
'code' => [
'type' => Type::string(),
'description' => 'code of document',
],
'name' => [
'type' => Type::nonNull(Type::string()),
'description' => 'road name',
],
'points' => [
'name' => 'points',
'description' => 'points of road',
'type' => GraphQL::type('RoadPoints'),
'is_relation' => false
]
];
}
}
here we refer to a new type of "point on the road"
GraphQL type 'RoadPoints':
<?php
namespace App\GraphQL\Types;
use App\Models\Address;
use App\Models\RoadPoints;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type as GraphQLType;
class RoadPointsType extends GraphQLType
{
protected $attributes = [
'name' => 'RoadPoints',
'description' => 'The points is defined by the format GeoJSON Point',
'model' => RoadPoints::class,
];
public function fields(): array
{
return [
'type' => [
'type' => Type::string(),
'description' => 'The format GeoJSON',
],
'pk' => [
'type' => Type::string(),
'description' => 'piket of point',
],
'coordinates' => [
'type' => Type::listOf(GraphQL::type('GeoJSON')),
'description' => 'The partner lat and lng',
]
];
}
}
laravel model of RoadPoints
model RoadPoints class :
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class RoadPoints extends Eloquent
{
protected $fillable = ['type', 'pk', 'coordinates'];
protected $casts = [
'coordinates' => 'array'
];
}
graphql RoadQuery :
<?php
namespace App\GraphQL\Queries;
use App\Models\Road;
use Closure;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Query;
use App\Services\RoadService;
use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Facades\GraphQL;
class RoadQuery extends Query
{
private $roadService;
public function __construct(RoadService $roadService)
{
$this->roadService = $roadService;
}
protected $attributes = [
'name' => 'Road',
'description' => 'Query to Road data and points.'
];
public function type(): Type
{
return Type::listOf(GraphQL::type('Road'));
}
public function args(): array
{
return [
'id' => ['name' => 'id', 'type' => Type::string()],
'roadId' => ['name' => 'roadId', 'type' => Type::int()],
'code' => ['name' => 'code', 'type' => Type::string()],
'name' => ['name' => 'name', 'type' => Type::string()],
'lat' => ['name' => 'lat', 'type' => Type::float()],
'lng' => ['name' => 'lng', 'type' => Type::float()]
];
}
public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
$fields = $resolveInfo->getFieldSelection($depth = 3);
return $this->roadService->find($args, $fields);
}
}
result:
why pk and coordinates is null ?
Please tell me how to correctly select all objects in the array (points).

error in model
change
'type' => GraphQL::type('RoadPoints'),
to
'type' => Type::listOf(GraphQL::type('RoadPoints')),

Related

I don't get "add button" with inline create on Backpack Laravel

Following this documentation : https://backpackforlaravel.com/docs/4.1/crud-operation-inline-create
I try to create a link between invoices (primary) and invoices lines (secondary).
The link seems good, but I don't succeed to have the "+add" button needed to have the secondary form.
My code.
Primary class (invoiceCrudController)
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Invoice;
use Backpack\CRUD\app\Http\Controllers\CrudController;
/**
* Class InvoiceCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class InvoiceCrudController 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\ShowOperation;
use SetAccesses;
protected function setupCreateOperation()
{
$this->crud->setValidation(InvoiceRequest::class);
$this->crud->addFields([
/*other cases*/
[
'name' => 'invoiceLines',
'type' => 'relationship',
'tags'=> 'invoice lines',
'ajax'=>true,
[ // specify the entity in singular
'entity' => 'invoiceLine', // the entity in singular
]
],
]);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
}
secondary class (invoiceLinesController)
<?php
namespace App\Http\Controllers\Admin;
use App\Models\InvoiceLine;
use Backpack\CRUD\app\Http\Controllers\CrudController;
/**
* Class InvoiceCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class InvoiceLinesCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
public function setup()
{
$this->setAccesses('invoiceLine');
$this->crud->setModel('App\Models\InvoiceLine');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/invoiceLine');
$this->crud->setEntityNameStrings('invoiceLine', 'invoiceLines');
$this->crud->addColumns([
[
'name' => 'slug',
'type' => 'text',
],
[
'name' => 'quantity',
'type' => 'number',
'default' => 1,
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
],
[
'name' =>'unit_vat_excluded',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
]
]);
}
protected function setupListOperation()
{
$this->crud->enableExportButtons();
CustomerCrudController::addFilterCustomer();
}
protected function setupCreateOperation()
{
$this->crud->addFields([
[
'name' => 'slug',
'type' => 'text',
'allows_null' => false,
],
[
'name' => 'quantity',
'type' => 'number',
'default' => 1,
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
],
[
'name' =>'unit_vat_excluded',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-sm-6 col-md-6 col-lg-3 col-xl-3'
]
]
]);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
protected function setupShowOperation()
{
}
public static function getColumn()
{
return [
'name' => 'invoice_line_id',
'label' => 'InvoiceLines',
'type' => 'select',
'entity' => 'invoiceLine',
'attribute' => 'pretty_print',
'model' => InvoiceLine::class,
];
}
}
I think the wrong is in your Filed definistion:
$this->crud->addFields([
/other cases/
[
'name' => 'invoiceLines',
'type' => 'relationship',
'tags'=> 'invoice lines',
'ajax'=>true,
[ // specify the entity in singular
'entity' => 'invoiceLine', // the entity in singular
]
],
since the relation is on to many (I guess) then the filed should be:
[
'type' => "relationship",
'name' => 'invoiceLines',
'ajax' => true,
'inline_create' => true,
]

Laravel Factories and Seeding: Static array of arrays

For some of my tables, I'd like to insert a fixed amount of rows with specific data.
This is my categories factory:
$factory->define(Category::class, function (Faker $faker) {
return [
[
'name' => 'Politics',
'slug' => 'politics',
'description' => 'To discuss politics'
],
[
'name' => 'News and Events',
'slug' => 'news',
'description' => 'To discuss news and world events'
],
[
'name' => 'Food and Cooking',
'slug' => 'cooking',
'description' => 'To discuss cooking and food'
],
[
'name' => "Animals and Nature",
'slug' => 'animals-nature',
'description' => 'To discuss politics'
]
];
});
This is the seeder:
public function run() {
factory(App\Category::class, 1)->create();
}
I get this error: preg_match() expects parameter 2 to be string, array given
Is there a way to insert a fixed amount of static information into certain tables using seeding and factories?
I think you want to use Seeder with static values, if I am correct you should use
Define Category seeder
<?php
use Illuminate\Database\Seeder;
use App\Category;
class CategorySeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$categories = [
[
'name' => 'Politics',
'slug' => 'politics',
'description' => 'To discuss politics'
],
[
'name' => 'News and Events',
'slug' => 'news',
'description' => 'To discuss news and world events'
],
[
'name' => 'Food and Cooking',
'slug' => 'cooking',
'description' => 'To discuss cooking and food'
],
[
'name' => "Animals and Nature",
'slug' => 'animals-nature',
'description' => 'To discuss politics'
]
];
foreach ($categories as $category) {
Category::create($category);
}
}
}
And in DatabaseSeeder
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* #return void
*/
public function run()
{
$this->call(CategorySeeder::class);
}
}
Now run php artisan db:seed and it will be done.
The answer of #Prafulla Kumar Sahu is by seeder, but you can override your factory values by:
$category = factory(App\Category::class)->make([
'name' => 'Politics',
'slug' => 'politics',
'description' => 'To discuss politics'
]);
$category = factory(App\Category::class)->make([
'name' => 'News and Events',
'slug' => 'news',
'description' => 'To discuss news and world events'
]);
$category = factory(App\Category::class)->make([
'name' => 'Food and Cooking',
'slug' => 'cooking',
'description' => 'To discuss cooking and food'
]);
$category = factory(App\Category::class)->make([
'name' => "Animals and Nature",
'slug' => 'animals-nature',
'description' => 'To discuss politics'
]);

Custom validator in zend framework 2

I am new to Zend framework. I'm using custom validators to validate image file but I'm getting this error.
Zend\Validator\ValidatorPluginManager::get was unable to fetch or create an instance for ImageValidator
Here is validation file:
namespace User\Validator;
//use User\Validator\FileValidatorInterface;
use Zend\Validator\File\Extension;
use Zend\File\Transfer\Adapter\Http;
use Zend\Validator\File\FilesSize;
use Zend\Filter\File\Rename;
use Zend\Validator\File\MimeType;
use Zend\Validator\AbstractValidator;
class ImageValidator extends AbstractValidator
{
const FILE_EXTENSION_ERROR = 'invalidFileExtention';
const FILE_NAME_ERROR = 'invalidFileName';
const FILE_INVALID = 'invalidFile';
const FALSE_EXTENSION = 'fileExtensionFalse';
const NOT_FOUND = 'fileExtensionNotFound';
const TOO_BIG = 'fileFilesSizeTooBig';
const TOO_SMALL = 'fileFilesSizeTooSmall';
const NOT_READABLE = 'fileFilesSizeNotReadable';
public $minSize = 64; //KB
public $maxSize = 1024; //KB
public $overwrite = true;
public $newFileName = null;
public $uploadPath = './data/';
public $extensions = array('jpg', 'png', 'gif', 'jpeg');
public $mimeTypes = array(
'image/gif',
'image/jpg',
'image/png',
);
protected $messageTemplates = array(
self::FILE_EXTENSION_ERROR => "File extension is not correct",
self::FILE_NAME_ERROR => "File name is not correct",
self::FILE_INVALID => "File is not valid",
self::FALSE_EXTENSION => "File has an incorrect extension",
self::NOT_FOUND => "File is not readable or does not exist",
self::TOO_BIG => "All files in sum should have a maximum size of '%max%' but '%size%' were detected",
self::TOO_SMALL => "All files in sum should have a minimum size of '%min%' but '%size%' were detected",
self::NOT_READABLE => "One or more files can not be read",
);
protected $fileAdapter;
protected $validators;
protected $filters;
public function __construct($options)
{
$this->fileAdapter = new Http();
parent::__construct($options);
}
public function isValid($fileInput)
{
//validation code
}
}
and here is form file:
namespace User\Form;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\Session\Container;
use User\Validator\ImageValidator;
class PlatFormForm extends Form
{
public function __construct()
{
parent::__construct('platform-form');
$this->addInputFilter();
$this->setAttribute('method', 'post');
$this->setAttribute('enctype','multipart/form-data');
$this->setAttribute('class', 'platform_popup');
$this->addElements();
}
private function addElements()
{
$this->add([
'type' => 'file',
'name' => 'input_thumb',
'attributes' => [
'id' => 'input_thumb', 'class' => 'upload'
]
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'id' => 'add_platform', 'class' => 'upload'
],
'options' => [
'label' => 'CREATE',
//'label_attributes' => [
//],
],
]);
}
private function addInputFilter()
{
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
$inputFilter->add([
'name' => 'input_thumb',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
['name' => 'StripTags'],
],
'validators' => [
[
'name' => 'ImageValidator',
'options' => [
'minSize' => '64',
'maxSize' => '1024',
'newFileName' => 'newFileName2',
'uploadPath' => './data/'
],
],
],
]
);
}
}
and here is module.config.php file code:
'validators' => array(
'invokables' => array(
'ImageValidator' => 'User\Validator\ImageValidator'
),
),
Can anyone suggest me what am I doing wrong?
To inject the validator options into your constructor method you should register your validator like this inside your module.config.php file:
<?php
use Zend\ServiceManager\Factory\InvokableFactory;
use User\Validator\ImageValidator;
return array(
//...
'validators' => array(
'factories' => array(
ImageValidator::class => InvokableFactory::class
),
'aliases' => array(
'ImageValidator' => ImageValidator::class
)
),
//...
);
Actually, I ran into the same problem, and first of all you don't need to inject anything ( unless you want to ). Just by adding the full path to the Validator will work, in your example:
private function addInputFilter()
{
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
$inputFilter->add([
'name' => 'input_thumb',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
['name' => 'StripTags'],
],
'validators' => [
[
'name' =>'User\Validator\ImageValidator\ImageValidator',
'options' => [
'minSize' => '64',
'maxSize' => '1024',
'newFileName' => 'newFileName2',
'uploadPath' => './data/'
],
],
],
]
);
}
But I would like to point out that this is not the correct way of uploading files, regardless if they are images or not. You need to use FileInput() instead.
The simple example can be found here: https://framework.zend.com/manual/2.4/en/modules/zend.input-filter.file-input.html

Yii2 app\model\Db6TrxImportData not found

I am new with Yii2 and i am having this error.
PHP Fatal Error – yii\base\ErrorException
Class 'app\models\Db6TrxImportData' not found
I have searched somewhere that you need to add
use app\models\Db6TrxImportData;
i have already added this to my controller but still get the same error. I am noob in yii2.. please help. This is my code.
<?php
namespace app\modules\dtv\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\components\helpers\User;
use app\components\helpers\Data;
use app\models\Db6TrxImportData;
class ManageController extends \yii\web\Controller
{
// Properties
public $layout = '/registerLayout';
public $breadcrumbItems;
public $breadcrumbHomeItems;
public $route_nav = 'dtv/manage/list';
public $viewPath = 'app/modules/dtv/views';
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['list', 'delete'],
'rules' => [
[
'allow' => true,
'actions' => ['list', 'delete'],
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
$identity = User::initUser();
$feature = Yii::$app->params['Modules']['News Video Management'];
return User::hasAccess($identity, $feature);
},
],
],
'denyCallback' => function ($rule, $action) {
if (Yii::$app->user->isGuest) {
$this->goHome();
} else {
$this->redirect(['/dashboard']);
}
}
],
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
public function init()
{
if (Yii::$app->user->isGuest) {
$label = Yii::t('app', 'Login');
$url = '/login';
} else {
$label = Yii::t('app', 'Dashboard');
$url = '/dashboard';
}
$this->breadcrumbHomeItems = [
'label' => $label,
'url' => $url,
'template' => '<li>{link}</li> ',
];
}
public function actionList()
{
// Initialize Layout
$this->breadcrumbItems = [
Yii::t('app', 'Xml acquisition article list')
];
$identity = User::initUser();
$ownerId = User::getOwnerId($identity);
$dtvMovieModel = new Db6TrxImportData();
$params = [ 'owner' => $ownerId,
'status' => 'active',
'application' => 'menumaker'
];
$dtvMovie = $dtvMovieModel->getRecords($params);
return $this->render('list', [
'dtvMovie' => $dtvMovie
]);
}
}
?>
This is my Model
<?php
namespace app\models;
use Yii;
use yii\db\Query;
use app\components\helpers\User;
use app\components\helpers\Data;
class Db6TrxImportData extends \yii\db\ActiveRecord
{
public static function tableName()
{
return '_dtvdb.trx_import_data';
}
public static function getDb()
{
return Yii::$app->get('dtvdb');
}
public function rules()
{
return [
[['article_id', 'ctrl_flg', 'image_flg', 'video_flg', 'del_flg', 'news_cat', 'news_cat_cd', 'copyright', 'copyright_cd', 'title', 'article_text', 'zapping_text'], 'required'],
[['cx_create_date', 'cx_update_date', 'publish_date_from', 'publish_date_to', 'import_date', 'create_time', 'up_time'], 'safe'],
[['status'], 'string'],
[['article_id'], 'string', 'max' => 12],
[['ctrl_flg', 'image_flg', 'video_flg', 'del_flg'], 'string', 'max' => 1],
[['news_cat', 'news_sub_cat', 'disptach_type', 'copyright', 'lang'], 'string', 'max' => 100],
[['news_cat_cd', 'dispatch_cd', 'copyright_cd', 'lang_cd', 'article_status', 'zapping_status'], 'string', 'max' => 2],
[['news_sub_cat_cd'], 'string', 'max' => 4],
[['title', 'zapping_text'], 'string', 'max' => 300],
[['article_text'], 'string', 'max' => 1000],
[['comment'], 'string', 'max' => 500]
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'article_id' => 'Article ID',
'cx_create_date' => 'Cx Create Date',
'cx_update_date' => 'Cx Update Date',
'ctrl_flg' => 'Ctrl Flg',
'image_flg' => 'Image Flg',
'video_flg' => 'Video Flg',
'del_flg' => 'Del Flg',
'news_cat' => 'News Cat',
'news_cat_cd' => 'News Cat Cd',
'news_sub_cat' => 'News Sub Cat',
'news_sub_cat_cd' => 'News Sub Cat Cd',
'dispatch_cd' => 'Dispatch Cd',
'disptach_type' => 'Disptach Type',
'copyright' => 'Copyright',
'copyright_cd' => 'Copyright Cd',
'lang_cd' => 'Lang Cd',
'lang' => 'Lang',
'publish_date_from' => 'Publish Date From',
'publish_date_to' => 'Publish Date To',
'title' => 'Title',
'article_text' => 'Article Text',
'comment' => 'Comment',
'zapping_text' => 'Zapping Text',
'import_date' => 'Import Date',
'article_status' => 'Article Status',
'zapping_status' => 'Zapping Status',
'status' => 'Status',
'create_time' => 'Create Time',
'up_time' => 'Up Time',
];
}
public static function findByAttribute($arr)
{
foreach ($arr as $arrKey => $arrValue) {
$record = self::find()->where($arrKey.'=:'.$arrKey,[':'.$arrKey => $arrValue])->one();
}
return $record;
}
}

ZF2 form with fieldset and doctrine not working

I have a problem with a form, fieldset and doctrine.
This is my edit form. In this form I add the User Fieldset and add another field "password" (that I use only in this form).
EditUserForm:
class EditUserForm extends Form implements InputFilterProviderInterface
{
public function __construct($name = null, $options = [])
{
parent::__construct($name, $options);
$this->setAttribute('method', 'post');
$this->setHydrator(new ClassMethods(false));
$this->setObject(new User());
$this->add([
'name' => 'user',
'type' => 'Application\Form\UserFieldset',
'options' => [
'use_as_base_fieldset' => true
]
]);
$this->add([
'name' => 'password',
'type' => 'Zend\Form\Element\Password',
'attributes' => [
'id' => 'password'
]
]);
}
public function getInputFilterSpecification()
{
return [
'password' => [
'required' => true
],
];
}
}
UserFieldset:
class UserFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name = null, $options = [])
{
parent::__construct($name, $options);
$this->setHydrator(new ClassMethods(false));
$this->setObject(new User());
$this->add([
'name' => 'name',
'type' => 'Zend\Form\Element\Text',
'attributes' => [
'id' => 'name'
]
]);
$this->add([
'name' => 'surname',
'type' => 'Zend\Form\Element\Text',
'attributes' => [
'id' => 'surname'
]
]);
}
public function getInputFilterSpecification()
{
return [
'name' => [
'required' => true
],
'surname' => [
'required' => true
],
];
}
}
Why if I try to var_dump(form->getData()) does the entity does not have the password field?
object(Application\Entity\User)[114]
private 'name' => string 'john' (length=4)
private 'surname' => string 'smith' (length=5)
private 'password' => null
thanks.
The password needs to be part of the UserFieldset as you're setting the UserFieldset as base-fieldset. If you choose a base-fieldset, only this fieldset will be hydrated recursively.

Categories