I am doing some refactoring of our large work app. This involves separating out some tools I've build, like a schema/seed migration tool for the command line, in to their own repositories to be used by multiple applications.
If it's in console/controllers, it gets picked up. If I move them to their own repository and require it via Composer, how do I get Yii to know when I say php yii db/up, i mean go to the new\vendor\namespace\DbController#actionup ?
If you create an extension (and load it through composer of course), you can locate Module.php inside, which will hold path to console controllers (that you can call with your terminal).
I will write my example for common\modules\commander namespace, for vendor extension your namespace will differ, but it work for all of them the same way.
So I have the following file structure for my extension
<app>
common
modules
commander
controllers
• TestController.php
• Module.php
My Module class looks as follow:
namespace common\modules\commander;
use yii\base\Module as BaseModule;
class Module extends BaseModule
{
public $controllerNamespace = 'common\modules\commander\controllers';
public function init()
{
parent::init();
}
}
And TestController.php is inherited from yii\console\Controller:
namespace common\modules\commander\controllers;
use yii\console\Controller;
class TestController extends Controller
{
public function actionIndex()
{
echo 123;
}
}
And the main part to make everything work is to register out Module.php in console/config/main.php settings
'modules' => [
'commander' => [
'class' => \common\modules\commander\Module::className(),
],
...
],
Here it is, now you can use your command like:
yii commander/test/index
And it'll print you 123, showing that everything works and Console Controllers are located in different folders!
Related
I'm creating an application for a Symfony web project that I have made previously as a portable bundle. I've created a "media.html.twig" template and want it to be called by the render() helperfunction.
I've activated the bundle in /config/bundles.php with
App\OM\MediaManagerBundle\OMMediaManagerBundle::class => ['all' => true],
and followed the instructions on this site https://symfony.com/doc/current/bundles.html for setting up the Symfony-Bundle folder structure and the required files.
I've prefixed the path with "#MediaManager" as told by this site https://symfony.com/doc/4.1/bundles/best_practices.html#resources.
This is my Controller class:
<?php
namespace App\OM\MediaManagerBundle\Controller;
use App\OM\MediaManagerBundle\Form\ImageType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class MediaManagerController extends AbstractController
{
const TEMPLATE = "#MediaManager/MediaManager/media.html.twig";
/**
* #Route("/media/", name="om_mediamanager_media")
* */
public function index(Request $request)
{
$form = $this->createForm(ImageType::class);
return $this->render(self::TEMPLATE,
[
'form' => $form->createView(),
]);
}
}
This is how my folder structure looks like inside src:
https://i.imgur.com/9UomIEK.png
I hoped my form would be displayed but instead I got an error message saying:
There are no registered paths for namespace "MediaManager".
I know that it starts looking from the /templates folder so I tried setting the path to "../src/OM/MediaManagerBundle/Resources/views/MediaManager/media.html.twig" but got
Looks like you try to load a template outside configured directories (../src/OM/MediaManagerBundle/Resources/views/MediaManager/media.html.twig).
The code does work when I move the "media.html.twig" template inside the /templates folder but I expect it to ruin the portability of the bundle and therefor don't want to do that.
How do I access this template from inside my OMMediaManagerController class?
Am I even using Symfony Bundles the right way?
Is there any more documentation about Bundles in general? I found the ones provided by the official site to be very lacking.
I've had to try and work with an older package meant for php into my Laravel project.
I've added two custom classes, both are in the same folder "Classes" under the main "app" folder in my Laravel project.
One of these classes is recognized from a generated controller for my Laravel project. My paymentsController has use App\Classes\Quickbooks_Payments; in the top.
However, going to that Classes' file, I hit the following error through a route leading to my controller:
Class 'App\Classes\Quickbooks_Loader' not found
Now this is where this above is referenced in my paymentsController file:
<?php
namespace App\Classes\Quickbooks_Payments;
use App\Classes\Quickbooks_Loader;
/**
* QuickBooks Payments class
*
*/
/**
* Utilities class (for masking and some other misc things)
*/
QuickBooks_Loader::load('/QuickBooks/Utilities.php');
This last line is where the above error is referenced. And I do have both the Quickbooks_Loader.php and the Quickbooks_Payments.php in the same folder. My Quickbooks_Loader.php file starts off as such:
<?php
namespace App\Classes\QuickBooks_Loader;
So I know this is likely because of my inexperience with custom/imported classes. What am I doing wrong and how should I properly "import" these custom classes and have them recognized without any issues?
Change namespace in both classes you've shown to:
namespace App\Classes;
And run composer du
Also, make sure the class looks like this and not like you've shown (I'm not sure about did you cut something or not):
<?php
namespace App\Classes;
use App\Classes\Quickbooks_Loader;
class Quickbooks_Payments
{
public function __construct()
{
dd('It\'s working!');
}
}
I have some functionality, that I want to add to yii\console\controllers\MessageController::actionExtract().
So normally what I have done - extended yii controller with my own controller and placed it to app\commands directory.
<?php
namespace app\commands;
class MessageController extends \yii\console\controllers\MessageController{ /* .. */ }
For test purposes I added method named actionTest.
When I do > yii command, all I get is
Now I copy-pasted exactly same controller and just renamed it to MsgController. Previous controller left intact.
So now > yii gives me
yii message/test - 'Unknown command message/test'
yii msg/test - 'OK'
My app\config\console.php has 'controllerNamespace' => 'app\commands'
How should I properly extend MessageController and continue use standard yii command (means not changing controller name to have new command)?
Extend the controller like you did and in console configuration add:
'controllerMap' => [
'message' => 'app\commands\MessageController',
],
I created a helper in the application module, and it works perfectly. When I try to load it from another modules, such as user, it tells me that it can not find the class.
Class 'Application \ View \ Helper \ Footertable' not found
I tried to put this code in module.config.php well as the application module even in the same file of the user module.
'view_helpers' => array (
'invokables' => array (
'footertable' => 'Application\View\Helper\Footertable'
)
),
I think it's a problem autoloading class but I can not find information on how to load this helper when you are in another module
I invoke helper in view file using
$this->footertable()
work perfectly in application module but not in user module
any idea?
Hello,
but my code is correct
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Footertable extends AbstractHelper{
protected $inizioFine;
protected $numero;
public function __invoke($inizioFine,$numero){
$this->inizioFine = $inizioFine;
$this->numero = $numero;
echo sprintf('Mostra %d a %d di %d record',$this->inizioFine['start'],$this->inizioFine['end'],$this->numero);
}
}
the space in config is an copy & past errors.
I still have the same problem: can't load helper from another module
update full error
Fatal error: Class 'Application\View\Helper\Footertable' not found in D:\www\httpdocs\test\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170
path is
D:\www\httpdocs\test\module\Application\src\View\Helper\Footertable.php
The path you posted doesn't look right. All the files in src for your Application module should be inside a folder called Application, since that's your top level namespace. So the path should be:
D:\www\httpdocs\test\module\Application\src\Application\View\Helper\Footertable.php
That would explain why the helper can't be autoloaded, but I don't understand how it works in the application module if this is the case.
Your configuration seems good. Probably the problem is in your helper class signature.
Since PhpRenderer composes a HelperPluginManager instance to manage helpers, your helper should implement the HelperInterface (1) to be registered correctly. Also you should write an __invoke() method within your helper to invoke it by method call. (2)
So, in your Footertable class, simply extend the AbstractHelper and make sure you have an _invoke() method. This is recommended way to write custom view helpers in documentation.
For example:
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Footertable extends AbstractHelper
{
public function __invoke()
{
return 'bar';
}
}
And use it in your views like this:
echo $this->footertable();
It should work.
Note: You also have to register all helpers (and other classes) in your module configuration's invokables section without spaces between the backslashes:
Wrong:
'footertable' => 'Application \ View \ Helper \ Footertable'
Correct:
'footertable' => 'Application\View\Helper\Footertable'
The error I'm getting is that the controller doesn't exist even though I know it does, here's the code.
Route.php
Route::get('mdpay/template', array("uses" => "templateController#index"));
templateController.blade.php
class templateController extends BaseController {
public function index()
{
echo "made it";
}
}
Why might I be getting this error: Class TemplateController does not exist
================= UPDATE: ==================
Ok, so I've created the correct route, renamed my file, and corrected the class name and I'm still coming up with that error.
File Names:
templateController.php
// File Name: TemplateController.php
class TemplateController extends BaseController {
public function index()
{
// app/views/myView.blade.php
echo "hello";
}
}
My route is:
Route::get('mdpay/template', array("uses" => "TemplateController#index"));
Still receiving Controller Doesn't Exist error. All my other controllers (3 others) are working except this one.
If you are using the standard composer classmap autoloader you need to composer dumpautoload everytime you create a new file.
So to create a new controller with the standard composer setup given by Laravel:
Create a new file in app/controllers named TemplateController.php
Open up terminal and run composer dumpautoload
As previous users have said, only view files should end with .blade.php.
If you're using Laravel 8, add this line to your RouteServiceProvider.php (you can search it by using CTRL + P):
protected $namespace = 'App\Http\Controllers';
This solved the issue for me.
It should be:
// File Name: TemplateController.php
class TemplateController extends BaseController {
public function index()
{
// return "made it"; // or
// app/views/myView.blade.php
return View::make('myView');
}
}
Route for that:
Route::get('mdpay/template', array("uses" => "TemplateController#index"));
Use blade in a Blade view, i.e: myView.blade.php basically stored in app/views/ folder. Read more about blate template on Laravel website.
Controllers live in the app/controllers directory and should remain there unless you have your own namespaced structure.
The reason you're getting a Class TemplateController does not exist is because it doesn't, firstly, your class is called templateController and secondly, it exists as templateController.blade.php which wouldn't be loaded in this way.
Blade files are for views, and only views within app/views or a custom views directory should end with .blade.php.
Create the file app/controllers/TemplateController.php and add the following code to it.
class TemplateController extends BaseController {
public function index()
{
echo "made it";
}
}
Now on the command line, run the command composer dumpautoload and change you route declaration to:
Route::get('mdpay/template', array('uses' => 'TemplateController#index"));
Now it should all work.
In case you're using Laravel 9 and the error is like Illuminate\Contracts\Container\BindingResolutionException and Target class <controller name> does not exist. when trying php artisan route:list on terminal.
This is the setup that I do:
Add protected $namespace = 'App\\Http\\Controllers'; to RouteServiceProvider.php
Add 'namespace App\Http\Controllers;' to the controller file.
Do php artisan optimize on terminal
(Just to make sure the route already there) Do php artisan route:list again on terminal, and the controller route should be displayed.