wpgraphql custom connection is returning null json - php

I was trying to fetch data from the wordpress custom tabel however the json in wpgraphql is return nothing
`
{
"data": {
"customers": {
"nodes": []
}
},
"extensions": {
"debug": [],
"tracing": {
"version": 1,
"startTime": 1674985374.163901,
"endTime": 1674985374.182393,
"duration": 18491,
"execution": {
"resolvers": [
{
"path": [
"customers"
],
"parentType": "RootQuery",
"fieldName": "customers",
"returnType": "RootQueryToCustomerConnection",
"startOffset": 15638,
"duration": 1742
},
{
"path": [
"customers",
"nodes"
],
"parentType": "RootQueryToCustomerConnection",
"fieldName": "nodes",
"returnType": "[Customer!]!",
"startOffset": 17647,
"duration": 7
}
]
}
},
"queryLog": [
"Query Logging has been disabled. The 'SAVEQUERIES' Constant is set to 'false' on your server."
],
"queryAnalyzer": {
"keys": "b8e3177963ec0ae1ea1edc35f5d818248bb0e460feecb0ac25cdaff638cd545e graphql:Query operation:NewQuery list:customer",
"keysLength": 111,
"keysCount": 4,
"skippedKeys": "",
"skippedKeysSize": 0,
"skippedKeysCount": 0,
"skippedTypes": []
}
}
}`
My Code is this
`
register_activation_hook( __FILE__, 'wpgraphql_customer_db_table');
/**
* When the plugin is activated, create the table
* if it doesn't already exist
*/
function wpgraphql_customer_db_table() {
global $table_prefix, $wpdb;
$table_name = 'customers';
$wp_table = $wpdb->prefix . $table_name;
$charset_collate = $wpdb->get_charset_collate();
/**
* If the table doesn't already exist
*/
if ( $wpdb->get_var( "show tables like '$wp_table") != $wp_table ) {
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
$sql = "
CREATE TABLE $wp_table (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(225) NOT NULL,
PRIMARY KEY (`id`)
) $charset_collate;
";
dbDelta( $sql );
}
}
/**
* Hook into graphql init to extend GraphQL functionality
*/
add_action( 'graphql_init', function() {
class CustomerConnectionResolver extends \WPGraphQL\Data\Connection\AbstractConnectionResolver {
public function get_loader_name() {
return 'customers';
}
public function get_query_args() {
return [];
}
public function get_query() {
global $wpdb;
$ids_array = $wpdb->get_results(
$wpdb->prepare(
'SELECT id FROM `".$wpdb->prefix."customers` WHERE 1'
)
);
$ids = ! empty( $ids_array ) ? array_values(array_column($ids_array, 'id')) : [];
return $ids;
// wp_send_json($ids);
// print_r($ids);
// die();
}
public function get_ids() {
return $this->get_query();
}
public function is_valid_offset( $offset ) {
return true;
}
// public function is_valid_model( $model ) {
// return true;
// }
public function should_execute() {
return true;
}
}
/**
* Class NotificationsLoader
*
* This is a custom loader that extends the WPGraphQL Abstract Data Loader.
*/
class CustomersLoader extends \WPGraphQL\Data\Loader\AbstractDataLoader {
public function loadKeys( array $keys ) {
if ( empty( $keys ) || ! is_array( $keys ) ) {
return [];
}
global $wpdb;
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM `".$wpdb->prefix."customers` WHERE `id` in (".implode(',',$keys).")"
)
);
$results_by_id = [];
foreach ( $results as $result ) {
$customer = [
// 'DatabaseId' => $result->id,
'firstName' => $result->first_name,
'lastName' => $result->last_name,
// 'email' => $result->email,
// 'password' => $result->password,
];
$results_by_id[ (int) $result->id ] = $customer;
}
echo $results_by_id;
$customers = [];
foreach ( $keys as $key ) {
if ( isset( $results_by_id[ $key ] ) ) {
$customers[$key] = $results_by_id[ $key ];
}
}
// graphql_debug($customers);
return $customers;
}
}
add_filter( 'graphql_data_loaders', function( $loaders, $context ) {
$loaders['customers'] = new CustomersLoader( $context );
return $loaders;
}, 10, 2 );
} );
/**
* Hook into GraphQL Schema initialization to register types
* and fields to the Schema
*/
add_action( 'graphql_register_types', function() {
# 1: Register the Type
register_graphql_object_type( 'Customer', [
'description' => __( 'Customer Records from Custom Table', 'wp-graphql-customers' ),
'fields' => [
// 'DatabaseId' => [
// 'type' => [ 'non_null' => 'Int' ],
// 'description' => __( 'Identifier of the customers database record id', 'wp-graphql-customers' ),
// ],
'firstName' => [
'type' => 'String',
'description' => __( 'First Name of the Customer', 'wp-graphql-customers' )
],
'lastName' => [
'type' => 'String',
'description' => __( 'Last Name of the Customer', 'wp-graphql-customers' )
],
// 'email' => [
// 'type' => 'String',
// 'description' => __( 'Email of the Customer', 'wp-graphql-customers' )
// ],
// 'password' => [
// 'type' => 'String',
// 'description' => __( 'Password of customers', 'wp-graphql-customers' )
// ],
],
'interfaces' => [ 'Node' ],
] );
# 2: Register the connection
register_graphql_connection( [
'fromType' => 'RootQuery',
'toType' => 'Customer' ,
'fromFieldName' => 'customers',
'resolve' => function( $source, $args, $context, $info ) {
$resolver = new CustomerConnectionResolver( $source, $args, $context, $info );
return $resolver->get_connection();
},
]);
} );
What I am doing wrong please help.
I would like to return data something like
{
"data": {
"posts": {
"edges": [
{
"node": {
"firstName": "shank",
"lastName": "Nath"
}
}
]
}
}

The SQL query to fetch data from the customers table is missing a quotation mark at the end:
$wpdb->get_var( "show tables like '$wp_table") != $wp_table
It should be:
$wpdb->get_var( "show tables like '$wp_table'") != $wp_table

Related

CodeIgniter 4: How do I display a gallery of image entity objects?

I have a site where members can:
upload images
subscribe to other members
like, dislike, and favorite images
view each other's profiles
So in my gallery view, all images are visible with their respective image uploader, likes rating (percentage of likes to dislikes), and date uploaded.
I have created an entity object class called Image that holds all of this information and more. So I am trying to find a way to loop through all the images in the gallery as Image objects. Is that possible?
Here is my Image entity class:
class Image extends Entity
{
protected $attributes = [
'viewkey' => NULL,
'id' => NULL,
'uploader' => NULL,
'filename' => NULL,
'title' => NULL,
'tags' => NULL,
'createdAt' => NULL,
'modifiedAt' => NULL,
'likeCount' => NULL,
'dislikeCount' => NULL,
'viewCount' => NULL,
'favoriteCount' => NULL,
'commentCount' => NULL,
'rating' => NULL,
'userLiked' => NULL,
'userDisliked' => NULL,
'userViewed' => NULL,
'userFavorited' => NULL,
'userCommented' => NULL,
'userSubscribed' => NULL,
'action' => NULL,
];
protected $datamap = [
'createdAt' => 'created_at',
'modifiedAt' => 'modified_at',
];
protected $dates = ['createdAt', 'updatedAt',];
protected $casts = [
'likeCount' => 'int',
'dislikeCount' => 'int',
'viewCount' => 'int',
'favoriteCount' => 'int',
'commentCount' => 'int',
'rating' => 'float',
'userDisliked' => 'bool',
'userLiked' => 'bool',
'userViewed' => 'bool',
'userFavorited' => 'bool',
];
protected $builder;
public function __construct (array $data = NULL)
{
parent::__construct($data);
$db = \Config\Database::connect();
$this->builder = $db->table('actions');
}
/**
* Custom __set Methods
*/
public function setDislikeCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 0,
];
$this->attributes['dislikeCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setLikeCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 1,
];
$this->attributes['likeCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setViewCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 2,
];
$this->attributes['viewCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setFavoriteCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 3,
];
$this->attributes['favoriteCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setCommentCount(string $viewkey)
{
$this->attributes['commentCount'] = $this->builder
->where('viewkey', $viewkey)
->countAllResults();
}
public function setRating(string $viewkey)
{
helper('arithmetic');
$whereDislike = $whereLike = [];
$whereDislike = [
'viewkey' => $viewkey,
'action' => 0,
];
$dislikes = $this->builder
->where($whereDislike)
->countAllResults();
$whereLike = [
'viewkey' => $viewkey,
'action' => 1,
];
$likes = $this->builder
->where($whereLike)
->countAllResults();
$this->attributes['rating'] = get_percentage($likes + $dislikes, $likes, 0);
}
public function setUserDisliked(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 0,
];
$userDisliked = $this->builder
->where($where)
->countAllResults();
if ($userDisliked === 1) {
$this->attributes['userDisliked'] = TRUE;
} else {
$this->attributes['userDisliked'] = FALSE;
}
}
public function setUserLiked(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 1,
];
$userLiked = $this->builder
->where($where)
->countAllResults();
if ($userLiked === 1) {
$this->attributes['userLiked'] = TRUE;
} else {
$this->attributes['userLiked'] = FALSE;
}
}
public function setUserViewed(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 2,
];
$userViewed = $this->builder
->where($where)
->countAllResults();
if ($userViewed === 1) {
$this->attributes['userViewed'] = TRUE;
} else {
$this->attributes['userViewed'] = FALSE;
}
}
public function setUserFavorited(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 3,
];
$userFavorited = $this->builder
->where($where)
->countAllResults();
if ($userFavorited === 1) {
$this->attributes['userFavorited'] = TRUE;
} else {
$this->attributes['userFavorited'] = FALSE;
}
}
public function setUserCommented(string $subscriber)
{
$db = \Config\Database::connect();
$this->builder = $db->table('comments');
$userCommented = $this->builder
->where('commenter')
->countAllResults();
if ($userCommented === 1) {
$this->attributes['userCommented'] = TRUE;
} else {
$this->attributes['userCommented'] = FALSE;
}
}
public function setUserSubscribed(string $uploader)
{
$db = \Config\Database::connect();
$this->builder = $db->table('subscribers');
$where = [];
$where = [
'profile' => $uploader,
'subscriber' => session()->get('username'),
];
$userSubscribed = $this->builder
->where($where)
->countAllResults();
if ($userSubscribed === 1) {
$this->attributes['userSubscribed'] = TRUE;
} else {
$this->attributes['userSubscribed'] = FALSE;
}
}
/**
* Custom __get Methods
*/
}
I fill the entity with a function in my ImageModel here:
public function fillImageEntity(string $viewkey)
{
$imageData = $this->builder()
->where('viewkey', $viewkey)
->get()
->getRowArray();
$image = new \App\Entities\Image();
$image->fill($imageData);
$image->setDislikeCount($viewkey);
$image->setLikeCount($viewkey);
$image->setViewCount($viewkey);
$image->setFavoriteCount($viewkey);
$image->setCommentCount($viewkey);
$image->setRating($viewkey);
$image->setUserDisliked($viewkey);
$image->setUserLiked($viewkey);
$image->setUserViewed($viewkey);
$image->setUserFavorited($viewkey);
$image->setUserCommented($viewkey);
$image->setUserSubscribed($imageData['uploader']);
return $image;
}
I have tried make a Gallery object class that would hold the images and then fill that object with Image objects but I get the error you cannot keep an array of Entity objects. Is this a logic error or am I going about it all wrong?
I was able to create a multidimensional array of my entity class Image.php and successfully display the necessary information in my view!
I pass the array into my view here in Gallery.php controller:
public function index()
{
$data = [];
$data = [
'title' => 'Image Gallery',
'gallery' => $this->imageModel->getEntireGallery(),
];
echo view('templates/header', $data);
echo view('templates/navigation');
echo view('templates/filter_bar', $data);
echo view('images/gallery', $data);
echo view('templates/footer', $data);
}
I fill the array and each image object in my model ImageModel.php:
public function fillImageEntity(string $viewkey)
{
$imageData = $this->builder()
->where('viewkey', $viewkey)
->get()
->getRowArray();
$image = new \App\Entities\Image();
$image->fill($imageData);
$image->setDislikeCount($viewkey);
$image->setLikeCount($viewkey);
$image->setViewCount($viewkey);
$image->setFavoriteCount($viewkey);
$image->setCommentCount($viewkey);
$image->setRating($viewkey);
$image->setUserDisliked($viewkey);
$image->setUserLiked($viewkey);
$image->setUserViewed($viewkey);
$image->setUserFavorited($viewkey);
$image->setUserCommented($viewkey);
$image->setUserSubscribed($imageData['uploader']);
return $image;
}
public function getEntireGallery()
{
$images = $this->builder()
->orderBy('modified_at', 'DESC')
->get()
->getResultArray();
foreach ($images as $image) {
$gallery[$image['id']] = $this->fillImageEntity($image['viewkey']);
}
return $gallery;
And here is my Image entity class:
class Image extends Entity
{
protected $attributes = [
'viewkey' => NULL,
'id' => NULL,
'uploader' => NULL,
'filename' => NULL,
'title' => NULL,
'tags' => NULL,
'createdAt' => NULL,
'modifiedAt' => NULL,
'likeCount' => NULL,
'dislikeCount' => NULL,
'viewCount' => NULL,
'favoriteCount' => NULL,
'commentCount' => NULL,
'rating' => NULL,
'userLiked' => NULL,
'userDisliked' => NULL,
'userViewed' => NULL,
'userFavorited' => NULL,
'userCommented' => NULL,
'userSubscribed' => NULL,
'action' => NULL,
];
protected $datamap = [
'createdAt' => 'created_at',
'modifiedAt' => 'modified_at',
];
protected $dates = ['createdAt', 'updatedAt',];
protected $casts = [
'likeCount' => 'int',
'dislikeCount' => 'int',
'viewCount' => 'int',
'favoriteCount' => 'int',
'commentCount' => 'int',
'rating' => 'float',
'userDisliked' => 'bool',
'userLiked' => 'bool',
'userViewed' => 'bool',
'userFavorited' => 'bool',
];
protected $builder;
public function __construct (array $data = NULL)
{
parent::__construct($data);
$db = \Config\Database::connect();
$this->builder = $db->table('actions');
}
/**
* Custom __set Methods
*/
public function setDislikeCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 0,
];
$this->attributes['dislikeCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setLikeCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 1,
];
$this->attributes['likeCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setViewCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 2,
];
$this->attributes['viewCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setFavoriteCount(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'action' => 3,
];
$this->attributes['favoriteCount'] = $this->builder
->where($where)
->countAllResults();
}
public function setCommentCount(string $viewkey)
{
$this->attributes['commentCount'] = $this->builder
->where('viewkey', $viewkey)
->countAllResults();
}
public function setRating(string $viewkey)
{
helper('arithmetic');
$whereDislike = $whereLike = [];
$whereDislike = [
'viewkey' => $viewkey,
'action' => 0,
];
$dislikes = $this->builder
->where($whereDislike)
->countAllResults();
$whereLike = [
'viewkey' => $viewkey,
'action' => 1,
];
$likes = $this->builder
->where($whereLike)
->countAllResults();
$this->attributes['rating'] = get_percentage($likes + $dislikes, $likes, 0);
}
public function setUserDisliked(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 0,
];
$userDisliked = $this->builder
->where($where)
->countAllResults();
if ($userDisliked === 1) {
$this->attributes['userDisliked'] = TRUE;
} else {
$this->attributes['userDisliked'] = FALSE;
}
}
public function setUserLiked(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 1,
];
$userLiked = $this->builder
->where($where)
->countAllResults();
if ($userLiked === 1) {
$this->attributes['userLiked'] = TRUE;
} else {
$this->attributes['userLiked'] = FALSE;
}
}
public function setUserViewed(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 2,
];
$userViewed = $this->builder
->where($where)
->countAllResults();
if ($userViewed === 1) {
$this->attributes['userViewed'] = TRUE;
} else {
$this->attributes['userViewed'] = FALSE;
}
}
public function setUserFavorited(string $viewkey)
{
$where = [];
$where = [
'viewkey' => $viewkey,
'username' => session()->get('username'),
'action' => 3,
];
$userFavorited = $this->builder
->where($where)
->countAllResults();
if ($userFavorited === 1) {
$this->attributes['userFavorited'] = TRUE;
} else {
$this->attributes['userFavorited'] = FALSE;
}
}
public function setUserCommented(string $subscriber)
{
$db = \Config\Database::connect();
$this->builder = $db->table('comments');
$userCommented = $this->builder
->where('commenter')
->countAllResults();
if ($userCommented === 1) {
$this->attributes['userCommented'] = TRUE;
} else {
$this->attributes['userCommented'] = FALSE;
}
}
public function setUserSubscribed(string $uploader)
{
$db = \Config\Database::connect();
$this->builder = $db->table('subscribers');
$where = [];
$where = [
'profile' => $uploader,
'subscriber' => session()->get('username'),
];
$userSubscribed = $this->builder
->where($where)
->countAllResults();
if ($userSubscribed === 1) {
$this->attributes['userSubscribed'] = TRUE;
} else {
$this->attributes['userSubscribed'] = FALSE;
}
}
}

How to show admin specific data in Laravel Tastyigniter(Online food ordering) system

I am using Laravel Tastyigniter system in which I want to show the locations name in dropdown in Menus module according to locations added by admin which is currently logged in.
For Example, If admin A added two locations such as location A and location B and
admin B added two locations such as location C and location D resp.
Note - The locations are getting saved in database with created_by column which is id of admin adding the location.
A) What supposed to happen -
If I logged in as admin A then in location dropdown Location A and Location B should get display
If I logged in as admin B then in location dropdown Location C and Location D should get display.
B) What is happening currently -
For both the admins all the 4 locations are getting displayed.
C) Following is the Code -
Here is Menus_model.php
<?php namespace Admin\Models;
use Admin\Traits\Locationable;
use Igniter\Flame\Database\Traits\Purgeable;
class Menus_model extends Model
{
use Purgeable;
use Locationable;
const LOCATIONABLE_RELATION = 'locations';
public $relation = [
'morphToMany' => [
'locations' => ['Admin\Models\Locations_model', 'name' =>
'locationable'],
],
];
protected $purgeable = ['locations'];
}
Here is menus_model.php which is present under models->config
<?php
$config['form']['tabs'] = [
'fields' => [
'locations' => [
'label' => 'Location',
'type' => 'relation',
'span' => 'right',
'valueFrom' => 'locations',
'nameFrom' => 'location_name',
'locationAware' => 'hide',
],
],
];
return $config;
Here is the Locations_model.php file code under models folder
<?php namespace Admin\Models;
use Admin\Traits\HasDeliveryAreas;
use Admin\Traits\HasWorkingHours;
use Igniter\Flame\Database\Attach\HasMedia;
use Igniter\Flame\Database\Traits\HasPermalink;
use Igniter\Flame\Database\Traits\Purgeable;
use Igniter\Flame\Location\Models\AbstractLocation;
use DB;
/**
* Locations Model Class
*
* #package Admin
*/
class Locations_model extends AbstractLocation
{
use HasWorkingHours;
use HasDeliveryAreas;
use HasPermalink;
use Purgeable;
use HasMedia;
const LOCATION_CONTEXT_SINGLE = 'single';
const LOCATION_CONTEXT_MULTIPLE = 'multiple';
protected $appends = ['location_thumb'];
protected $hidden = ['options'];
public $casts = [
'location_country_id' => 'integer',
'location_lat' => 'double',
'location_lng' => 'double',
'offer_delivery' => 'boolean',
'offer_collection' => 'boolean',
'delivery_time' => 'integer',
'collection_time' => 'integer',
'last_order_time' => 'integer',
'reservation_time_interval' => 'integer',
'reservation_stay_time' => 'integer',
'location_status' => 'boolean',
'options' => 'serialize',
'location_city' => 'integer',
'region_id'=>'integer',
];
public $relation = [
'hasMany' => [
'working_hours' => ['Admin\Models\Working_hours_model', 'delete' =>
TRUE],
'delivery_areas' => ['Admin\Models\Location_areas_model', 'delete'
=> TRUE],
'reviews' => ['Admin\Models\Reviews_model', 'delete' => TRUE],
],
'belongsTo' => [
'country' => ['System\Models\Countries_model', 'otherKey' =>
'country_id', 'foreignKey' => 'location_country_id'],
'city' => ['Admin\Models\City_model', 'otherKey' => 'city_id', 'foreignKey' => 'location_city'],
'region' => ['Admin\Models\Region_model', 'otherKey' => 'region_id', 'foreignKey' => 'region_id'],
],
'belongsToMany' => [
'tables' => ['Admin\Models\Tables_model', 'table' => 'location_tables'],
'cuisines' => ['Admin\Models\Cuisines_model', 'table' => 'location_cuisines'],
],
];
protected $purgeable = ['tables', 'delivery_areas','cuisines'];
public $permalinkable = [
'permalink_slug' => [
'source' => 'location_name',
'controller' => 'local',
],
];
public $mediable = [
'thumb',
'gallery' => ['multiple' => TRUE],
];
protected static $allowedSortingColumns = [
'distance asc', 'distance desc',
'reviews_count asc', 'reviews_count desc',
'location_id asc', 'location_id desc',
'location_name asc', 'location_name desc',
];
public $url;
protected static $defaultLocation;
public static function onboardingIsComplete()
{
if (!$defaultId = params('default_location_id'))
return FALSE;
if (!$model = self::isEnabled()->find($defaultId))
return FALSE;
return isset($model->getAddress()['location_lat'])
AND isset($model->getAddress()['location_lng'])
AND ($model->hasDelivery() OR $model->hasCollection())
AND isset($model->options['hours'])
AND $model->delivery_areas->where('is_default', 1)->count() > 0;
}
public function getWeekDaysOptions()
{
return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
}
//
// Events
//
protected function afterFetch()
{
$this->parseOptionsValue();
}
protected function beforeSave()
{
$this->parseOptionsValue();
}
protected function afterSave()
{
$this->performAfterSave();
}
protected function beforeDelete()
{
Location_tables_model::where('location_id', $this->getKey())->delete();
Location_cuisines_model::where('location_id', $this->getKey())->delete();
}
//
// Scopes
//
/**
* Scope a query to only include enabled location
*
* #return $this
*/
public function scopeIsEnabled($query)
{
return $query->where('location_status', 1);
}
public function scopeListFrontEnd($query, array $options = [])
{
extract(array_merge([
'page' => 1,
'pageLimit' => 20,
'sort' => null,
'search' => null,
'latitude' => null,
'longitude' => null,
], $options));
if ($latitude AND $longitude)
$query->selectDistance($latitude, $longitude);
$searchableFields = ['location_name', 'location_address_1', 'location_address_2', 'location_city',
'location_state', 'location_postcode', 'description'];
if (!is_array($sort)) {
$sort = [$sort];
}
foreach ($sort as $_sort) {
if (in_array($_sort, self::$allowedSortingColumns)) {
$parts = explode(' ', $_sort);
if (count($parts) < 2) {
array_push($parts, 'desc');
}
[$sortField, $sortDirection] = $parts;
$query->orderBy($sortField, $sortDirection);
}
}
$search = trim($search);
if (strlen($search)) {
$query->search($search, $searchableFields);
}
return $query->paginate($pageLimit, $page);
}
//
// Accessors & Mutators
//
public function getLocationThumbAttribute()
{
return $this->hasMedia() ? $this->getThumb() : null;
}
public function getDeliveryTimeAttribute($value)
{
return (int)$value;
}
public function getCollectionTimeAttribute($value)
{
return (int)$value;
}
public function getFutureOrdersAttribute($value)
{
return (bool)$value;
}
public function getReservationTimeIntervalAttribute($value)
{
return (int)$value;
}
//
// Helpers
//
public function setUrl($suffix = null)
{
if (is_single_location())
$suffix = '/menus';
$this->url = site_url($this->permalink_slug.$suffix);
}
public function hasGallery()
{
return $this->hasMedia('gallery');
}
public function getGallery()
{
$gallery = array_get($this->options, 'gallery');
$gallery['images'] = $this->getMedia('gallery');
return $gallery;
}
public function parseOptionsValue()
{
$value = #unserialize($this->attributes['options']) ?: [];
$this->parseHoursFromOptions($value);
$this->parseAreasFromOptions($value);
$this->attributes['options'] = #serialize($value);
return $value;
}
public function listAvailablePayments()
{
$result = [];
$payments = array_get($this->options, 'payments', []);
$paymentGateways = Payments_model::listPayments();
foreach ($paymentGateways as $payment) {
if ($payments AND !in_array($payment->code, $payments)) continue;
$result[$payment->code] = $payment;
}
return collect($result);
}
public function performAfterSave()
{
$this->restorePurgedValues();
if (array_key_exists('hours', $this->options)) {
$this->addOpeningHours($this->options['hours']);
}
if (array_key_exists('delivery_areas', $this->attributes)) {
$this->addLocationAreas($this->attributes['delivery_areas']);
}
if (array_key_exists('tables', $this->attributes)) {
$this->addLocationTables($this->attributes['tables']);
}
if (array_key_exists('cuisines', $this->attributes)) {
$this->addLocationCuisines($this->attributes['cuisines']);
}
}
public static function getDefault()
{
if (self::$defaultLocation !== null) {
return self::$defaultLocation;
}
$defaultLocation = self::isEnabled()->where('location_id', params('default_location_id'))->first();
if (!$defaultLocation) {
$defaultLocation = self::isEnabled()->first();
if ($defaultLocation) {
params('default_location_id', $defaultLocation->getKey());
params()->save();
}
}
return self::$defaultLocation = $defaultLocation;
}
/**
* Create a new or update existing location tables
*
* #param array $tables
*
* #return bool
*/
public function addLocationTables($tables = [])
{
return $this->tables()->sync($tables);
}
public function addLocationCuisines($cuisines = [])
{
return $this->cuisines()->sync($cuisines);
}
}
Here is locations_model.php which is present under models->config folder
<?php
$config['form']['tabs'] = [
'defaultTab' => 'lang:admin::lang.locations.text_tab_general',
'fields' => [
'location_name' => [
'label' => 'lang:admin::lang.label_name',
'type' => 'text',
'span' => 'left',
],
'location_email' => [
'label' => 'lang:admin::lang.label_email',
'type' => 'text',
'span' => 'right',
],
'location_telephone' => [
'label' => 'lang:admin::lang.locations.label_telephone',
'type' => 'text',
'span' => 'left',
],
'location_status' => [
'label' => 'lang:admin::lang.label_status',
'type' => 'switch',
'default' => 1,
'span' => 'right',
],
'created_by' => [
'type' => 'hidden',
'default' => isset($_SESSION['user_id']) ? $_SESSION['user_id'] : '',
],
],
];
return $config;
UPDATED
Basically I want to diaply locations in menus form , Currently in menus form all the locations are getting display and the code for this is mentioned below
This is Menus.php controller
<?php namespace Admin\Controllers;
use Admin\Classes\AdminController;
use Admin\Models\Menu_options_model;
use AdminMenu;
use ApplicationException;
class Menus extends AdminController
{
public $implement = [
'Admin\Actions\ListController',
'Admin\Actions\FormController',
'Admin\Actions\LocationAwareController',
];
public $listConfig = [
'list' => [
'model' => 'Admin\Models\Menus_model',
'title' => 'lang:admin::lang.menus.text_title',
'emptyMessage' => 'lang:admin::lang.menus.text_empty',
'defaultSort' => ['menu_id', 'DESC'],
'configFile' => 'menus_model',
],
];
protected $requiredPermissions = 'Admin.Menus';
public function __construct()
{
parent::__construct();
AdminMenu::setContext('menus');
}
public function edit_onChooseMenuOption($context, $recordId)
{
$menuOptionId = post('Menu._options');
if (!$menuOption = Menu_options_model::find($menuOptionId))
throw new ApplicationException('Please select a menu option to
attach');
$model = $this->asExtension('FormController')->formFindModelObject($recordId);
$menuItemOption = $model->menu_options()->create(['option_id' => $menuOptionId]);
$menuOption->option_values()->get()->each(function ($model) use ($menuItemOption) {
$menuItemOption->menu_option_values()->create([
'menu_option_id' => $menuItemOption->menu_option_id,
'option_value_id' => $model->option_value_id,
'new_price' => $model->price,
]);
});
$model->reload();
$this->asExtension('FormController')->initForm($model, $context);
flash()->success(sprintf(lang('admin::lang.alert_success'), 'Menu item option attached'))->now();
$formField = $this->widgets['form']->getField('menu_options');
return [
'#notification' => $this->makePartial('flash'),
'#'.$formField->getId('group') => $this->widgets['form']->renderField($formField, [
'useContainer' => FALSE,
]),
];
}
}
Below is Locaations.php controller
<?php namespace Admin\Controllers;
use Admin\Facades\AdminLocation;
use Admin\Models\Locations_model;
use AdminMenu;
use Exception;
use Geocoder;
class Locations extends \Admin\Classes\AdminController
{
public $implement = [
'Admin\Actions\ListController',
'Admin\Actions\FormController',
];
public $listConfig = [
'list' => [
'model' => 'Admin\Models\Locations_model',
'title' => 'lang:admin::lang.locations.text_title',
'emptyMessage' => 'lang:admin::lang.locations.text_empty',
'defaultSort' => ['location_id', 'DESC'],
'configFile' => 'locations_model',
],
];
protected $requiredPermissions = 'Admin.Locations';
public function __construct()
{
parent::__construct();
AdminMenu::setContext('locations', 'restaurant');
}
public function remap($action, $params)
{
if ($action != 'settings' AND AdminLocation::check())
return $this->redirect('locations/settings');
return parent::remap($action, $params);
}
public function settings($context = null)
{
if (!AdminLocation::check())
return $this->redirect('locations');
$this->asExtension('FormController')->edit('edit', $this-
>getLocationId());
}
public function index_onSetDefault($context = null)
{
$defaultId = post('default');
if (Locations_model::updateDefault(['location_id' => $defaultId])) {
flash()->success(sprintf(lang('admin::lang.alert_success'),
lang('admin::lang.locations.alert_set_default')));
}
return $this->refreshList('list');
}
public function settings_onSave($context = null)
{
try {
$this->asExtension('FormController')->edit_onSave('edit',
params('default_location_id'));
return $this->refresh();
}
catch (Exception $ex) {
$this->handleError($ex);
}
}
public function listOverrideColumnValue($record, $column, $alias = null)
{
if ($column->type != 'button')
return null;
if ($column->columnName != 'default')
return null;
$attributes = $column->attributes;
$column->iconCssClass = 'fa fa-star-o';
if ($record->getKey() == params('default_location_id')) {
$column->iconCssClass = 'fa fa-star';
}
return $attributes;
}
public function formExtendQuery($query)
{
if ($locationId = $this->getLocationId())
$query->where('location_id', $locationId);
}
public function formAfterSave($model)
{
if (post('Location.options.auto_lat_lng')) {
if ($logs = Geocoder::getLogs())
flash()->error(implode(PHP_EOL, $logs))->important();
}
}
}
Views
Now the n views folder there is folder names menus and under that folder there is create.php file for displaying create menu form
The code in views->menus->create.php file is below
<div class="row-fluid">
<?= form_open(current_url(),
[
'id' => 'edit-form',
'role' => 'form',
'method' => 'POST',
]
); ?>
<?= $this->renderForm(); ?>
<?= form_close(); ?>
</div>
FormController
Now the renderForm() function is present at path app/admin/actions/FormController.php which we have defined in Locations and Menus controller under public $implement = ['Admin\Actions\FormController'];
Ther renderForm() function is as follow
public function renderForm($options = [])
{
if (!$this->formWidget) {
throw new Exception(lang('admin::lang.form.not_ready'));
}
if (!is_null($this->toolbarWidget)) {
$form[] = $this->toolbarWidget->render();
}
$form[] = $this->formWidget->render($options);
return implode(PHP_EOL, $form);
}
Widgets
At last the there are widgets for input fields like select, text, radio, checkbox etc. In our case we have widget name field_selectlist, which is present at path app/admin/widgets/form/field_selectlist.php
The field_selectlist.php file has code as below
<?php
$fieldOptions = $field->options();
//print_r($fieldOptions);die; All the locations are displaying here.
$isCheckboxMode = $field->config['mode'] ?? 'checkbox';
$selectMultiple = $isCheckboxMode == 'checkbox';
$checkedValues = (array)$field->value;
$enableFilter = (count($fieldOptions) > 20);
?>
<div class="control-selectlist">
<select
data-control="selectlist"
id="<?= $field->getId() ?>"
name="<?= $field->getName() ?><?= $selectMultiple ? '[]' : '' ?>"
<?php if ($field->placeholder) { ?>data-non-selected-text="<?=
e(lang($field->placeholder)) ?>"<?php } ?>
<?= $selectMultiple ? 'multiple="multiple"' : '' ?>
data-enable-filtering="<?= $enableFilter; ?>"
data-enable-case-insensitive-filtering="<?= $enableFilter; ?>"
<?= $field->getAttributes() ?>>
<?php if ($field->placeholder) { ?>
<option value=""><?= e(lang($field->placeholder)) ?></option>
<?php } ?>
<?php
foreach ($fieldOptions as $value => $option) { ?>
<?php
if (!is_array($option)) $option = [$option];
if ($field->disabled AND !in_array($value, $checkedValues)) continue;
?>
<option
<?= in_array($value, $checkedValues) ? 'selected="selected"' : '' ?>
value="<?= $value ?>">
<?= e(is_lang_key($option[0]) ? lang($option[0]) : $option[0]) ?>
<?php if (isset($option[1])) { ?>
<span><?= e(is_lang_key($option[1]) ? lang($option[1]) :
$option[1]) ?></span>
<?php } ?>
</option>
<?php } ?>

Module lang not working in Prestashop 1.7.6

Just trying to create a new simple module with translation but the saving process is not working. The table 'ps_myoptions_lang' is updating with the field id_myoptions = 0 in each lang_id and nothing is saved in 'ps_myoptions'.
modules/myoptions/controllers/admin/AdminOptionsController.php
<?php
require_once(dirname(__FILE__) . './../../classes/Option.php');
class AdminOptionsController extends AdminController
{
public function __construct(){
parent::__construct();
$this->bootstrap = true; // use Bootstrap CSS
$this->table = 'myoptions'; // SQL table name, will be prefixed with _DB_PREFIX_
$this->lang = true;
$this->identifier = 'id_myoptions'; // SQL column to be used as primary key
$this->className = 'Option'; // PHP class name
$this->allow_export = true; // allow export in CSV, XLS..
$this->_defaultOrderBy = 'a.name'; // the table alias is always `a`
$this->_defaultOrderWay = 'DESC';
$this->fields_list = [
'id_myoptions' => ['title' => 'ID','class' => 'fixed-width-xs'],
'name' => ['title' => 'Name'],
];
$this->addRowAction('edit');
$this->addRowAction('details');
$this->fields_form = [
'legend' => [
'title' => 'Pasta',
'icon' => 'icon-list-ul'
],
'input' => [
['name'=>'name','type'=>'text', 'lang' => true, 'label'=>'Name','required'=>true],
],
'submit' => [
'title' => $this->trans('Save', [], 'Admin.Actions'),
]
];
}
}
modules/myoptions/classes/Options.php
<?php
class Option extends ObjectModel
{
public $id;
public $name;
public static $definition = [
'table' => 'myoptions',
'primary' => 'id_myoptions',
'multilang' => true,
'fields' => [
'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isAnything', 'required'=>true],
],
];
}
modules/myoptions/myoptions.php
if (!defined('_PS_VERSION_')) {
exit;
}
class Myoptions extends Module
{
protected $config_form = false;
public function __construct()
{
$this->name = 'myoptions';
$this->tab = 'administration';
$this->version = '1.0.0';
$this->author = 'abc';
$this->need_instance = 1;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('My Options');
$this->description = $this->l('Add additional options');
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install()
{
Configuration::updateValue('MYOPTIONS_LIVE_MODE', false);
include(dirname(__FILE__).'/sql/install.php');
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('backOfficeHeader') &&
$this->installTabs();
}
public function uninstall()
{
Configuration::deleteByName('MYOPTIONS_LIVE_MODE');
include(dirname(__FILE__).'/sql/uninstall.php');
return parent::uninstall();
}
public function enable($force_all = false)
{
return parent::enable($force_all)
&& $this->installTabs()
;
}
public function disable($force_all = false)
{
return parent::disable($force_all)
&& $this->uninstallTabs()
;
}
/**
* Since PS 1.7.1
* #var array
*/
public $tabs = array(
array(
'name' => array(
'en' => 'Options', // Default value should be first
'fr' => 'Options',
),
'class_name' => 'AdminOptions',
'visible' => true,
'parent_class_name' => 'AdminParentThemes',
),
);
public function installTabs()
{
$moduleName = $this->name;
$this->addTab('AdminOptions', 'Options', $moduleName, 'AdminTools');
return true;
}
public function addTab($className, $tabName, $moduleName, $parentClassName)
{
$tab = new Tab();
$tab->active = 1;
$tab->class_name = $className;
$tab->name = array();
foreach (Language::getLanguages(true) as $lang) {
$tab->name[$lang['id_lang']] = $tabName;
}
$tab->id_parent = (int) Tab::getIdFromClassName($parentClassName);
$tab->module = $moduleName;
$tab->add();
return $tab;
}
}
Is there something that I'm doing wrong?
Thanks for your answer.
Prestashop 1.7.6
PHP 7.2.25
I think I found the problem :
$sqlCreate = "CREATE TABLE `" . _DB_PREFIX_ . "myoptions` (
`id_myoptions` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_myoptions`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
$sqlCreateLang = "CREATE TABLE `" . _DB_PREFIX_ . "myoptions_lang` (
`id_myoptions` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id_lang` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_myoptions`,`id_lang`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
Db::getInstance()->execute($sqlCreate) && Db::getInstance()->execute($sqlCreateLang);
I have the same field name in both tables. I then use it only in Lang Table and it seems to work now.

Yii2 file upload returns UPLOAD_ERR_PARTIAL

Images fail to upload when I create a new item but on updating the newly created item the file is successfully uploaded. Any reasons?
Trending News Model
class TrendingNews extends \yii\db\ActiveRecord
{
const EVENT_ADD_TRENDING_NEWS = 'add-trending-news';
public $featuredFile;
public function init() {
$this->on(self::EVENT_ADD_TRENDING_NEWS, [$this, 'saveToLog']);
}
/**
* #inheritdoc
*/
public static function tableName()
{
return 'trending_news';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['headline_text','news_info', 'news_url', 'author', 'published', 'date_added', 'date_modified'], 'required'],
[['headline_text', 'image_url', 'news_info', 'news_url'], 'string'],
[['date_added', 'date_modified'], 'safe'],
[['author'], 'string', 'max' => 20],
[['published'], 'string', 'max' => 2],
[['featuredFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'headline_text' => 'Headline',
'image_url' => 'Image Url',
'news_info' => 'Source',
'news_url' => 'News Url',
'author' => 'Author',
'published' => 'Published',
'date_added' => 'Date Added',
'date_modified' => 'Date Modified',
'featuredFile' => 'Featured Image',
];
}
public function uploadBanner()
{
if ($this->validate()) {
$ymd = date("Ymd");
$save_path = \Yii::getAlias('#backend') . '/web/uploads/' . $ymd . '/';
if (!file_exists($save_path)) {
mkdir($save_path, 0777, true);
}
$fileName = "trending_".Yii::$app->security->generateRandomString(20);
$this->featuredFile->saveAs($save_path . $fileName .'.' . $this->featuredFile->extension);
$this->image_url = $ymd . '/'. $fileName . '.' . $this->featuredFile->extension;
return true;
} else {
return false;
}
}
public function upload()
{
if ($this->validate()) {
$ymd = date("Ymd");
$save_path = \Yii::getAlias('#backend') . '/web/uploads/' . $ymd . '/';
if (!file_exists($save_path)) {
mkdir($save_path, 0777, true);
}
$fileName = Yii::$app->security->generateRandomString(20);
$this->featuredFile->saveAs($save_path . $fileName .'.' . $this->featuredFile->extension);
$this->image_url = $ymd . '/'. $fileName . '.' . $this->featuredFile->extension;
return true;
} else {
return false;
}
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->date_added = date("YmdHis");
$this->author = Yii::$app->user->identity->id;
}
else {
$this->date_modified = date("YmdHis");
}
return true;
}
else{
return false;
}
}
public function saveToLog($event)
{
//assigning attributes
// echo 'mail sent to admin using the event';
$app_log_model = new AppLog();
$app_log_model->log_time = date("YmdHis");
$app_log_model->log_activity = 'Added a trending news';
$app_log_model->user_id = Yii::$app->user->identity->id;
$app_log_model->device = "1";
if ($app_log_model->save()) {
return true;
} else {
return $app_log_model->getErrors() ;
}
}
}
usage
public function actionCreate()
{
$model = new TrendingNews();
if ($model->load(Yii::$app->request->post())) {
$model->featuredFile = UploadedFile::getInstance($model, 'featuredFile');
if(isset($model->featuredFile)){
$model->upload();
$model->save(false);
} else {
// file is uploaded successfully
$model->save();
//$model->trigger(BlogArticle::EVENT_EDIT_ARTICLE);
}
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$model->featuredFile = UploadedFile::getInstance($model, 'featuredFile');
if(isset($model->featuredFile)){
$model->upload();
$model->save(false);
} else {
$model->save();
}
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
the app log shows this
$_FILES = [
'TrendingNews' => [
'name' => [
'featuredFile' => 'another_evento.jpg'
]
'type' => [
'featuredFile' => ''
]
'tmp_name' => [
'featuredFile' => ''
]
'error' => [
'featuredFile' => 3
]
'size' => [
'featuredFile' => 0
]
]
]
featuredFile is not a database field
Is there something that is being done wrong?
I am using xampp,tried on a live server and the issue is same
You are doing it wrong if you have to require a file input on insert and not on the update you should add a scenario for it so that it asks you to provide file when adding a new record only.
Secondly you are using the same ActiveRecord model and added a custom attribute in it to be used as a file input and in the upload() function you are calling validate() and returning false if not validated but on the same time you are not checking for true or false in you controller action and on the very next line you are calling $model->save(false) with false so technically your script would never intimate the user if there is any validation error.
The file should be uploaded after the record is saved not before saving the record so that there are no extra files uploaded in case of error, although you want the file to be required on insert so technically if file is not uploaded the record should not be saved, and for this reason we have transactions for database insertions you should use a transaction block to save the rcord and the file along with it
You should only call the validate() method for file uploading if you have a separate FormModel for file uploading otherwise you should load the instance from the UploadedFile to the model field and call the $model->save() which will automatically validate the model before saving you should just check for the empty filename before uploading so that when you are updating any record and not submitting a file the previous file should be kept as is.
You need to update your validation rules to the following first
/**
* #inheritdoc
*/
public function rules()
{
return [
[['headline_text','news_info', 'news_url', 'author', 'published', 'date_added', 'date_modified'], 'required'],
[['headline_text', 'image_url', 'news_info', 'news_url'], 'string'],
[['date_added', 'date_modified'], 'safe'],
[['author'], 'string', 'max' => 20],
[['published'], 'string', 'max' => 2],
[ [ 'featuredFile' ] , 'required' , 'on' => 'insert' ] ,
[ [ 'featuredFile' ] , 'file' , 'extensions' => 'png, jpg' , 'maxSize' => 200000 , 'tooBig' => 'Limit is 500KB' ] ,
];
}
Change the upload() function to the following
public function upload( $ymd , $fileName ) {
if ( $this->featuredFile !== null && $this->featuredFile->name !== '' ) {
$save_path = \Yii::getAlias ( '#backend' ) . '/web/uploads/' . $ymd . '/';
if ( !file_exists ( $save_path ) ) {
mkdir ( $save_path , 0777 , true );
}
if ( !$this->featuredFile->saveAs ( $save_path . $fileName ) ) {
$this->addError ( 'featuredFile' , 'File could not be uploaded' );
throw new \Exception ( 'File upload error' );
}
}
}
Then add another method inside your model to remove old file in case of new file uploaded on update
public function unlinkOldFile( $filename ) {
if ( $filename !== '' ) {
$save_path = \Yii::getAlias ( '#backend' ) . '/web/uploads/' . $filename;
unlink ( $save_path );
}
}
after that change your create and update actions to the following so that they use transation blocks for database operations
public function actionCreate() {
$model = new TrendingNews(['scenario'=>'insert']);
if ( $model->load ( Yii::$app->request->post () ) ) {
$model->featuredFile = UploadedFile::getInstance ( $model , 'featuredFile' );
if ( $model->featuredFile !== null ) {
$ymd = date ( "Ymd" );
$fileName = Yii::$app->security->generateRandomString ( 20 ) . '.' . $model->featuredFile->extension;
$model->image_url = $ymd . '/' . $fileName;
}
$transaction = Yii::$app->db->beginTransaction ();
try {
if ( !$model->save () ) {
throw new \Exception ( 'Error Occoured' );
}
$model->upload ( $ymd , $fileName );
$transaction->commit ();
return $this->redirect ( [ 'view' , 'id' => $model->id ] );
} catch ( \Exception $ex ) {
$transaction->rollBack ();
}
}
return $this->render ( 'create' , [
'model' => $model ,
] );
}
public function actionUpdate( $id ) {
$model = $this->findModel ( $id );
if ( $model->load ( Yii::$app->request->post () ) ) {
$model->featuredFile = UploadedFile::getInstance ( $model , 'featuredFile' );
//$oldFile = '';
$oldFile = $model->image_url;
if ( $model->featuredFile !== null ) {
$ymd = date ( "Ymd" );
$fileName = Yii::$app->security->generateRandomString ( 20 ) . '.' . $model->featuredFile->extension;
$model->image_url = $ymd . '/' . $fileName;
}
$transaction = Yii::$app->db->beginTransaction ();
try {
if ( !$model->save () ) {
throw new \Exception ( 'Model error' );
}
$model->upload ( $ymd , $fileName );
$model->unlinkOldFile ( $oldFile );
$transaction->commit ();
return $this->redirect ( [ 'view' , 'id' => $model->id ] );
} catch ( Exception $ex ) {
$transaction->rollBack ();
}
}
return $this->render ( 'update' , [
'model' => $model ,
] );
}

Accessing root value and arguments resolver graphql-php

I am having issues with the following part of my code using graphql-php libraries.
'resolve' =>function($value,$args,$context)
When I run the query:
"http://localhost:8080/index.php?query={certificate(id:"123ecd"){id}}"
I get the below listed message:
{"errors":[{"message":"Internal server error","category":"internal",
"locations":[{"line":1,"column":2}],"path":["certificate"]}],"data":{"certificate":null}}
Secondly when I run a nested query
"http://192.168.211.15:8080/index.php?query{certificates{id,products{id}}}"
I get the below listed response:
{"errors":[{"message":"Internal server error","category":"internal","locations":[{"line":1,"column":26}],"path":["certificates",0,"products"]}
"data":{"certificates":[{"id":"a023gavcx","status":"Valid","products":null}]}}
Below is my complete code:
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
class CertificateType extends ObjectType{
public function __construct(){
$config = [
'name' => 'Certificate',
'fields' => function() {
return [
'id' => [
'type' => Types::nonNull(Types::string()),
],
'number' => [
'type' => Types::int()
],
'first_issue_date' => [
'type' => Types::string()
],
'products' => [
'type' => Types::product(),
'resolve'=> function($value, $args, $context){
$pdo = $context['pdo'];
$cert_id = $value->id;
$result = $pdo->query("select * from products where cert_id = {$cert_id} ");
return $result->fetchObject() ?: null;
}
]
];
}
];
parent::__construct($config);
}
}
use GraphQL\Type\Definition\Type;
class Types extends Type{
protected static $typeInstances = [];
public static function certificate(){
return static::getInstance(CertificateType::class);
}
public static function product(){
return static::getInstance(ProductType::class);
}
protected static function getInstance($class, $arg = null){
if (!isset(static::$typeInstances[$class])) {
$type = new $class($arg);
static::$typeInstances[$class] = $type;
}
return static::$typeInstances[$class];
}
}
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
class ProductType extends ObjectType
{
public function __construct()
{
$config = [
'name' => 'Product',
'fields' => function() {
return [
'id' => [
'type' => Types::nonNull(Types::string()),
],
'primary_activity' => [
'type' => Types::string()
],
'trade_name' => [
'type' => Types::string()
],
];
},
];
parent::__construct($config);
}
}
require_once __DIR__ . '/../../../../autoload.php';
use GraphQL\GraphQL;
use GraphQL\Type\Schema;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
define('BASE_URL', 'http://127.0.0.1:8080');
ini_set('display_errors', 0);
$debug = !empty($_GET['debug']);
if ($debug) {
$phpErrors = [];
set_error_handler(function($severity, $message, $file, $line) use (&$phpErrors) {
$phpErrors[] = new ErrorException($message, 0, $severity, $file, $line);
});
}
try {
$dbHost = 'localhost';
$dbName = '*******';
$dbUsername = 'root';
$dbPassword = '*********';
$pdo = new PDO("mysql:host={$dbHost};dbname={$dbName}", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$appContext = [
'pdo' => $pdo ];
if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
$raw = file_get_contents('php://input') ?: '';
$data = json_decode($raw, true);
} else {
$data = $_REQUEST;
}
$data += ['query' => null, 'variables' => null];
if (null === $data['query']) {
$data['query'] = '{hello}';
}
require __DIR__ . '/types/CertificateType.php';
require __DIR__ . '/types/ProductType.php';
require __DIR__ . '/types/OrganizationType.php';
require __DIR__ . '/Types.php';
$queryType = new ObjectType([
'name' => 'Query',
'fields' => [
'hello' => [
'description' => ' Hello world',
'type' => Types::string(),
'resolve' => function() {
return 'Hello World';
}
],
'certificate' => [
'type' => Types::listOf(Types::certificate()),
'description' => 'This is the certificate identification',
'args' => [
'id' => Types::string()],
'resolve' => function ($rootValue,$args,$context) {
$pdo = $context['pdo'];
$id = $args['id'];
return $pdo->query("SELECT * from certificates where id ={$id}");
return $data->fetchObject() ?: null;
}
],
'certificates' => [
'type' => Types::listOf(Types::certificate()),
'resolve' => function($rootValue, $args, $context) {
$pdo = $context['pdo'];
$result = $pdo->query("select * from certificates order by id limit 10");
return $result->fetchAll(PDO::FETCH_OBJ);
}
],
]
]);
$schema = new Schema([
'query' => $queryType
]);
$result = GraphQL::execute(
$schema,
$data['query'],
null,
$appContext,
(array) $data['variables']
);
if ($debug && !empty($phpErrors)) {
$result['extensions']['phpErrors'] = array_map(
['GraphQL\Error\FormattedError', 'createFromPHPError'],
$phpErrors
);
}
$httpStatus = 200;
} catch (\Exception $error) {
// Handling Exception
// *************************************
$httpStatus = 500;
if (!empty($_GET['debug'])) {
$result['extensions']['exception'] = FormattedError::createFromException($error);
} else {
$result['errors'] = [FormattedError::create('Unexpected Error')];
}
}
header('Content-Type: application/json', true, $httpStatus);
echo json_encode($result);
Can somebody help me resolve these issues. Thanks in advance

Categories