I am trying to get this phalconphp OAuth2.0 wrapper working on my OAuth2.0 server.
The README of this repository is not very clear on how to use the namespaces.
I have followed the guide but I keep getting the following error :
Fatal error: Class 'Sum\Oauth2\Server\Storage\Pdo\Mysql\Client'
not found in C:\localhost\oauth2-phalcon\public\index.php on line 56
Here is my index.php file :
<?php
require __DIR__."/../vendor/autoload.php";
// Setup IIS Rewrite Rules
// Enable the verbs GET,PUT,POST,DELETE
// Check URL Scan for dissallowed seperators eg ; :
$config = new \Phalcon\Config([
'database' => [
'oauth' => [
'host' => 'localhost\test',
'port' => 1433,
'instance' => 'INSTANCENAME',
'username' => 'test',
'password' => 'test',
'dbname' => 'oauth',
'pdoType' => 'sqlsrv',
'dialectClass' => '\Twm\Db\Dialect\Mssql'
],
],
# ...
]);
# Register The Lib to the loader
$loader = new \Phalcon\Loader();
$loader->registerNamespaces([
"Twm\Db\Adapter\Pdo" => "../app/library/db/adapter/",
"Twm\Db\Dialect" => "../app/library/db/dialect/",
"League" => "../vendor/league/oauth2-server/src/League/OAuth2/Server",
//"Sum\Oauth2\Server\Storage\Pdo" => "../Oauth2/Server/Storage/Pdo/Mysql",
"Sum" => "../Oauth2/Server/Storage/Pdo/Mysql",
//"Sum\Oauth2\Server\Storage\Pdo\Mysql" => "../Oauth2/Server/Storage/Pdo/Mysql "
# ...
])->register();
$app = new \Phalcon\Mvc\Micro();
# set as service
$app->setService('oauth', function() use ($config) {
// HERE! We use our custom MSSQL Adapter
//$oauthdb = new Phalcon\Db\Adapter\Pdo\Mysql($config->database->oauth->toArray());
$oauthdb = new \Twm\Db\Adapter\Pdo\Mssql($config->database->oauth->toArray());
$server = new \League\OAuth2\Server\Authorization(
new \Sum\Oauth2\Server\Storage\Pdo\Mysql\Client($oauthdb),
new Sum\Oauth2\Server\Storage\Pdo\Mysql\Session($oauthdb),
new Sum\Oauth2\Server\Storage\Pdo\Mysql\Scope($oauthdb)
// new \Sum\Oauth2\Server\Client($oauthdb),
//new \Sum\Oauth2\Server\Session($oauthdb),
//new \Sum\Oauth2\Server\Scope($oauthdb)
);
# Not required as it called directly from original code
# $request = new \League\OAuth2\Server\Util\Request();
# add these 2 lines code if you want to use my own Request otherwise comment it
$request = new \Sum\Oauth2\Server\Storage\Pdo\Mysql\Request();
$server->setRequest($request);
$server->setAccessTokenTTL(86400);
$server->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
});
$app->get('/hello', function() use($world){
$world = "world";
echo "hello {$world}:)";
});
$app->get('/access', function () use ($app) {
try {
$params = $app->oauth->getParam(array('client_id', 'client_secret'));
echo json_encode(
$app->oauth
->getGrantType('client_credentials')
->completeFlow($params)
);
} catch (\League\OAuth2\Server\Exception\ClientException $e) {
echo $e->getTraceAsString();
} catch (\Exception $e) {
echo $e->getTraceAsString();
}
});
$app->handle();
//echo $app->handle()->getContent();
The project repository for the phalcon wrapper is here :
https://github.com/sumeko/phalcon-oauth2
I have contacted the author already but he is not replying to my emails.
I appreciate any help or advice, thanks.
UPDATE
So I solved my issue. Basically you need to have the standard OAuth2 library installed via composer and the phalconphp OAuth2 wrapper.
That solved it :)
This might be a long shot, but the problem might be with the autoloader that you are explicitly defining. If you use composer's autoload, you don't need to include Sum namespace in Phalcon's loader. Remove all vendor-specific paths from $loader->registerNamespaces() and only use require __DIR__ . "/../vendor/autoload.php" for that.
Also, it's often more convenient use composer's autoloader for your internal things too, e.g.:
{
"require": {
"phpunit/dbunit": "*",
"phpunit/phpunit": "*",
"…": "…"
},
"autoload": {
"psr-0": {
"": "../src"
}
}
}
So I solved my issue. Basically you need to have the standard OAuth2 library installed via composer and the phalconphp OAuth2 wrapper. That solved it :)
Related
I am trying out Slim 4 (I've previously used Slim 3 but many things seem to have changed in the new versions of Slim and Twig) and I have a very simple starter application:
<?php
use DI\Container;
use Slim\Views\Twig;
use Slim\Factory\AppFactory;
use Slim\Views\TwigMiddleware;
use Slim\Middleware\ErrorMiddleware;
// Autoload
require 'vendor/autoload.php';
// Create Container using PHP-DI
$container = new Container();
AppFactory::setContainer($container);
// Create the app
$app = AppFactory::create();
// Show meaningful errors with ErrorMiddleware
$errorMiddleware = new ErrorMiddleware(
$app->getCallableResolver(),
$app->getResponseFactory(),
true,
false,
false
);
$app->add($errorMiddleware);
// Set view in Container
$container->set('view', function() {
return Twig::create('views', [
'auto_reload' => true,
'cache' => false
]);
});
$app->add(TwigMiddleware::createFromContainer($app));
// Define routes
$app->get('/', function($req, $res) {
return $this->get('view')->render($res, 'home.twig');
});
$app->get('/heroes', function($req, $res) {
$users = [
'Batman',
'Supes',
'Flash'
];
return $this->get('view')->render($res, 'heroes.twig', [
'users' => $users
]);
});
// Run the app
$app->run();
After several tests I have noticed that if I make a change, for example if I type a different twig file or if I write a different route, changes are not reflected when I refresh the browser. No matter how many times I hit refresh, changes are not reflected until approx. a minute later.
I'm using MAMP PRO v6.6. The project is built with the following dependencies:
{
"require": {
"slim/slim": "^4.10",
"slim/psr7": "^1.5",
"php-di/php-di": "^6.4",
"slim/twig-view": "^3.3"
}
}
I have added auto-reload and cache settings to the Twig creation but this doesn't seem to have any effect.
I ended up going into the php.ini file and commenting out the OPCache block towards the end of the file. That took care of it.
I have setup new laravel v5.3 project and install elastic search driver to implement elastic search via composer. But when I reload my page then I always receive This page isn’t working even the elastic search is running on my system below is my complete code that I code.
composer.json
"require": {
"php": ">=5.6.4",
"elasticsearch/elasticsearch": "^6.0",
"laravel/framework": "5.3.*"
},
web.php
Route::get('/',array('uses' => 'ElasticSearch#addPeopleList'));
Controller
<?php
namespace App\Http\Controllers;
class ElasticSearch extends Controller
{
// elastic
protected $elastic;
//elastic cliend
protected $client;
public function __construct(Client $client)
{
$this->client = ClientBuilder::create()->build();
$config = [
'host' =>'localhost',
'port' =>9200,
'index' =>'people',
];
$this->elastic = new ElasticClient($config);
}
public function addPeopleList(){
echo "<pre>";
print_r($this->$elastic);
exit;
}
}
But when I refresh the page then This page isn’t working i received this message and page not loaded one thing that I want to let you know that I made no changes in app.php file of configuration. Please eduacate to solve this issue.
if You want to instantiate an elastic client with some configuration, You should use method ClientBuilder::fromConfig(array $config).
In your case it should be
<?php
$client = ClientBuilder::fromConfig([
'hosts' => [ 'localhost:9200' ]
]);
As You can notice above hosts must be provided as array.
Also I'm not sure that Elasticsearch client that You use have ElasticClient class.
Also if You provided actual code from your controller than it contains an error. You should call class properties like that: print_r($this->client) (without $ near the property name).
Finaly your controller should looks like this:
<?php
namespace App\Http\Controllers;
use Elasticsearch\ClientBuilder;
class ElasticSearch extends Controller
{
/**
* #var \Elasticsearch\Client
*/
protected $client;
public function __construct()
{
$this->client = ClientBuilder::fromConfig([
'hosts' => [
'localhost:9200',
],
]);
}
public function addPeopleList(){
echo "<pre>";
print_r($this->client);
exit;
}
}
And to add a document to the index You need to call this command according to the official documentation
$params = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => ['testField' => 'abc']
];
$response = $client->index($params);
print_r($response);
Official documentation can be found here https://github.com/elastic/elasticsearch-php
P.S. Sorry for my English. It is far from perfect.
I'm using the google-trends library and installed it with composer
composer update jonasva/google-trends
my composer.json:
{
"require": {
"jonasva/google-trends": "dev-master"
}
}
I included the file start.php in the main folder:
require __DIR__ . '/vendor/autoload.php';
$config = [
'email' => 'myemail#gmail.com',
'password' => 'mypass',
];
$session = (new GoogleSession($config))->authenticate();
$response = (new GoogleTrendsRequest($session))
->setDateRange(new \DateTime('2014-02-01'), new \DateTime()) // date range, if not passed, the past year will be used by default
->setLocation('BE') // For location Belgium
->getTopQueries() // cid (top queries)
->send(); //execute the request
$data = $response->getTermsObjects(); // return an array of GoogleTrendsTerm objects
But I get
Fatal error: Class 'GoogleSession' not found in
Should I include files other than vendor/autoload.php?
The author conveniently didn't mention the fact that the actual fully qualified class name is Jonasva\GoogleTrends\GoogleSession.
use Jonasva\GoogleTrends\GoogleSession; at the top of your file.
Check the source code of the library to figure out such information.
You have to use FQDN. Namespace + Classname
$session = (new Jonasva\GoogleTrends\GoogleSession($config))->authenticate();
I'm using Slim Framework together with Laravel's Eloquent ORM and this is my code:
User.php
class User extends \Illuminate\Database\Eloquent\Model
{
protected $table = 'accounts';
}
index.php
require_once 'vendor/autoload.php';
// Models
include 'app/models/User.php';
$app = new \Slim\Slim();
// Database information
$settings = array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'photo_mgmt',
'username' => 'root',
'password' => '',
'collation' => 'utf8_general_ci',
'prefix' => '',
'charset' => 'utf8',
);
$container = new Illuminate\Container\Container;
$connFactory = new \Illuminate\Database\Connectors\ConnectionFactory($container);
$conn = $connFactory->make($settings);
$resolver = new \Illuminate\Database\ConnectionResolver();
$resolver->addConnection('default', $conn);
$resolver->setDefaultConnection('default');
\Illuminate\Database\Eloquent\Model::setConnectionResolver($resolver);
$app->get('/', function () use ($app) {
$users = \User::all();
echo $users->toJson();
});
$app->run();
As you can see in my code, I have to include the User.php file in my index.php. But what if I have multiple models? Can I just include a folder and all models will also be included so that it won't look messy including every model file in my index.
Thank you in advance.
UPDATE:
I'm using this piece of code I saw
foreach (glob("app/models/*.php") as $filename)
{
include $filename;
}
Is there a cleaner looking way?
You can use Composer to automatically include classes from your project. Let's say your composer.json file lives in app. Then you can use the classmap attribute in your composer.json to automatically include all classes in models:
...
"require": {
"php" : ">=5.4.0",
"slim/slim" : "2.*",
"illuminate/database" : "5.0.33",
...
},
"autoload": {
"classmap" : [
"models"
]
}
The classmap tells Composer to map all classes in the specified directory(ies). Then, all you need to do is run composer update to update Composer's list of includes whenever you add a new file to this directory.
Yes, there is a much cleaner way to do this, namely autoloading.
It boils down to the use of spl_autoload_register() and of a custom class loader.
The principle is to mimic the namespace with the file hierarchy and load these accordingly to the namespace:
$loader = function load($class)
{
include __DIR__."/app/$class.php";
}
spl_autoload_register($loader);
$user = new models\User();
This will automatically include the file located at app/models/User.php. It is a good practice to respect uppercases in your namespace; if you namespace is Model\User, the directory should respect the casing (app/Model/User.php)
The problem with your current solution:
foreach (glob("app/models/*.php") as $filename)
{
include $filename;
}
is that it will load all classes, even if the script will not use them. Registering an autoloader will prevent that, only loading the necessary code.
I created a simple Phalcon project using Phalcon DevTools (1.2.3).
Now I want to use MongoDB for the database. How do I set this up correctly?
I came this far (see code below):
This is my config.php
<?php
return new \Phalcon\Config(array(
'database' => array(
'adapter' => 'Nosql', //Was 'Mysql', but Nosql is not supported?
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'test',
),
'application' => array(
'controllersDir' => __DIR__ . '/../../app/controllers/',
'modelsDir' => __DIR__ . '/../../app/models/',
'viewsDir' => __DIR__ . '/../../app/views/',
'pluginsDir' => __DIR__ . '/../../app/plugins/',
'libraryDir' => __DIR__ . '/../../app/library/',
'cacheDir' => __DIR__ . '/../../app/cache/',
'baseUri' => 'localhost/',
)
));
This is my services.php
<?php
use Phalcon\DI\FactoryDefault,
Phalcon\Mvc\View,
Phalcon\Mvc\Url as UrlResolver,
//Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter, //Do I need this when I use Mongo?
Phalcon\Mvc\View\Engine\Volt as VoltEngine,
Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter,
Phalcon\Session\Adapter\Files as SessionAdapter;
/**
* The FactoryDefault Dependency Injector automatically register the right services providing a full stack framework
*/
$di = new FactoryDefault();
/**
* The URL component is used to generate all kind of urls in the application
*/
$di->set('url', function() use ($config) {
$url = new UrlResolver();
$url->setBaseUri($config->application->baseUri);
return $url;
}, true);
/**
* Setting up the view component
*/
$di->set('view', function() use ($config) {
$view = new View();
$view->setViewsDir($config->application->viewsDir);
$view->registerEngines(array(
'.volt' => function($view, $di) use ($config) {
$volt = new VoltEngine($view, $di);
$volt->setOptions(array(
'compiledPath' => $config->application->cacheDir,
'compiledSeparator' => '_'
));
return $volt;
},
'.phtml' => 'Phalcon\Mvc\View\Engine\Php'
));
return $view;
}, true);
/**
* Database connection is created based in the parameters defined in the configuration file
*/
$di->set('mongo', function() use ($config) {
$mongo = new Mongo();
return $mongo->selectDb($config->database->dbname);
});
/**
* If the configuration specify the use of metadata adapter use it or use memory otherwise
*/
$di->set('modelsMetadata', function() {
return new MetaDataAdapter();
});
/**
* Start the session the first time some component request the session service
*/
$di->set('session', function() {
$session = new SessionAdapter();
$session->start();
return $session;
});
I altered the standard mysql db connection to be mongo, using the documentation.
But now I have to set up my database adapter in Config, but Nosql doesn't seem to work. DevTools throws this error in the terminal when trying to create a model:
Error: Adapter Nosql is not supported
When I do put in ' Mysql' for the adapter in the config and try to create a model, this is the error I get:
Error: SQLSTATE[HY000] [2002] No such file or directory
Does it need the Mysql adapter to be set in order to use Mongo/Nosql? Or should I put in something else for the adapter/config? Any ideas?
within service.php file where you have mongo service registered
$di->set('mongo', function() {
$mongo = new Mongo();
return $mongo->selectDb("DB_NAME");
}, true);
below that put following lines of code,
$di->set('collectionManager', function(){
return new Phalcon\Mvc\Collection\Manager();
}, true);
After the above is done you need to ensure that your model is extending from \Phalcon\Mvc\Collection
E.g. Customers.php
class Customers extends \Phalcon\Mvc\Collection
{
public $name;
public $email;
}
Once above is done, you can verify if everything is working fine as follows
$robot = new Customers();
$robot->email= "abc#test.com";
$robot->name = "XYZ";
if ($robot->save() == false)
{
echo "Could not be Saved!!";
}
else
{
echo "Data Saved!!";
}
You can put above code in any Controller-Action and try.
If everything goes well, you should be able to see one document created within Customer collection within your database of MongoDB.
Refer http://docs.phalconphp.com/en/latest/reference/odm.html for more..
$di->set('mongo', function() {
$user = 'blog';
$password = 'blog';
$host = 'localhost';
$port = '27017';
$db = 'blog';
$cn = sprintf('mongodb://%s:%d/%s',$host,$port,$db);
$con = new Mongo($cn,array('username'=>$user,'password'=>$password));
return $con->selectDB($db);
}, true);
As of the latest PhalconPHP, MongoDB seems to be a supported option for cache only, not for using as a replacement for the database.
It looks there is no MongoDB adapter for the Config component, only MySQL and couple of others (text based) in the incubator (https://github.com/phalcon/incubator).
You can still use MongoDB for the ACL and your Models though, see https://github.com/phalcon/incubator/tree/master/Library/Phalcon/Acl/Adapter and http://docs.phalconphp.com/en/latest/reference/odm.html#