I have this code:
index.php
$router = new Core\Libraries\Router();
$router->add('', ['controller' => 'HomeAdminController', 'action' => 'index']);
$router->add('home', ['controller' => 'HomeAdminController', 'action' => 'indexAction']);
$router->add('home2', ['controller' => 'HomeAdminController', 'action' => 'indexAction2']);
$router->add('home3', ['controller' => 'HomeAdminController', 'action' => 'indexAction3']);
router.php
class Router
{
protected $_routes = [];
protected $_params = [];
public function add(string $route, array $params = [])
{
$route = preg_replace('/\//', '\\/', $route);
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route);
$route = '/^' . $route . '$/i';
$this->_routes[$route] = $params;
}
public function getRoutes(): string
{
return $this->_routes;
}
public function match(string $url): bool
{
foreach ($this->_routes as $route => $params) {
if (preg_match($route, $url, $matches)) {
foreach ($matches as $key => $match) {
if (is_string($key)) {
$params[$key] = $match;
}
}
$this->_params = $params;
return true;
}
}
return false;
}
public function getParams(): string
{
return $this->_params;
}
public function dispatch(string $url)
{
$url = $this->removeQueryStringVariables($url);
if ($this->match($url)) {
$controller = $this->_params['controller'];
$controller = $this->convertToStudlyCaps($controller);
$controller = $this->getNamespace() . $controller;
if (class_exists($controller)) {
$controller_object = new $controller($this->_params);
$action = $this->_params['action'];
$action = $this->convertToCamelCase($action);
if (is_callable([$controller_object, $action])) {
$controller_object->$action();
} else {
throw new \Exception("Method $action (in controller $controller) not found");
}
} else {
throw new \Exception("Controller class $controller not found");
}
} else {
throw new \Exception('No route matched.', 404);
}
}
protected function convertToStudlyCaps(string $string): string
{
return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
}
protected function convertToCamelCase(string $string): string
{
return lcfirst($this->convertToStudlyCaps($string));
}
protected function removeQueryStringVariables(string $url): string
{
if ($url != '') {
$parts = explode('&', $url, 2);
if (strpos($parts[0], '=') === false) {
$url = $parts[0];
} else {
$url = '';
}
}
return $url;
}
protected function getNamespace(): string
{
$namespace = null;
$namespace = 'Controllers\\';
if (array_key_exists('namespace', $this->_params)) {
$namespace .= $this->_params['namespace'] . '\\';
}
return $namespace;
}
}
**controllers: Home.php**
class HomeAdminController extends Controllers\Controller
{
protected function before()
{
}
protected function after()
{
}
public function indexAction()
{
echo "## 1";
}
public function index()
{
echo "## 2";
$config = Registry::register("Core\Libraries\Config");
View::renderTemplate('Home/index.twig', [
'name' => 'Dave',
'colours' => ['red', 'green', 'blue']
]);
}
public function indexAction2()
{
echo "## 2";
$config = Registry::register("Core\Libraries\Config");
View::renderTemplate('Home/home2.twig', [
'name' => 'Dave',
'products' => [
[
'name' => 'Notebook',
'description' => 'Core i7',
'value' => 800.00,
'date_register' => '2017-06-22',
],
[
'name' => 'Mouse',
'description' => 'Razer',
'value' => 125.00,
'date_register' => '2017-10-25',
],
[
'name' => 'Keyboard',
'description' => 'Mechanical Keyboard',
'value' => 250.00,
'date_register' => '2017-06-23',
],
]
]);
}
public function indexAction3()
{
echo "home 3";
print_r($_POST);
View::renderTemplate('Home/home2.twig', [
'name' => 'Dave',
'colours' => ['red', 'green', 'blue']
]);
}
}
Controlers path: Controllers\Name.php
Is it possible to automatically build such routers?
I mean search the directory: Controllers \ and build for example based on files:
- Controllers \ home.php
- Controllers \ product.php
- Controllers \ contact.php
- Controllers \ productList.php
....
in an automatic way:
$ router-> add ('', ['controller' => 'HomeAdminController', 'action' => 'index']);
$ router-> add ('home', ['controller' => 'HomeAdminController', 'action' => 'indexAction']);
$ router-> add ('home2', ['controller' => 'HomeAdminController', 'action' => 'indexAction2']);
$ router-> add ('home3', ['controller' => 'HomeAdminController', 'action' => 'indexAction3']);
$ router-> add (product '', ['controller' => 'Product AdminController', 'action' => 'index']);
$ router-> add ('contact', ['controller' => 'ContactAdminController', 'action' => 'index']);
$ router-> add ('productList', ['controller' => 'ProductListAdminController', 'action' => 'index']);
I would like to automatically build this router so that I do not have to manually.
Does anyone know how to do it?
Related
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 } ?>
Using namespaces to create instances of database tables and controllers. When I try to load the 'RegisterController' I'm getting an error that 'Warning: require(../Furniture/Controllers/page.php): failed to open stream: No such file or directory in /srv/http/assignment/autoload.php on line 6'.
Find this odd as the instances of the database's are loading but the controller isn't?
//AutoLoad.php
<?php
function autoload($className)
{
$fileName = str_replace('\\', '/', $className) . '.php';
$file = '../' . $fileName;
require $file;
}
spl_autoload_register('autoload');
// Routes.php
<?php
namespace Furniture;
use Furniture\Conrollers\pageController;
class Routes implements \classes\Routes {
public function getRoutes(){
require '../classes/DatabaseConnection.php';
$furnitureTable = new \classes\databaseFunctions($pdo, 'furniture', 'id');
$categoryTable = new \classes\databaseFunctions($pdo, 'category', 'id');
$usersTable = new \classes\databaseFunctions($pdo, 'users', 'id');
$registerController = new \Furniture\Controllers\page($usersTable);
//$registerController = new \Furniture\Controllers\RegisterController($usersTable);
$routes = [
'' => [
'GET' => [
'controller' => $pageController,
'function' => 'home',
]
],
'about' => [
'GET' => [
'controller' => $pageController,
'function' => 'about',
]
]
];
return $routes;
}
}
//Pagecontroller.php
<?php
namespace Furniture\Controllers;
class page {
private $categoryTable;
public function __construct($usersTable)
{
$this->$usersTable = $usersTable;
}
public function home()
{
return ['template' => 'home-template.php',
'title' => 'This is the new home page',
'variables' => [
]
];
}
public function about()
{
return ['template' => 'about-template.php',
'title' => 'This is the new about page',
'variables' => [
]
];
}
public function faq()
{
return ['template' => 'faq-template.php',
'title' => 'This is the new faq page',
'variables' => [
]
];
}
public function contact()
{
return ['template' => 'contact-template.php',
'title' => 'This is the new contact page',
'variables' => [
]
];
}
public function furniture()
{
return ['template' => 'furniture-template.php',
'title' => 'This is the new furniture page',
'variables' => [
]
];
}
}
?>
//EntryPoint.php
<?php
namespace classes;
class EntryPoint {
private $routes;
public function __construct($routes){
$this->routes = $routes;
}
public function run() {
$route = strtolower(ltrim(explode('?', $_SERVER['REQUEST_URI'])[0], '/'));
$routes = $this->routes->getRoutes();
$method = $_SERVER['REQUEST_METHOD'];
$controller = $routes[$route][$method]['controller'];
$functionName = $routes[$route][$method]['function'];
$page = $controller->functionName();
$output = $this->loadTemplate('../templates/' . $page['template'], $page['variables']);
$title = $page['title'];
require '../templates/layout.html.php';
}
function loadTemplate($fileName, $templateVars) {
extract($templateVars);
ob_start();
require $fileName;
$content = ob_get_clean();
return $content;
}
}
As I undrestand the filename is Pagecontroller.php so please name your class accordingly to
Pagecontroller
//Pagecontroller.php
<?php
namespace Furniture\Controllers;
class Pagecontroller {
Alternative would be to rename your file to page.php as the error suggest it is looking for such a file
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
i'm trying to develop a PrestaShop module with controllers i placed, for example in:
/modules/mymodule/controllers/admin/myControlController.php
class MyControlController extends ModuleAdminController {
public function __construct() {
$this->module = 'mymodule';
$this->bootstrap = true;
$this->context = Context::getContext();
$token = Tools::getAdminTokenLite('AdminModules');
$currentIndex='index.php?controller=AdminModules&token='.$token.'&configure=mymodule&tab_module=administration&module_name=mymodule';
Tools::redirectAdmin($currentIndex);
parent::__construct();
}
public function showForm() {
die("hello");
}}
Controller works (construct method is called) if i call it form url
http://myshop.com/adminxxx/index.php?controller=MyControl&token=9faf638aa961468c8563ffb030b3c4a8
But i can't access methods of controller from main class of module:
ModuleAdminController::getController('MyControl')->showForm();
I received "Class not found" ever
Is that the correct method to access a control from outside?
Thanks!
If you want to show anything that concern a form you should use renderForm().
Your should try parent::showForm(); or $this->showForm();.
Here is an example of controller that can work :
require_once _PS_MODULE_DIR_.'modulename/models/ModuleNameLog.php';
require_once _PS_MODULE_DIR_.'modulename/modulename.php';
class AdminModuleNameLogController extends ModuleAdminController
{
protected $_defaultOrderBy = 'id_modulenamelog';
protected $_defaultOrderWay = 'DESC';
public function __construct()
{
$this->table = 'modulenamelog';
$this->className = 'ModuleNameLog';
$this->context = Context::getContext();
$this->lang = false;
$this->bootstrap = true;
$this->actions_available = array();
$this->actions = array();
$this->show_toolbar = false;
$this->toolbar_btn['new'] = array();
$this->tabAccess['add'] = '0';
$this->allow_export = true;
$this->requiredDatabase = true;
$this->page_header_toolbar_title = $this->l('Example Module Name logs');
$this->_select = 'SUM(a.quantity) as total_quantity';
$this->_group = ' GROUP BY a.id_product, a.id_product_attribute ';
$this->fields_list = array(
'id_product' => array(
'title' => $this->l('Product'),
'align' => 'center',
'callback' => 'getProductName',
),
'id_product_attribute' => array(
'title' => $this->l('Combination'),
'align' => 'center',
'callback' => 'getAttributeName',
),
'total_quantity' => array(
'title' => $this->l('Total Quantity'),
'align' => 'center',
),
);
$this->mod = new ModuleName();
$this->mod->cleanLogs();
$this->context = Context::getContext();
parent::__construct();
}
public function getProductName($id)
{
if (!empty($id)) {
$product = new Product($id, true, $this->context->cookie->id_lang);
return $product->name;
}
}
public function getAttributeName($id)
{
if (!empty($id)) {
$combination = new Combination($id);
$names = $combination->getAttributesName($this->context->cookie->id_lang);
$str = array();
if (!empty($names)) {
foreach ($names as $value) {
$str[] = $value['name'];
}
}
return implode(' - ', $str);
} else {
return '-';
}
}
public function postProcess()
{
if (Tools::isSubmit('purge_id')) {
// Do something here
$id = (int) Tools::getValue('purge_id');
Tools::redirectAdmin(self::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModuleNameLog').'&conf=4');
}
parent::postProcess();
}
public function renderList()
{
$carts = Db::getInstance()->executeS('SELECT ct.*, cs.`firstname`, cs.`lastname` FROM '._DB_PREFIX_.'cart ct LEFT JOIN '._DB_PREFIX_.'customer cs ON ct.id_customer = cs.id_customer WHERE 1 ORDER BY id_cart DESC LIMIT 0,2000');
$tpl = $this->context->smarty->createTemplate(_PS_MODULE_DIR_.'modulename/views/templates/admin/preform.tpl');
$tpl->assign(array(
'carts' => $carts,
));
$html = $tpl->fetch();
return $html.parent::renderList();
}
public function renderForm()
{
if (!$this->loadObject(true)) {
return;
}
$obj = $this->loadObject(true);
if (isset($obj->id)) {
$this->display = 'edit';
} else {
$this->display = 'add';
}
$array_submit = array(
array(
'type' => 'select',
'label' => $this->l('Cart :'),
'name' => 'id_cart',
'options' => array(
'query' => Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'cart WHERE id_cart > 0 ORDER BY id_cart DESC LIMIT 0,500'),
'id' => 'id_cart',
'name' => 'id_cart',
),
),
array(
'type' => 'text',
'label' => $this->l('Quantity translation here'),
'hint' => $this->l('Description and translation here'),
'name' => 'quantity',
),
);
$this->fields_form[0]['form'] = array(
'tinymce' => false,
'legend' => array(
'title' => $this->l('Form title'),
),
'input' => $array_submit,
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default',
),
);
$this->multiple_fieldsets = true;
return parent::renderForm();
}
}
I have a trouble:
I'm trying to create multilingual site. I want that all "French" pages have prefix "fre" and all "English" pages have no prefix at all.
but I have one trouble:
When I switch language to "fre" all links would be changed. But if I follow pass through one of new links I'll get page which consists links without prefix "fre"(except "Delete" current Item)
<?php
class AppController extends Controller
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Cookie');
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Items',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Categories',
'action' => 'index'
]
]);
$this->_init_language();
}
public function beforeFilter(Event $event)
{
$this->_setLanguage();
$this->Auth->allow(['index', 'view', 'display']);
}
public function redirect( $url, $status = NULL, $exit = true ) {
$session = $this->request->session();
if($session->check('Config.language')){
if (is_array($url) && !isset($url['language'])) {
$url['language'] = $session->read('Config.language');
}else{
$url = $session->read('Config.language');
}
}
parent::redirect($url,$status,$exit);
}
private function _init_language(){
$language = !isset($this->request->query['language']) ? $this->request->session()->read('Config.language')
: $this->request->query['language'];
switch($language)
{
case "du":
I18n::locale('du_DU');
break;
case "ru":
I18n::locale('ru_RU');
break;
case "jp":
I18n::locale('ja_JP');
break;
default:
I18n::locale('en_EN');
break;
}
}
private function _setLanguage()
{
$session = $this->request->session();
if ($this->Cookie->read('language') && !$session->check('Config.language')) {
$session->write('Config.language', $this->Cookie->read('language'));
}
else if (isset($this->request->query['language']) && ($this->request->query['language'] != $session->read('Config.language'))) {
$session->write('Config.language', $this->request->query['language']);
$this->Cookie->write('language', $this->request->query['language'], false, '20 days');
}
}
//LanguageHelper
<?php
namespace App\View\Helper;
use Cake\View\Helper\HtmlHelper;
class LanguageHelper extends HtmlHelper {
public function url($url = null, $full = false) {
$session = $this->request->session();
if(isset($this->request->query['language'])){
$language = $this->request->query['language'];
if(is_array($url) && !isset($url['language'])) {
$url['language'] = $language;
} else {
$url = $language;
}
}
return parent::url($url, $full);
}
public function link($title, $url = null, array $options = []){
if(isset($this->request->query['language'])){
$language = $this->request->query['language'];
if(is_array($url) && !isset($url['language'])) {
$url['language'] = $language;
} else{
$url = $language;
}
}
return parent::link($title, $url, $options);
}
//AppView
<?php
namespace App\View;
use Cake\View\View;
class AppView extends View
{
public function initialize()
{
$this->loadHelper('Html', [
'className' => 'Language'
]);
}
}
}
$routes->connect('/:language', ['controller' => 'Categories', 'action' => 'index'],['language' => 'ru|de|en|fr']);
$routes->connect('/:language/:controller/:action/*', [], ['language' => 'ru|de|en|fr','routeClass' => 'InflectedRoute']);
$routes->connect('/:language/:controller', ['action' => 'index'], ['language' => 'ru|de|en|fr','routeClass' => 'InflectedRoute']);
Thax for help!