Laravel cannot find a Controller Method (does not exist) - php

I'm trying to implement a new method in a BoController called "deleteBooking", the method is defined:
public function deleteBooking($id){
$booking = Reservation::find($id);
if($booking && $booking->delete()){
try {
$email = Mail::to($booking->user_email)->send(new Cancel($booking));
} catch(\Exception $e){
Log::error($e->getMessage());
}
return redirect('admin/manager/home')->with('message','Réservation annulée!');
}
return redirect('admin/manager/home')->with('message','Réservation non annulée!');
}
But laravel at the endpoint says:
(1/1) BadMethodCallException
Method [deleteBooking] does not exist.
Other methods from the same class are linked to endpoints too, and work well.
Do you have any ideas please? Thank you.

I got it fixed, I've found another file called BoController, in another folder somehow and it was conflicting with the App\Http\Controllers one.
Thank you.

It's most likely that you have declared that function for some other request type other than the one you're trying to make. For example you put Route::post('some-method', 'BoController#deleteBooking'); but you need to put either Route::get(...) or Route::put(...) or Route::delete(...).
If it isn't that problem, then you probably misspelled it.

I have faced similar issue. Then I have figured out a issue pointed in composer install log, with following instance of log line:
Class App\Http\Controllers\BlogController located in ./app/Http/Controllers/BlogControllerOld.php does not comply with psr-4 autoloading standard. Skipping.
Based on that I have found that one of the file renamed with Old suffix was creating conflict with the main file. So here I have to chhoseone of the following solutions:
To delete the file created for backup.
Or just rename the class in duplicated file to BlogControllerOld.
So its a good idea to check for issues with composer install
It will highlight the conflicts that can be fixed using one of the method above.
Once fixed using specified methods above issue composer install to apply the fix and regenerate autoloader.

Related

Laravel "Unable to locate a class or view for component" in production environment

I develop on a Mac locally. Latest version of Big Sur.
Today I went to deploy my app to production via an Ubuntu server through Forge, and got greeted with an error I've never seen before, and can't find an answer to online. I can see MANY people complaining about it, but all anyone has said on other answers is link to issues that don't have solutions or even explanations really, so that's why I'm asking a new question.
The exact error is this;
Unable to locate a class or view for component [layouts.base]. (View: /home/forge/default/releases/20201204084441/resources/views/layouts/app.blade.php)
In my app I have;
app\View\Components\Layouts\App.php
which looks like this;
<?php
namespace App\View\Components\Layouts;
use Illuminate\View\Component;
class App extends Component
{
public function render()
{
return view('layouts.app');
}
}
Then I also have;
resources\views\layouts\app.blade.php
<x-layouts.base>
<!-- contents -->
</x-layouts.base>
(Also pretty much the same for base)
Works flawlessly on Mac. As soon as I deploy it on Ubuntu, I get the error above that it is "unable to locate a class or view" with those names.
Can someone please instruct me on how I can go about fixing this, since so far I have absolutely no idea and despite knowing that case sensitivity is probably the issue as per the other questions about this, I cannot find any actual solution or way to resolve this.
I had the same problem. Thanks to your question, I could find out how to solve it :D
In my case, I had created a component inside another folder, for better organization sake:
$ php artisan make:component Tutorial/channelName/Alert
So it created the view component inside the following directory:
views/components/tutorial/channel-name/alert.blade.php
Now, to call your component you do it this way:
<x-tutorial.channelName.alert />
That's pretty much it.
I was facing the same issue and I fixed it by cross-checking my folder name.
Please note that the folder name should be components and not component.
Refer the screenshot for a better idea.
Example:
In case you are following the convention, one more thing is that if you have a file at
views/components/admin/side-menu/side.blade.php
You can call your Component as:
<x-admin.side-menu.side></x-admin.side-menu.side>
Explained:
The x- used in the blade syntax basically tells that you are selecting folder or file from the Components folder.
The . (dot) used is for every directory you dig to the blade file you want to use.
Well, I had the same problem but I realized that the error was the class name of the component. I didn't capitalize the class name and when I did capitalize the class name I stopped getting that error and my project worked well.
Please try capitalizing the class name that matches the component in the error message.
In my Case, I didn't provide the namespace in the Component, it solved after providing namespace.
when I was a beginner I got the same error But in my case, there is all ok but there is a small syntax error <x- card /> there is a gap between card and dash which is not correct so there should be no space between dash and card <x-card /> so try once maybe this is your problem.
I had the same problem - solution
was to change:
<x-forms.inputradio>
to:
<x-forms.inputRadio>
just letter size..
The issue for the mentioned problem is case sensitive,
for local looks like its case insensitive reasons its works for local perfect but breaks on serve.
if you have create new component inside any new folder
i.e
$ php artisan make:component Widgets/CustomAlert
it will create two files, class and blade file for the component.
class file
app\Views\Components\\CustomAlert.php
blade file
resources\views\components\widgets.custom-alert.blade.php
you can render component with either class or with blade file.
for class make sure folder, class name in case sensitive
ie.
<x-Widgets.CustomAlert />
to render blade file it should be
<x-widgets.custom-alert />
Note
if you have manually relocate the file, make sure your namespace in class file, filename and the component call syntax should be match(with case sensitive)
examples are just for reference try to compare syntax and names with your files,folder.
I hope it will help :)
In my case, I had created a class AppLogo and I had the blade generated as app-logo.blade.php.
However, in my view files, I referenced the component as x-applogo and this worked locally, but in production (a live hosting server), I got this error.
SOLUTION:
I changed all occurrences of x-applogo in my blade/view files to x-app-logo.
This worked both in development and in production.
Hope this helps someone out there.
This happens at server. try not to make components inside folder..
i had the same issue at server but did not get any solution,
the only solution worked is to keep your components outside any sub folder

Yii2 $model->_attributes assignment does not work in new version

I inherited a project that was created with Yii2, ver. 2.0.4, with the task to update said project to a more current version of Yii2 (2.0.15) because of the incompatibility of the older one with PHP 7.2+.
I noticed that there is a lot of use of assigning arrays to a model:
$model->_attributes = $array;
With the new version this results in an exception
'yii\base\UnknownPropertyException' with message 'Setting unknown property: app\models\model::_attributes'
For the time being I created a workaround with the following function:
function customSetAttributes(&$model, $array) {
foreach($model->attributeLabels() as $model_key => $model_label) {
if(!isset($array[$model_key])) continue;
$model->$model_key = $array[$model_key];
}
}
Also, the getter function now has a similar issue.
What I would like to know:
Was this type of assignment never intended in the first place (and I just haven't found the previous developer's code that enables it)? I skimmed over the Yii2 changelog but didn't notice anything related.
Is there a way to "salvage" the previous behaviour so I don't have to replace each occurence with my workaround function?
ActiveRecord::$_attributes was always private and never should be used in this way. I guess that previous developer edited framework core files in vendor directory and make this property protected/public.
You may try to emulate this behavior by creating virtual attribute using getter and setter:
public function get_attributes() {
return $this->getAttributes();
}
public function set_attributes($values) {
$this->setAttributes($values, false);
}
But this will not always work and it is more like an ugly hack to make crappy code work. I strongly suggest to fix code to use setAttributes() instead of _attributes.
Also you should compare yii2 package from vendor directory with source from https://github.com/yiisoft/yii2-framework/releases/tag/2.0.4 - you may find more places where core was edited.

Loading a composer class in laravel

I'm in the process of trying to make a laravel compatible composer/packagist package. I'm using Laravel 5.5.
I've created a package : floor9design/machine-identifier. Composer downloads this to vendors/floor9design fine, but despite reading/googling how to do this, I'm unsure of how to include this in my laravel projects.
PHP Storm is correctly picking up the class, auto-completing as expecting.
I have not modified any files so far. If I add the following to a controller:
use Floor9design\MachineIdentifier\MachineIdentifier;
(alongside some class usage on the page).
PHP storm autocompletes this (as it does with other classes validly called).
When I try to load this, the following error comes:
Class 'Floor9design\MachineIdentifier\MachineIdentifier' not found
I've had a look round plenty of tutorials, and this final step seems to be missing from a lot of information.
I realise there are three approaches:
Firstly:
Direct include_once, which while working, is not the normal approach
Secondly:
Pre-laravel 5.5 approach (add something to app.php)
Thirdly
Laravel 5.5 approach and up, autodetection of something.
I've deliberately said something as the documentation seems to speak about ServiceProviders, and I simply don't get how they work.
Let me rephrase this into a question and a follow up question:
Question: apart from include_once, how do I load the MachineIdentifer class from floor9design/machine-identifier in Laravel.
Question 2: If the answer is via a service provider, can you simply explain how they relate to one another.
Thanks
Answer (as accepted below)
On the composer repo I was incorrectly specifying the PSR4 namespace, which is now corrected to:
"autoload": {
"psr-4": {
"Floor9design\\MachineIdentifier\\": "src"
}
}
The previous namespace had a -, which is an illegal character. Many thanks to lawrence-cherone.
Your PSR4 is wrong in the package
floor9design\\machine-identifier\\": "src"
Will cause the composer/autoload_psr4.php to map to:
'floor9design\\machine-identifier\\' => array($vendorDir . '/floor9design/machine-identifier/src'),
Which is not a valid class namespace.
You should change the PSR4 to match your class namespace:
Floor9design\\MachineIdentifier\\": "src"
Once you fix that you will be able to use it like normal from anywhere in your project.

PHP-FFMpeg prerequisites

I'm attempting to implement https://github.com/PHP-FFMpeg/PHP-FFMpeg
I copied the src/FFMpeg folder to my includes folder and made sure my autoloader knows where to find everything.
as a test I made a script that simply does:
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
I get:
Fatal error: Class 'Doctrine\Common\Cache\ArrayCache' not found in /var/www/php/include/FFMpeg/FFProbe.php on line 203
My question is: does PHP-FFMPeg require Doctrine, because that is not stated in the documentation. What version do I need? Are there other prerequisites?
I could create a new question for this, but I'm not sure if I should. I now have PHP-ffmpeg implemented. I'm using Laravel, however that should be irrelevant for this question. I'm trying to enable progress monitoring. It works, however I need to pass in an ID so I can update the correct key in memcache.
$id = 12345;
$format->on('progress', function ($audio, $format, $percentage) {
//this works perfect, but doesn't tell me which item is being updated
Cache::put("progress", $percentage, .25);
//this does not work as I am unable to pass in $id, if I add it as the 4th argument above it will display the number of threads or something
//Cache::put("{$id}_progress", $percentage, .25);
});
I need clarification on the "on" method. I looked through https://ffmpeg-php.readthedocs.org/en/latest/_static/API/ and was not able to figure out how this method works. Any help would be appreciated.
You should follow the recommended instructions in the README.
Composer is the easiest way to install PHP-FFMpeg dependencies
The "on" method called on the format is an implementation of EventEmitter.
As you can see here : https://ffmpeg-php.readthedocs.org/en/latest/_static/API/FFMpeg/Format/ProgressableInterface.html it extends the EventEmitterInterface of https://github.com/igorw/evenement.
If you're really interested about how it works under the hood, have a look at here :
The progress listener is created here : https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Format/Audio/DefaultAudio.php#L96 and added at execution here https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Media/Video.php#L151
This is actually possible because FFMpegDriver extends the Driver provided by https://github.com/alchemy-fr/BinaryDriver
Hope this helps :)

Propel Data Load - "default" context does not exist

I am currently stuck on the error The "default" context does not exist. when trying to build my data model with the command symfony propel:build --application=frontend --all --and-load --no-confirmation
After lots of Googling it appears this error is caused by using sfContext inside a model or a form so I have found these and commented them out (see below), the error still occurs, does anyone else know a fix?
>> file- /var/www/html/dev/meeting/config/generated-sfGuardPlugin-schema.xml
>> file- /var/www/html/dev/meeting/config/generated-schema.xml
>> propel load data from "/var/www/html/dev/meeting/data/fixtures"
>> propel load data from "/var/www/html/dev/meeting/plugins/sfGuardPlugin/data/fixtures"
The "default" context does not exist.
grep -R sfContext lib/model/*
lib/model/MeetingMeetings.php: return "";//sfContext::getInstance()->getController()->genUrl('meeting/show?id='.$this->getId(), $full);
lib/model/sfGuardUserProfile.php: //if(!is_null(sfContext::getInstance())&&($useYou||$useYourself)&&$this->getUserId()==sfContext::getInstance()->getUser()->getId()) {
grep -R sfContext lib/form/*
lib/form/MeetingMeetingsForm.class.php: //sfContext::getInstance()->getUser()->setFlash("info",
Many thanks for your time,
Not sure what information I can provide, does anyone have any other questions?
I resolved this problem by doing the following.
First find all references to sfContext in your model files and find an alternative way to get what ever sfContext was needed for (for example passing it to the method).
Check all library files mentioned inside any models for use of sfContext, repeat above solution.
Use is_null checks on sfContexts where it has to exist so it only does if it required.
The problem in my case was my save method used another library which used sfContext to get the current user, which obviously doesn't exist when inserting data to the model
Just ran into this today with data-load. Instead of modifying the function signature, here's what I did.
if(!sfContext::hasInstance())
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'cache', true);
else
$configuration = sfContext::getInstance()->getConfiguration();
And then I can run stuff like this in my model classes.
$configuration->loadHelpers('Texturizer');
I'm not sure what the 'cache' parameter does in getApplicationConfiguration, but I found that line off of the Jobeet book here http://www.symfony-project.org/jobeet/1_4/Propel/en/21
To resolve the problem quickly, comment the code /lib/form/baseForm.class.php , generate the module, and restores the code

Categories