Lavel can't load classes - laravel

I installed someone's laravel project on my machine. Im getting an error that says my controller file can not load a class. However, no one else is experiencing the same issue. Here's the files related to my issues
app/Models/Menu.php
namespace App\Models;
use ...etc....
class Menu extends Model implements Sortable
{
}
class MenuPage extends Model
{
}
app/Http/Controller/AutomobileController.php
namespace App\Http\Controllers;
use App\Models\Menu;
use App\Models\MenuPage as MenuPage;
use ...etc...
class AutomobileController extends Controller
{
public function index(Request $request)
{
// Both these lines give Class 'App\Models\MenuPage' not found
$menu_items = MenuPage::where('menu_id', 6)->get()->toArray();
//$menu_items = \App\Models\MenuPage::where('menu_id', 6)->get()->toArray();
}
}
I comment that both lines where I tried to use MenuPage gives an App\Models\MenuPage not foudn error. I looked on my other colleague's computers and those same lines work for them.
I have not modified any other code since downloading this project.
Can anyone suggest why things break on my system but not others?
NOTES
I noticed that my colleagues are on PHP7.3 and Ubuntu 18.04, and I am on PHP7.4 and Ubuntu 20.04.

Related

How to work with subdirectory controllers in CodeIgniter 4?

I need help with using sub directory controllers in CodeIgniter 4.
I just can't make it work for some reason.
This is the URL for example: www.example.com/admin/dashboard
In the controllers folder, I created a folder named Admin, and a file named Dashboard.php.
I used this code in Dashboard.php:
namespace App\Controllers;
class Dashboard extends BaseController
{
public function index()
{
}
}
I tried changing the class name to AdminDashboard, Admin_Dashboard, pretty much every logical name but every time I get a 404 error, saying:
Controller or its method is not found:
App\Controllers\Admin\Dashboard::index
I know the file itself gets loaded successfully, but I think I don't declare the classname correctly and it keeps throwing me those 404 errors.
The documentation of CI4 isn't providing any information about what the classname should be called unfortunately...
UPDATE #1
I managed to make it work by changing few things:
namespace App\Controllers\Admin;
use CodeIgniter\Controller;
class Dashboard extends Controller
{
public function index()
{
}
}
But now it won't extend the BaseController which has some core functions that I built for my app.
Any ideas to how to make it extend BaseController?
I must admit that I don't have much knowledge about namespacing yet, so that might be the reason for my mistakes.
As I imagined, the problem was that I didn't learn about namespacing.
I needed to point the use line at the BaseController location.
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
class Dashboard extends BaseController
{
public function index()
{
}
}
Now www.example.com/admin/dashboard/ goes directly to that index function, as intended.
php spark make:controller /Subfolder/ControllerName
$routes->add('/(.+?)_(.+?)/(.+?)$', 'subdir\\\\$1_$2::$3');
$routes->add('/(.+?)_(.+?)$', 'subdir\\\\$1_$2::index');
I was able to map with this setting.
The route mapping could be as simple as:
$routes->group('admin', static function ($routes) {
$routes->get('dashboard', 'Admin\Dashboard::index');
});

How to extend a laravel package within laravel 5.8 application?

I am new to Laravel and would appreciate any help on describing how a Laravel package residing in vendor folder can be extended and wont get affected if I update the package.
I'll try to create a brief guide, and we'll expand if need be.
I suggest putting all of your files inside a separate directory / namespace. You'll benefit from this should you decide to create your own composer package afterwards.
As an example I'll extend bumbummen99/shoppingcart package which forks the great gloudemans/shoppingcart, adding support for Laravel 5.8 and some minor functionality. You will of course first need to install that package:
composer require bumbummen99/shoppingcart
Start by making a couple of folders. You can use any name for folders / classes, this is what I used, relative to the project root:
app/Repositories/ExtendedCart
app/Repositories/ExtendedCart/Facades
Create the file
app/Repositories/ExtendedCart/ExtendedCart.php
This class will extend the package's main class:
namespace App\Repositories\ExtendedCart;
use Gloudemans\Shoppingcart\Cart;
class ExtendedCart extends Cart
{
public function myMethod(){
return 'myMethod';
}
}
Then make your Service Provider. Create the file:
app/Repositories/ExtendedCart/ExtendedCartServiceProvider.php
(I'm not using artisan as generating / moving the provider will produce wrong namespace)
This is your Service Provider content, here you reference the class that extends the package's class. Note you overwrite the binding from the original package.
namespace App\Repositories\ExtendedCart;
use Gloudemans\Shoppingcart\ShoppingcartServiceProvider;
class ExtendedCartServiceProvider extends ShoppingcartServiceProvider
{
public function register()
{
$this->app->bind('cart', 'App\Repositories\ExtendedCart\ExtendedCart');
}
}
Then register your service provider in config/app.php
'providers' => [
...
//Add this line to the end of providers array
App\Repositories\ExtendedCart\ExtendedCartServiceProvider::class,
]
Lastly create a Facade, which will instantiate the class (otherwise you will get non-static method exceptions). Create this file:
app/Repositories/ExtendedCart/Facades/ExtendedCart.php
This is the contents of the file:
namespace App\Repositories\ExtendedCart\Facades;
use Illuminate\Support\Facades\Facade;
class ExtendedCart extends Facade {
protected static function getFacadeAccessor() { return 'cart'; }
}
You're all set to use your extended methods. You can safely upgrade the original package, and you can even use the default facade:
namespace App\Http\Controllers;
use Cart;
class SomeController extends Controller{
public function someFunction(){
Cart::instance('default')->myMethod();
//This should return 'myMethod'
}
}
I hope this helps, good luck!

Laravel 4 to 5 Models

Hi can anyone clarify this for me. I have a rather large Laravel 4 app using a few models. I would like to upgrade to L5 and would simply like to use the same model calls in the controllers.
e.g.
Course::
\Course:: //if controller in a deeper folder
The course model is in App/Models. I've tried a composer mapping App/Models but to no avail.
Thanks
I don't know about anyone else. But in my installation of Laravel 5, my models are defined directly within the app folder. The app directory is psr-4 namespaced as App.
composer.json
"autoload": {
...
"psr-4": {
"App\\": "app/"
}
}
Models are then defined under the App namespace. e.g.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
So you can either:
1: Use the full path to the model whenever you use it:
\App\Course::all();
2: use your model before using it like you normally would:
namespace Your\Namespace;
use App\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
3: Create a folder called Models, put your models in there and make sure that their namespace reflects the path (And then call the model like in options 1 and 2):
// app/Models/Course.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Course extends Model {
}
e.g.
\App\Models\Course::all();
or
namespace Your\Namespace;
use App\Models\Course;
class YourClass {
public function yourFunction()
{
Course::all();
}
}
That's just how namespaces work. If you specify a class PHP will always search for it relative to the current namespace. Unless you prepend a backslash and use the full path or add an import statement at the beginning of your files:
namespace App\Http\Controllers;
use App\Models\Course;
class ...
Or
\App\Models\Course::all();
I should add that many editors and IDEs are able to automatically resolve and import classes, so with the right tools it's not that cumbersome...

Laravel 5 and models

I have a new installation of Laravel 5. The problem is that it's not recognizing my model classes. I will keep it very simple for solution purposes.
Route::get('test', function() {
$test = boxstyle::all();
....
}
My model is in the app directory
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Boxstyle extends Model {
protected $table = 'boxstyle';
protected $primaryKey = 'key1';
}
I am getting:
class boxstyle not found error
I've been searching all over the internet and can't find a solution. This installation is fresh. This isn't magic and I suspect a configuration issue but I can't find a solution. This works fine in Laravel 4.2 so I know it should work but not working in L5.
Your model is defined inside the App namespace. If the code accessing the model is not in the same namespace as the model, you need to qualify it.
Route::get('test', function() {
$test = \App\Boxstyle::all();
}
Laravel 4 did not define the models and controllers inside namespaces. Your models would have been defined inside the global namespace, so any code also in the global namespace (like your controller) would not need to qualify the model. However, Laravel 5 has made the push to put most everything inside namespaces.
To create a model in Laravel 5 try this,create a folder name "Models" folder under your App folder, now for instance you want to create a Model class for Boxstyle ...under your Models folder create a file name
"BoxstyleModel.php" inside your BoxstyleModel.php should look like this and make sure your inside the folder to namespace your model under the App\Models
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BoxstyleModel extends Model {
public static function say_hello(){
return "Hello";
}
}
in your Boxstyle Controller to be able to use your BoxstyleModel added this code at the top of your BoxstyleController use App\Models\BoxstyleModel;
now everything should be the same like Laravel 4.X.

How to register a namespace in laravel 4

The problem:
class PostRepostioryInterface not found for line 4 in PostController.php
or in tinkering with the namespace I've even got class
App\Models\Interfaces\PostRepositoryInterface not found
The questions: How to register a namespace in laravel 4? What do I need to do to get L4 to recognise the classes/interfaces at this namespace?
Larave 3 had a $namespaces static object in ClassLoader where you could add namespaces by
Autoloader::namespaces(array(
'App\Models\Interfaces' => path('app').'models/interfaces',
));
I'm not sure if I have that right for laravel 3 but either way, AutoLoader doesn't exist in Laravel 4 and ClassLoader exists but the method namespaces doesn't exist in ClassLoader in Laravel 4.
I've looked at this but it doesn't seem to work without registering the namespace somehow.
Using namespaces in Laravel 4
Example structure:
app/models/interfaces
PostRepostitoryInterface.php
app/models/repositories
EloquentPostRepository.php
namespaces:
App\Models\Repositories;
App\Models\Interfaces;
the files:
PostRepositoryInterface.php
<?php namespace App\Models\Interfaces;
interface PostRepositoryInterface {
public function all();
public function find($id);
public function store($data);
}
EloquentPostRepository.php
<?php namespace App\Models\Repositories;
use App\Models\Interfaces\PostRepositoryInterface;
class EloquentPostRepository implements PostRepositoryInterface {
public function all()
{
return Post::all();
}
public function find($id)
{
return Post::find($id);
}
public function store($data)
{
return Post::save($data);
}
}
PostController.php
<?php
use App\Models\Interfaces\PostRepositoryInterface;
class PostsController extends BaseController {
public function __construct( PostRepositoryInterface $posts )
{
$this->posts = $posts;
}
Thanks
You probably forgot to do composer dump-autoload. This updates the list of classes Laravel autoloads.
You can read more on composer documentation.
On the laravel irc channel I found out the namespaces should work in L4 without a need for registering them anywhere. This is because the composer dump-autoload adds them to the composer/autoload file for me. So that was not an issue.
The issue turned out to be a typo apparently(I can't find it in the code above but after going through every line copy/pasting the class names and namespaces something changed), and also somehow in my real code I left out the 'use' statement for EloquentPostRepository.php
use App\Models\Interfaces\PostRepositoryInterface;
Now I've hit another wall trying to use the namespaced interface with ioc and the controller constructor (target interface App\Models\Interfaces\PostRepositoryInterface is not instantiable) but I guess that should be a different question.

Resources