Split configuration in more files in Silex - php

I am using Silex PHP framework.
I have two files, the first is app.php:
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ParameterBag;
use Silex\ControllerProviderInterface;
$app = new Silex\Application();
$app['debug'] = true;
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
'db.options' => array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'dbname' => 'testapp',
'user' => 'root',
'password' => 'turoke55u',
),
));
$app->before(function (Request $request) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
});
$app->mount('/', include 'login.php');
$app->run();
And the second is login.php:
<?php
use Symfony\Component\HttpFoundation\Request;
$login = $app['controllers_factory'];
$login->post('/apiv1/user/login', function (Request $request) use ($login) {
$userinfo = array(
'email' => $request->request->get('email'),
'mode' => $request->request->get('mode'),
'password' => $request->request->get('password'),
);
$passwordcoding = sha1($userinfo['email']."66643asd");
$emailverification = "SELECT email,password FROM user WHERE email='".$userinfo['email']."'";
$selectemail = $login['db']->$fetchAll('SELECT * FROM user');
var_dump($emailverification);
});
return $login;
When I run the select on db I get this error:
Cannot use object of type Silex\ControllerCollection as array in /mnt/hgfs/Share_Folder/frontend/src/login.php on line 13
Does someone know a solution for that issue?
I have a second question, why if I change in app.php this:
$app->mount('/', include 'login.php');
To this:
$app->mount('/apiv1/user/login', include 'login.php');
And in login.php:
$login->post('/',
Like in the Silex documentation, the framework doesn't work?

You have a silly error in your function signature:
<?php
use Symfony\Component\HttpFoundation\Request;
$login = $app['controllers_factory'];
$login->post('/apiv1/user/login', function (Request $request) use ($login) {
// ^^^^^^^^
// this should be $app, not $login as this function is using the container
$userinfo = array(
'email' => $request->request->get('email'),
'mode' => $request->request->get('mode'),
'password' => $request->request->get('password'),
);
$passwordcoding = sha1($userinfo['email']."66643asd");
$emailverification = "SELECT email,password FROM user WHERE email='".$userinfo['email']."'";
// here you're using the $login as the container and it's a controller collection, so in the signature use the container not the $login
// vvvvvvvvvvvv
$selectemail = $login['db']->$fetchAll('SELECT * FROM user');
var_dump($emailverification);
});
return $login;
As for the second doubt you should elaborate more on "the framework doesn't work", explain the symptoms and the output (if error which error?)

Related

How to connect Postgresql database in Slim framework with PDO?

I work with MYSQL database in slim framework. Its perfectly worked.
But going to connect Postgresql, It not connected as well.
Here is the sample Coding: (settings.php)
declare(strict_types=1);
use App\Application\Settings\Settings;
use App\Application\Settings\SettingsInterface;
use DI\ContainerBuilder;
use Monolog\Logger;
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
SettingsInterface::class => function () {
return new Settings([
'displayErrorDetails' => true, // Should be set to false in production
'logError' => true,
'logErrorDetails' => true,
'logger' => [
'name' => 'slim-app',
'path' => isset($_ENV['docker']) ? 'php://stdout' : __DIR__ . '/../logs/app.log',
'level' => Logger::DEBUG,
],
"db" =>
[
'driver' => 'pgsql',
'host' => 'localhost',
'port' => '5433',
'database' => 'test_db',
'username' => 'postgres',
'password' => 'password',
'prefix' => '',
'schema' => 'public',
]
]);
}
]);
};
Here is the code : (dependencies.php)
<?php
declare(strict_types=1);
use App\Application\Settings\SettingsInterface;
use DI\ContainerBuilder;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\UidProcessor;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
LoggerInterface::class => function (ContainerInterface $c) {
$settings = $c->get(SettingsInterface::class);
$loggerSettings = $settings->get('logger');
$logger = new Logger($loggerSettings['name']);
$processor = new UidProcessor();
$logger->pushProcessor($processor);
$handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']);
$logger->pushHandler($handler);
return $logger;
},
PDO::class => function (ContainerInterface $c)
{
$settings = $c->get(SettingsInterface::class);
$dbSettings = $settings->get("db");
$host = $dbSettings['host'];
$dbname = $dbSettings['database'];
$username = $dbSettings['username'];
$password = $dbSettings['password'];
$port = $dbSettings['port'];
$dsn = new PDO ("pgsql:host=$host;port=$port;dbname=$dbname");
return new PDO($dsn, $username, $password);
},
]);
};
Here checking for database connection : (routes.php)
<?php
declare(strict_types=1);
use App\Application\Actions\User\ListUsersAction;
use App\Application\Actions\User\ViewUserAction;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
use Slim\Interfaces\RouteCollectorProxyInterface as Group;
return function (App $app) {
$app->options('/{routes:.*}', function (Request $request, Response $response) {
// CORS Pre-Flight OPTIONS Request Handler
return $response;
});
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('Hello world!');
return $response;
});
$app->group('/users', function (Group $group)
{
$group->get('', ListUsersAction::class);
$group->get('/{id}', ViewUserAction::class);
});
$app->post('/db-select', function (Request $request, Response $response)
{
$db = $this->get(PDO::class);
$sth = $db->prepare("SELECT * FROM login");
$sth->execute();
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
$payload = json_encode($data);
$response->getBody()->write($payload);
return $response->withHeader('Content-Type', 'application/json');
});
};
If I run the command such as localhost:8000/db-select Its give me the following error:
{
"statusCode": 500,
"error": {
"type": "SERVER_ERROR",
"description": "SQLSTATE[08006] [7] fe_sendauth: no password supplied"
}
}
I worked the sample code for MYSQL it worked perfect.
What else missed for Postgresql connection?
Check extension for PostgreSQL is enabled
extension=pdo_pgsql
Also you may take help fromm this question
fe_sendauth: no password supplied error in postgresql + laravel
Here is a bug:
$dsn = new PDO ("pgsql:host=$host;port=$port;dbname=$dbname");
return new PDO($dsn, $username, $password);
Try this:
return new PDO("pgsql:host=$host;port=$port;dbname=$dbname", $username, $password);

How to make Restful API in Codeigniter?

I am having problems when trying the API that I made. When I tested it in Postman, it appeared false, even though my username and password were correct. Can you identify the problem with my code?
I really appreciate your help.
Auth_admin.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH . '/libraries/REST_Controller.php';
class Auth_admin extends REST_Controller
{
public function signin_post()
{
$this->load->model('model_admin', 'admin');
$params = array(
'username' => $this->post('username'),
'password' => md5($this->post('password'))
);
$result = $this->admin->admin_check($params);
if ($result){
if ($result->level == "admin"){
$response = array(
"status" => true,
"message" => "Authentication seccessfully",
"auth" => array(
"username" => $result->username
)
);
$this->set_response($response, REST_Controller::HTTP_OK);
}else{
$response = array(
"status" => false,
"message" => "This features does'nt exist for your Account"
);
$this->set_response($response, REST_Controller::HTTP_OK);
}
}
}
}
Model_admin.php
<?php
class Model_admin extends CI_Model
{
var $tablename;
public function __construct()
{
parent::__construct();
$this->tablename = "m_admin";
}
public function admin_check($data = array())
{
$params = array(
'username' => $data['username'],
'password' => $data['password'],
);
$this->db->where($params);
$query = $this->db->get($this->tablename);
return $query->row();
}
}
You have to pass function name after the controller name.
Like your path: http://192.168.122.1/project_name/auth_admin/signin it will work.
If that does not work, then please add index.php and check it because it depends on how you setup the project.

Slim 3 Controller Issue: Using $this when not in object context

Having an issue using $this->container inside of my controllers.
When I try to access the logger/monolog in the code below, it fails miserably:
$this->container->get('logger')->addInfo('Request: users->get-one');
Here's the code in src/dependancies.php:
<?php
$container = $app->getContainer();
// monolog
$container['logger'] = function ($c) {
$logs = $c->get('settings')['logger'];
$logger = new Monolog\Logger($logs['name']);
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
$logger->pushHandler(new Monolog\Handler\StreamHandler($logs['path'], $logs['level']));
return $logger;
};
// database
$container['db'] = function ($c) {
$database = $c->get('settings')['database'];
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection([
'driver' => 'mysql',
'host' => $database['hostname'],
'database' => $database['database'],
'username' => $database['username'],
'password' => $database['password'],
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
]);
$capsule->setAsGlobal();
$capsule->bootEloquent();
return $capsule;
};
// register users controller
require __DIR__ . '/../src/controllers/users.php';
$container['UsersController'] = function($c) {
return new UsersController($c);
};
Below is the code that's in src/controllers/users.php:
<?php
use Psr\Container\ContainerInterface;
use Slim\Http\Request;
use Slim\Http\Response;
class UsersController {
protected $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
public function get(Request $request, Response $response, $args) {
$this->container->get('logger')->addInfo('Request: users->get-one');
/**
* TODO: Replace $args['id'] with the id from the current token payload
*/
$data = Users::find($args['id']);
return $response->withJSON($data)->withStatus(200);
}
public function create(Request $request, Response $response, $args) {
$this->logger->addInfo('Request: users->create');
$user = $request->getParsedBody();
$data = Users::create([
'first_name' => $user['first_name'],
'last_name' => $user['last_name'],
'email' => $user['email'],
'password' => password_hash($user['password'], PASSWORD_BCRYPT),
'telephone' => $user['telephone'],
'timezone' => $user['timezone'],
'verification' => '011010'
]);
return $response->withJSON($data)->withStatus(200);
}
public function update(Request $request, Response $response, $args) {
$this->logger->addInfo('Request: users->update');
$user = $request->getParsedBody();
$data = Users::where('id', $args['id'])->update([
'first_name' => $user['first_name'],
'last_name' => $user['last_name'],
'email' => $user['email'],
'password' => password_hash($user['password'], PASSWORD_BCRYPT),
'telephone' => $user['telephone'],
'timezone' => $user['timezone']
]);
return $response->withJSON($data)->withStatus(200);
}
public function delete(Request $request, Response $response, $args) {
$this->logger->addInfo('Request: users->delete');
$data = Users::destroy($args['id']);
return $response->withJSON($data)->withStatus(200);
}
/*
* ==============================
* Manager Functions Routines
* ==============================
*/
public function getAll(Request $request, Response $response, $args) {
$this->logger->addInfo('Request: admin->users->getAll');
$data = Users::all();
return $response->withJSON($data)->withStatus(200);
}
}
I have tried following different tutorials as well as the documentation on the Slim website however, nothing has seemed to fix the issue. I am sure it's something easily fixed that I am just missing.
PHP Slim 3 Framework - Use MonoLog in Custom Class - Using $this when not in object context - The accepted answer here just seems silly to do when I want to be able to access the entire app container and NOT just the logger.
Any help is appreciated.
Thank you!
Well, I figured it out. Apparently using two semicolons when invoking the controller routine is not the proper way of doing things. Oops!
/*
* users::read::one
* method:get
*/
$app->get('/users', '\UsersController::get');
When the code above is adjust to only use one semicolon, it works:
/*
* users::read::one
* method:get
*/
$app->get('/users', '\UsersController:get');

custom user(customers) table password-reset for is not working - Laravel(working with API)

I do have trouble in setting password reset facility for custom user table (suppose 'customers' table). It was successful to generate a token for password reset but unable to do the reset because of Laravel considering its default table 'users', not the table I suppose to do reset. Changing default table users to customers in Config\Auth.php generate validation error
Passwords must be at least six characters and match the confirmation.
I just copy/pasting what I did so far
<?php
/*
Code Done by Arun
*/
namespace App\Http\Controllers\API\ResetPassword;
use App\Http\Controllers\API\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Password;
use App\Model\Customer;
use Laravel\Passport\Client;
use Illuminate\Support\Facades\Auth;
class ResetPasswordController extends Controller
{
use ResetsPasswords;
public function __construct()
{
$this->middleware('api');
}
protected function guard()
{
return Auth::guard('api');
}
public function ResetPassword(Request $request)
{
$v = validator($request->only('email', 'token', 'password','confirm_password'), [
'token' => 'required|string|max:255',
'email' => 'required|string|email|max:255',
'password' => 'required|string',
'confirm_password' => 'required|string|min:6',
]);
if ($v->fails()) {
return response()->json(["error"=>$v->errors()->all()], 400);
}
else
{
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
});
}
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->customResetFailedResponse($request, $response);
// $client = Client::where('password_client', 1)->first();
// $request->request->add([
// 'grant_type' => 'password',
// 'client_id' => $client->id,
// 'client_secret' => $client->secret,
// 'username' => $request->email,
// 'password' => $request->password,
// 'scope' => null,
// ]);
// // Fire off the internal request.
// $proxy = Request::create(
// 'oauth/token',
// 'POST'
// );
// return $response ;
}
}
Any Laravel expert can help me with the problem?
Im finally able to figure this out, im just posting answer may help others come across the same problem.
<?php
namespace App\Http\Controllers\API\Auth;
use App\Http\Controllers\API\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Password;
use App\Model\Customer;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
use GuzzleHttp\Client;
use DB;
class ResetPasswordController extends Controller
{
use ResetsPasswords;
protected $confirmEmail = false;
public function __construct()
{
}
public function resetPasswordCustomer(Request $request)
{
//Custome password reset mail has done in customer model
$v = validator($request->only('token', 'password','password_confirmation'), [
'token' => 'required|string|max:255',
'password' => 'required|string',
'password_confirmation' => 'required|string|min:6',
]);
if ($v->fails()) {
return response()->json(["error"=>$v->errors()->all()], 400);
}
else
{
$request->merge(['email'=> $this->checkTokenAgainstHashedValue($request->token)]);//Add new property to request..
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
});
}
return $response == Password::PASSWORD_RESET
? $this->authToken($request)
: $this->customResetFailedResponse($request, $response);
return $response ;
}
protected function checkTokenAgainstHashedValue($token)
{
$resetTable = DB::table('password_reset_customers')->select('token','email')->get();
foreach ($resetTable as $value) {
if (Hash::check($token, $value->token)) {
return $value->email;
}
}
return null;
}
protected function authToken(Request $request)
{
$http = new Client();
$response = $http->post('http://abcd.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' =>'qazrxGbDwrwbYXwbEbbkUFNO1zGB3eFYQN3AbG3m',
'username' => Auth::user()->email,
'password' => $request->password,
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
}
public function broker()
{
return Password::broker('customers');
}
}

EDIT: Class Zend\Db\Adapter\Adapter not found

I have a simple form which after submitting redirects to processAction inside AuthController and in this action I want to create a simple table bar.
EDITED:
Referring to Zend framerwork DB DDL update, I made a little modification in below code
AuthController.php
<?php
namespace Blog\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Debug\Debug;
use Blog\Form\LoginForm;
use Zend\Authentication\AuthenticationService;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Ddl;
use Zend\Db\Sql\Ddl\Column;
use Zend\Db\Sql\Insert;
use Zend\Authentication\Adapter\DbTable as DbTableAuthAdapter;
class AuthController extends AbstractActionController
{
protected $adapter;
public function getAdapter()
{
if (!$this->adapter) {
$sm = $this->getServiceLocator();
$this->adapter = $sm->get('Zend\Db\Adapter\Adapter');
}
return $this->adapter;
}
public function indexAction()
{
return new ViewModel();
}
public function processAction()
{
$DB = new \Zend\Db\Adapter\Adapter(array(
'driver' => 'Pdo',
'database' => 'blog',
'username' => 'root',
'password' => 'mysql'
));
$this->adapter = $this->getAdapter();
$sql = new Sql($this->adapter);
$table = new Ddl\CreateTable('bar');
$table->addColumn(new Column\Integer('id'));
$table->addColumn(new Column\Varchar('name', 255));
$table->setTable('bar');
$results = $this->adapter->query($sql->getSqlStringForSqlObject($table), $this->adapter ::QUERY_MODE_EXECUTE);
return new ViewModel();
}
}
global.php:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=blog;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
Module.php
<?php
namespace Blog;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements AutoloaderProviderInterface,ConfigProviderInterface
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getServiceConfig()
{
return array(
'factories' =>array(
'Zend\Db\Adapter\Adapter' => function ($sm) {
$config = $sm->get('Config');
return new \Zend\Db\Adapter\Adapter($config['db']);
}
)
);
}
}
Problem:(Updated)
table bar is not created and shows error like
Fatal error: Class 'Blog\Controller\Zend\Db\Adapter\Adapter' not found
in /var/www/zend2/module/Blog/src/Blog/Controller/AuthController.php
on line 110
if I print
echo $sql->getSqlStringForSqlObject($table);
The query prints like this
CREATE TABLE `bar` ( `id` INTEGER NOT NULL, `name` VARCHAR(255) NOT NULL )
but table was not there.
Error occurs in below line of code as it is not able to identify adapter :
$results = $this->adapter->query($sql->getSqlStringForSqlObject($table), $this->adapter ::QUERY_MODE_EXECUTE);
But works in this way:
$results = $this->adapter->query($sql->getSqlStringForSqlObject($table), $DB ::QUERY_MODE_EXECUTE);
I am using Zend 2.4
I think you are trying to access non existing service. You can try to create a service factory:
config.php
<?php
return [
'db' => [
'driver' => 'Pdo',
'database' => 'blog',
'username' => 'root',
'password' => 'mysql'
]
];
Module.php
<?php
class Module
{
public function getServiceConfig()
{
return [
'factories' => [
'Zend\Db\Adapter\Adapter' => => function ($sm) {
$config = $sm->get('Config');
return new \Zend\Db\Adapter\Adapter($config['db']);
},
],
];
}
}
Then, you can access the service with the service manager:
AuthController.php
class AuthController extends AbstractActionController
{
public function getAdapter()
{
if (!$this->adapter) {
$sm = $this->getServiceLocator();
$this->adapter = $sm->get('Zend\Db\Adapter\Adapter');
}
return $this->adapter;
}
public function processAction()
{
$this->adapter = $this->getAdapter();
$sql = new Sql($this->adapter);
// other stuff here
}
}
You can find more examples here and here.
For beginners in ZF2 ,the query execute won't work if you don't instantiate class Zend\Db\Adapter\Adapter correctly.
I corrected like
$DB = new \Zend\Db\Adapter\Adapter(array(
'driver' => 'Pdo',
'database' => 'blog',
'username' => 'root',
'password' => 'mysql'
));
Also below line of code :
$results = $this->adapter->query($sql->getSqlStringForSqlObject($table), $DB ::QUERY_MODE_EXECUTE);
Ref Fatal error : class not found in Zend framework 2
Note: I still fail to understand why $this->adapter = $this->getAdapter(); not working instead of $DB.Any hint will be appreciated.

Categories