Laravel controller doesn't exist - php

Ok, so I haven't had this issue in a while, but I've done most the options I can to resolve this and have read other people's posts. I'm at a lost right now.
After creating the controller, I did the "php ./composer.phar dump-autoload" command, saying it generated successfully, and it's still saying the controller doesn't exist. There are already 3 other controllers in the folder it's in, and each one of those works, it's just this controller that's having the problem.
Code to Controller: (/apps/controllers/api/apiBulkController.php)
class apiBulkController extends BaseController {
private $error;
public function __construct()
{
// Set default values
$this->error = 'false';
}
public function create()
{
$bulk = array();
// Authenticate the user using the api
if (!isset($_SERVER['PHP_AUTH_USER'])) {
$this->authenticate();
} else {
$auth = User::where('username', $_SERVER['PHP_AUTH_USER'])->first();
// Check to see if the user is valid
if(isset($auth->authkey) && $auth->authkey == $_SERVER['PHP_AUTH_PW'])
{
$req = Request::get();
$bulk = new Bulk;
// Add Columns by example below
$bulk->save();
//ex. $Bulk->Name = Request::get(''); $object->column_name = Request;
// Return JSON data
return Response::json(array(
'error' => $this->error
));
}
else
{
echo $_SERVER['PHP_AUTH_USER'].": Your hash seems to be incorrect.";
}
}
}
public function authenticate()
{
header('WWW-Authenticate: Basic realm="User Authentication (Username / Hash)"');
header('HTTP/1.0 401 Unauthorized');
echo "You must enter a valid Login ID and Hash to access this resource\n";
exit;
}
}

You should probably add
namespace api;
at the beginning of your controller
and run controller also using your namespace before class name, for example in Route api\apiBulkController#create instead of apiBulkController#create.
If error changes, you should then alter your class adding namespaces or uses to other classes for example instead of extends BaseController should be extends \BaseController and so on

Related

How do you return custom errors from CakePHP AuthComponent?

I am currently adding a CakePHP 3 Authentication component to and existing CakePHP application following the documentation listed here:
https://book.cakephp.org/3/en/controllers/components/authentication.html
I am currently handling the display of error messages, following this example:
https://book.cakephp.org/3/en/controllers/components/authentication.html#identifying-users-and-logging-them-in
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error(__('Username or password is incorrect'));
}
}
}
I am integrating the auth components following the documentation here, where an array of user data is returned if a user is able to be authenticated and false if they are not (as specified in the docs):
https://book.cakephp.org/3/en/controllers/components/authentication.html#creating-custom-authentication-objects
namespace App\Auth;
use Cake\Auth\BaseAuthenticate;
use Cake\Http\ServerRequest;
use Cake\Http\Response;
class OpenidAuthenticate extends BaseAuthenticate
{
public function authenticate(ServerRequest $request, Response $response)
{
// Do things for OpenID here.
// Return an array of user if they could authenticate the user,
// return false if not.
if($failureCondition) {
return false;
}
return $user;
}
}
However I would like to dynamically determine the error in the auth component:
namespace App\Auth;
use Cake\Auth\BaseAuthenticate;
use Cake\Http\ServerRequest;
use Cake\Http\Response;
class OpenidAuthenticate extends BaseAuthenticate
{
public function authenticate(ServerRequest $request, Response $response)
{
if($failureConditionA) {
$this->error = 'Error A';
return false;
}
if($failureConditionB) {
$this->error = 'Error B';
return false;
}
return $user;
}
}
And print the dynamically produced error in the flash message like so:
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
} else {
// 'Error A' or 'Error B' displayed on failure
$this->Flash->error($this->Auth->error());
}
}
}
What is the correct code to use to do this?
If this violates the intention behind how the AuthComponent is supposed to function, I would be interested to have that explained and / or know any other correct ways to do this?
Thanks in advance!
There's no overly clean way of exposing error details, the whole auth component stuff was never specifically designed to return failure details.
There's lots of ways to solve this, the most simple one would probably be to obtain a specific authentication object, and access the errors that the object stored via a public API that it would need to implement, ie your authenticator could for example expose a getError() method, then you could something like this in your controller:
$openIdAuth = $this->Auth->getAuthenticate('Openid');
$error = $openIdAuth->getError();
For something a little more sophisticated you could implement a custom/extended authentication component, where you have access to the complete list of authentication objects and can easily access the last one in the chain and return possible error information that it holds.
If you're implementing authentication into an application that doesn't yet use any authentication, then I'd very, very strongly recommend that you ditch the deprecated auth component, and use the new authentication plugin instead! It's way cleaner and much more versatile, and returning error details is supported out of the box.

MVC Class between controller and Model

I'm building application in Phalcon PHP where I have database with access from website and API.
In normal website I would create MVC like here:
- app
-- controllers
-- models
-- views
- public
but I have problem with duplicate code for API and Web.
Sample code:
class Users extends Model {
// ...
protected $id;
protected $username;
protected $email;
// setters and getters, validation
}
class UserController extends ControllerBase {
// ...
public function loginAction() {
if ($this->request->isPost()) {
// ... get post
// check login is correct
// create session
// redirect
}
$this->view->var = $var;
}
}
class ApiController extends ControllerBase {
// ...
public function loginAction() {
if ($this->request->isPost() //or put) {
$json = $this->request->getJsonRawBody();
// ... get json
// check login is correct
// create session
}
$response->setStatusCode('2xx/4xx', 'msg');
$response->setJsonContent([
'status' => 'OK / ERROR',
'message' => '$msg / $ex->getMessage()'
]);
}
}
Now I would create class with logic for check is user data correct.
I think about class like this:
class MyClass extends ParentClass {
public function login($username, $password) {
$user = Users::findFirstByEmail($email);
if ($user->password === hash($password)) {
$successLogin = new UserSuccessLogins();
$successLogin ->setId('id');
$successLogin ->setIpAddress('ip');
$successLogin ->save();
} else {
$failedLogin = new UserFailedLogins();
$failedLogin->setId('id');
$failedLogin->setIpAddress('ip');
$failedLogin->save();
}
}
}
And now I could use it in controllers like here:
class UserController extends ControllerBase {
public function loginAction() {
if ($this->request->isPost()) {
$c = new MyClass();
if ($c->login($username, $password)) {
// redirect
}
}
$this->view->var = $var;
}
}
class ApiController extends ControllerBase {
public function loginAction() {
if ($this->request->isPost() //or put) {
$c = new MyClass();
if ($c->login($username, $password)) {
// send json OK
} else {
// send json Error
}
}
}
}
What is best way for this? I don't want logic in model class.
I have read about Plugin and Component, but I don't know how create good self commented code.
You might be looking for Phalcon Multimodule, have a look at this example. Besides "Front-End" and "Back-End" modules, you can add "API" module.
OK, I'm going to extend my project with components like here:
-app
--components
--controllers
--models
--views
-public
Now, my code may looks like below:
use Phalcon\Mvc\Model;
class Users extends Model {
// ...
protected $id;
protected $username;
protected $email;
// setters and getters, validation
}
use Phalcon\Mvc\User\Component;
class UserComponent extends Component {
// class with access to dependecy injector
public login ($email, $password) {
$user = Users::findFirstByEmail($email);
// logic with setting session in $di
}
}
class UserController extends ControllerBase {
public function loginAction() {
if ($this->request->isPost()) {
$userComponent = new UserComponent();
if ($userComponent ->login($username, $password)) {
return $this->response->redirect($this->url->getBaseUri(), false, 301);
} else {
$this->flash->error('message');
}
}
// setting view variables if not post or login filed
$this->view->var = $var;
}
}
class ApiController extends ControllerBase {
public function loginAction() {
if ($this->request->isPost()) {
$userComponent = new UserComponent();
if ($userComponent ->login($username, $password)) {
//json OK
} else {
//json Error
}
}
}
}
If no one have better proposition I'll close this topic as solved in few days.
Your suggestion is a good option, however if you want to decouple and segregate responsibilities in a better way, you can try to use a service layer like in this example https://github.com/phalcon/mvc/tree/master/multiple-service-layer-model. Where you will have:
entities ( the models generated by phalcon)
repositories ( all the operations that requires fetching, updating or persisting data)
services (where the business logic is).
Whit this the call graph can be summarised as follow:
controllers -> services -> repositories -> entities
Note that the dependencies go in a single direction, nonetheless for simple tasks you can use a repo inside the controller directly o a entity inside the service, is up to you how hard or flexible your architecture will be.
I hope It is clear regards.

Yii2 - port a request to a controller based on user types

I have a controller as admin and another as guest.
I want to have some http requests to a static address like test.com/guest/index, and have this results:
if the user(determined in request body as a username) is an admin (actually not-guest) user then it should port the request(not redirect, because redirect cant be done in an api-client, and of course http request cant move along the methods on redirect) to a specific method of admin controller.
like i send a POST request to test.com/guest/index and I am admin so it should run the methodName() - I should specify the name not the request - from admin controller and if somebody else who is not admin send the same request it should run methodName() (same method name) from guest controller.
how can this be done? I use Yii2. so I want to know is there any way to do this or if there is no way so is it possible in a single controller with different method names?
is it possible in ACL extension?
thanks
I suggest creating single controller named GuestController and process request not based on sent information, but on current user status:
class GuestController extends yii\web\Controller {
public function actionIndex() {
$response = null;
$model = User::getByCredentials();
if (!$model) {
$response = $this->guestAction();
} else {
switch ($model->role) {
case 'admin':
$response = $this->adminAction();
break;
case 'user':
$response = $this->someUserAction();
break;
}
}
echo $response;
}
protected function adminAction() {
$data = \Yii::$app->request->post(); // still can access _POST/_GET...
return 'Hallo Warold!';
}
/* ... */
}
/**
*
*/
class User extends yii\web\ActiveRecord {
public funcion getByCredentials($username, $password) {
$model = self::findOne(['username' => $username]);
if (!empty($model) && \Yii::$app->security->validatePassword($password, $model->password)) {
return $model;
}
return null;
}
}

Laravel, Auth and logging out from a model

I'm currently using Laravel 5 Authentification, but I have edited it to allow me to connect to an API server instead of an Eloquent model.
Here is the code of my custom UserProvider:
<?php namespace App\Auth;
use Illuminate\Contracts\Auth\UserProvider as UserProviderInterface;
use WDAL;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\GenericUser;
use Session;
class WolfUserProvider implements UserProviderInterface {
private $_loggedUser;
public function __construct()
{
$this->_loggedUser = null;
$user = Session::get('user');
if (!empty($user)) {
$this->_loggedUser = unserialize($user);
}
}
public function retrieveById($id)
{
return $this->_loggedUser;
}
public function retrieveByToken($identifier, $token)
{
return null;
}
public function updateRememberToken(Authenticatable $user, $token)
{
//dd('updateRememberToken');
}
public function retrieveByCredentials(array $credentials)
{
$user = WDAL::getContactCredentials($credentials['login']);
return $user;
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
if($user->username == $credentials['login'] && $user->password == $credentials['password']){
$this->_loggedUser = $user;
Session::set('user', serialize($user));
return true;
}
else{
return false;
}
}
}
?>
This code might not be perfect as it still in early development ;-) (feel free to suggest me some ideas of improvement if you want to)
So when the user is logged, it has access to the whole platform and to several views and can communicate with the API server to display and edit data.
Sometimes, the API server can return "Invalid Session ID" and when my Model gets this message, the user should be redirected to the login page.
From a Controller it's really easy to handle I can use this code (logout link):
public function getLogout()
{
$this->auth->logout();
Session::flush();
return redirect('/');
}
But do you know how I should proceed from a Model ? I could of course edit all my controllers to check for the value returned by the Model to logout, but cannot it be done thanks to middlewares?
It seems to be really long to edit all my controllers, and this will imply a lot of duplicated code.
One of my tries was to throw an exception from the Controller, and catch in from the auth middleware.
It was not working, because I didn't write use Exception;
I'm now catching the exception, and can now redirect the user from the middleware.
Thank you anyway!

Code Igniter RESTful Modeling and Controller

I have been developing using non framework for about 3 years and I have heard about PHP framework codeigniter.
I think I missed something using this framework which is used for API for my mobile application.
I've facing some problem to get data from database using Phil's CI framework, RESTful plugin. My browser shows error code:
{"status":false,"error":"Unknown method."}
Using my logic below:
controller: user.php
<?php
require(APPPATH.'libraries/REST_Controller.php');
class User extends REST_Controller{
public function user_get()
{
//IF USER NOT EXIST
if(!$this->get('id'))
{
$this->response(NULL, 400);
}
//CHECK TO MODEL FUNCTION
$user = $this->user_model->get_user($this->get('id'));
//IF USER EXIST
if($user)
{
$this->response($user, 200); // 200 being the HTTP response code
}
}
public function user_put()
{
// create a new user and respond with a status/errors
}
public function user_post()
{
// update an existing user and respond with a status/errors
}
public function user_delete()
{
// delete a user and respond with a status/errors
}
}
?>
model: user_model.php
<?php
class User_model extends CI_Model{
function __construct() {
parent::__construct();
}
function get_user($id){
$query = $this->db->get('mt_user', array('idmt_user'=>$id));
return $query->row_array();
}
}
?>
i'm accessing the database which is has this rows:
idmt_user,username,password, emails, createdate
accessed using mozilla:
#http://localhost/<project>/index.php/user/<userid>
Where's the error(s) ?
thanks.
update,
i am already defined the autoloads for database. But this problem still persist. Is there any helps? thanks
as stated below in answer, i tried to access the url, /user/get_user/ but still showing the same result. Is there any problem using idmt_user in database?
Insert in controllers:
function __construct() {
parent::__construct();
$this->load->model('user_model');
}
And try this route:
http://localhost//index.php/user/user/id/
I believe that the url you are accessing with is wrong.. Try accessing with the url #http://localhost/<project>/index.php/user/<method_name>/<user_id>
Another way of doing it would be using the URI Class.
Instead of writing the following:
//IF USER NOT EXIST
if(!$this->get('id'))
{
$this->response(NULL, 400);
}
Changed to:
$userid = $this->uri->segment(3);
Would be 3 based off the url being http://localhost/<project>/user/<method_name>/<user_id>
Reference for URI Class: http://www.codeigniter.com/user_guide/libraries/uri.html
In order to use $this->get(); there would have to be a query parameter to get. Example: id=
If you are passing query parameters than you could store these values in a array as shown below.
if(!empty($this->get()))
{
$params[] = $this->get();
}
I hope this helps.
You should to try include your model file into your controller file by using a __construct() function, like this:
function __construct(){
parent::__construct();
$this->load->model(array('user_model'));
}

Categories